diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index be9c422..7df467a 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -284,6 +284,24 @@ "isDebugModeCaptionLabel": { "message": "When debug mode is enabled, the log is output to the debugger." }, + "exportSettingsLabel": { + "message": "Export settings" + }, + "exportSettingsCaptionLabel": { + "message": "Save the settings as a json file on the computer." + }, + "exportButtonLabel": { + "message": "Export" + }, + "importSettingsLabel": { + "message": "Import Settings" + }, + "importSettingsCaptionLabel": { + "message": "Load the settings file saved on the computer." + }, + "importButtonLabel": { + "message": "Import" + }, "resetSettingsLabel": { "message": "Reset settings" }, diff --git a/src/options/components/SettingsPage.js b/src/options/components/SettingsPage.js index e910305..76e66e8 100644 --- a/src/options/components/SettingsPage.js +++ b/src/options/components/SettingsPage.js @@ -1,7 +1,7 @@ import React, { Component } from "react"; import browser from "webextension-polyfill"; import { updateLogLevel, overWriteLogLevel } from "src/common/log"; -import { initSettings, resetAllSettings } from "src/settings/settings"; +import { initSettings, resetAllSettings, exportSettings, importSettings } from "src/settings/settings"; import defaultSettings from "src/settings/defaultSettings"; import CategoryContainer from "./CategoryContainer"; @@ -44,6 +44,25 @@ export default class SettingsPage extends Component { const additionalCategory = { category: "", elements: [ + { + id: "importSettings", + title: "importSettingsLabel", + captions: ["importSettingsCaptionLabel"], + type: "file", + accept: ".json", + value: "importButtonLabel", + onChange: importSettings + }, + { + id: "exportSettings", + title: "exportSettingsLabel", + captions: ["exportSettingsCaptionLabel"], + type: "button", + value: "exportButtonLabel", + onClick: async () => { + await exportSettings(); + } + }, { id: "resetSettings", title: "resetSettingsLabel", diff --git a/src/settings/settings.js b/src/settings/settings.js index c4cac9b..a1a1188 100644 --- a/src/settings/settings.js +++ b/src/settings/settings.js @@ -57,3 +57,59 @@ export const handleSettingsChange = (changes, area) => { currentSettings = changes.Settings.newValue; } }; + +export const exportSettings = async () => { + const settingsIds = getSettingsIds(); + + let settingsObj = {}; + for (const id of settingsIds) { + settingsObj[id] = getSettings(id); + } + + const downloadUrl = URL.createObjectURL( + new Blob([JSON.stringify(settingsObj, null, " ")], { + type: "aplication/json" + }) + ); + + const a = document.createElement("a"); + document.body.appendChild(a); + a.download = "SimpleTranslate_Settings.json"; + a.href = downloadUrl; + a.click(); + a.remove(); + URL.revokeObjectURL(downloadUrl); +}; + +export const importSettings = async e => { + const reader = new FileReader(); + + reader.onload = async () => { + const importedSettings = JSON.parse(reader.result); + const settingsIds = getSettingsIds(); + + for (const id of settingsIds) { + if (importedSettings[id] !== undefined) await setSettings(id, importedSettings[id]); + } + + location.reload(true); + }; + + const file = e.target.files[0]; + reader.readAsText(file); +}; + +const getSettingsIds = () => { + let settingsIds = []; + defaultSettings.forEach(category => { + category.elements.forEach(optionElement => { + if (optionElement.id && optionElement.default !== undefined) settingsIds.push(optionElement.id); + if (optionElement.childElements) { + optionElement.childElements.forEach(childElement => { + if (childElement.id && childElement.default !== undefined) settingsIds.push(childElement.id); + }); + } + }); + }); + return settingsIds; +}; \ No newline at end of file