mirror of
https://github.com/SoPat712/videospeed.git
synced 2026-04-21 04:42:35 -04:00
226 lines
6.4 KiB
JavaScript
226 lines
6.4 KiB
JavaScript
// Import/Export functionality for Video Speed Controller settings
|
|
|
|
const EXPORTABLE_LOCAL_SETTINGS_KEYS = ["customButtonIcons"];
|
|
|
|
function getExportableLocalSettings(localStorage) {
|
|
const exportable = {};
|
|
const customButtonIcons =
|
|
localStorage &&
|
|
localStorage.customButtonIcons &&
|
|
typeof localStorage.customButtonIcons === "object" &&
|
|
!Array.isArray(localStorage.customButtonIcons)
|
|
? localStorage.customButtonIcons
|
|
: null;
|
|
|
|
if (customButtonIcons) {
|
|
exportable.customButtonIcons = customButtonIcons;
|
|
}
|
|
|
|
return exportable;
|
|
}
|
|
|
|
function replaceImportableLocalSettings(localSettings, callback) {
|
|
chrome.storage.local.remove(EXPORTABLE_LOCAL_SETTINGS_KEYS, function () {
|
|
if (chrome.runtime.lastError) {
|
|
showStatus(
|
|
"Error: Failed to clear local icon overrides - " +
|
|
chrome.runtime.lastError.message,
|
|
true
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (!localSettings || Object.keys(localSettings).length === 0) {
|
|
callback();
|
|
return;
|
|
}
|
|
|
|
chrome.storage.local.set(localSettings, function () {
|
|
if (chrome.runtime.lastError) {
|
|
showStatus(
|
|
"Error: Failed to save local icon overrides - " +
|
|
chrome.runtime.lastError.message,
|
|
true
|
|
);
|
|
return;
|
|
}
|
|
|
|
callback();
|
|
});
|
|
});
|
|
}
|
|
|
|
function generateBackupFilename() {
|
|
const now = new Date();
|
|
const year = now.getFullYear();
|
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
const day = String(now.getDate()).padStart(2, "0");
|
|
const hours = String(now.getHours()).padStart(2, "0");
|
|
const minutes = String(now.getMinutes()).padStart(2, "0");
|
|
const seconds = String(now.getSeconds()).padStart(2, "0");
|
|
return `speeder-backup_${year}-${month}-${day}_${hours}.${minutes}.${seconds}.json`;
|
|
}
|
|
|
|
function getBackupManifestVersion() {
|
|
var manifest = chrome.runtime.getManifest();
|
|
return manifest && manifest.version ? manifest.version : "unknown";
|
|
}
|
|
|
|
function getExportableSyncSettings(syncStorage) {
|
|
return vscBuildStoredSettingsDiff(vscExpandStoredSettings(syncStorage));
|
|
}
|
|
|
|
function getImportableSyncSettings(backup, rawSettings) {
|
|
var importable = vscClonePlainData(rawSettings) || {};
|
|
|
|
if (
|
|
backup &&
|
|
backup.siteRulesFormat &&
|
|
importable.siteRulesFormat === undefined
|
|
) {
|
|
importable.siteRulesFormat = backup.siteRulesFormat;
|
|
}
|
|
|
|
if (
|
|
backup &&
|
|
backup.siteRulesMeta &&
|
|
importable.siteRulesMeta === undefined
|
|
) {
|
|
importable.siteRulesMeta = backup.siteRulesMeta;
|
|
}
|
|
|
|
return vscExpandStoredSettings(importable);
|
|
}
|
|
|
|
function exportSettings() {
|
|
chrome.storage.sync.get(null, function (storage) {
|
|
chrome.storage.local.get(
|
|
EXPORTABLE_LOCAL_SETTINGS_KEYS,
|
|
function (localStorage) {
|
|
const localSettings = getExportableLocalSettings(localStorage);
|
|
const syncSettings = getExportableSyncSettings(storage);
|
|
const backup = {
|
|
version: getBackupManifestVersion(),
|
|
exportDate: new Date().toISOString(),
|
|
settings: syncSettings
|
|
};
|
|
|
|
if (Object.keys(localSettings).length > 0) {
|
|
backup.localSettings = localSettings;
|
|
}
|
|
|
|
const dataStr = JSON.stringify(backup, null, 2);
|
|
const blob = new Blob([dataStr], { type: "application/json" });
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
const link = document.createElement("a");
|
|
link.href = url;
|
|
link.download = generateBackupFilename();
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
URL.revokeObjectURL(url);
|
|
|
|
showStatus("Settings exported successfully");
|
|
}
|
|
);
|
|
});
|
|
}
|
|
|
|
function importSettings() {
|
|
const input = document.createElement("input");
|
|
input.type = "file";
|
|
input.accept = ".json";
|
|
|
|
input.onchange = function (event) {
|
|
const file = event.target.files[0];
|
|
if (!file) return;
|
|
|
|
const reader = new FileReader();
|
|
reader.onload = function (e) {
|
|
try {
|
|
const backup = JSON.parse(e.target.result);
|
|
let settingsToImport = null;
|
|
|
|
// Detect backup format: check for 'settings' wrapper or raw storage keys
|
|
if (backup.settings && typeof backup.settings === "object") {
|
|
settingsToImport = getImportableSyncSettings(backup, backup.settings);
|
|
} else if (typeof backup === "object" && (backup.keyBindings || backup.rememberSpeed !== undefined)) {
|
|
settingsToImport = getImportableSyncSettings(backup, backup);
|
|
}
|
|
|
|
if (!settingsToImport) {
|
|
showStatus("Error: Invalid backup file format", true);
|
|
return;
|
|
}
|
|
|
|
var localToImport = getExportableLocalSettings(backup.localSettings);
|
|
|
|
function afterLocalImport() {
|
|
persistManagedSyncSettings(settingsToImport, function (error) {
|
|
if (error) {
|
|
showStatus(
|
|
"Error: Failed to save imported settings - " + error.message,
|
|
true
|
|
);
|
|
return;
|
|
}
|
|
showStatus("Settings imported successfully. Reloading...");
|
|
setTimeout(function () {
|
|
if (typeof restore_options === "function") {
|
|
restore_options();
|
|
} else {
|
|
location.reload();
|
|
}
|
|
}, 500);
|
|
});
|
|
}
|
|
|
|
replaceImportableLocalSettings(localToImport, afterLocalImport);
|
|
} catch (err) {
|
|
showStatus("Error: Failed to parse backup file - " + err.message, true);
|
|
}
|
|
};
|
|
|
|
reader.onerror = function () {
|
|
showStatus("Error: Failed to read file", true);
|
|
};
|
|
|
|
reader.readAsText(file);
|
|
};
|
|
|
|
input.click();
|
|
}
|
|
|
|
function showStatus(message, isError = false) {
|
|
const status = document.getElementById("status");
|
|
if (status) {
|
|
status.textContent = message;
|
|
status.style.color = isError ? "#d32f2f" : "";
|
|
setTimeout(function () {
|
|
status.textContent = "";
|
|
status.style.color = "";
|
|
}, 3000);
|
|
}
|
|
}
|
|
|
|
// Initialize import/export buttons when DOM is ready
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", initImportExport);
|
|
} else {
|
|
initImportExport();
|
|
}
|
|
|
|
function initImportExport() {
|
|
const exportBtn = document.getElementById("exportSettings");
|
|
const importBtn = document.getElementById("importSettings");
|
|
|
|
if (exportBtn) {
|
|
exportBtn.addEventListener("click", exportSettings);
|
|
}
|
|
|
|
if (importBtn) {
|
|
importBtn.addEventListener("click", importSettings);
|
|
}
|
|
}
|