From a1f028f11acd63ba6e21842fbbfb890ae684771f Mon Sep 17 00:00:00 2001 From: Richard Frost Date: Fri, 5 Apr 2019 20:47:07 -0600 Subject: [PATCH] :sparkles: Config UI - Import/Export file --- src/script/lib/helper.ts | 8 +++++ src/script/optionPage.ts | 63 +++++++++++++++++++++++++++++--------- src/static/optionPage.html | 9 ++++-- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/script/lib/helper.ts b/src/script/lib/helper.ts index e0404668..ed04496d 100644 --- a/src/script/lib/helper.ts +++ b/src/script/lib/helper.ts @@ -61,6 +61,14 @@ export function isVersionOlder(version: Version, minimum: Version): boolean { return false; } +export function readFile(file) { + return new Promise((resolve, reject) => { + let fr = new FileReader(); + fr.onload = () => { resolve(fr.result); }; + fr.readAsText(file); + }); +} + export function removeFromArray(array: string[], element: string) { return array.filter(e => e !== element); } \ No newline at end of file diff --git a/src/script/optionPage.ts b/src/script/optionPage.ts index 79f3ae11..67b786cc 100644 --- a/src/script/optionPage.ts +++ b/src/script/optionPage.ts @@ -1,4 +1,4 @@ -import { dynamicList, escapeHTML, exportToFile } from './lib/helper'; +import { dynamicList, escapeHTML, exportToFile, readFile } from './lib/helper'; import WebConfig from './webConfig'; import { Filter } from './lib/filter'; import OptionAuth from './optionAuth'; @@ -142,6 +142,18 @@ export default class OptionPage { } } + configInlineToggle() { + let input = document.getElementById('configInlineInput') as HTMLInputElement; + let configText = document.getElementById('configText') as HTMLTextAreaElement; + if (input.checked) { + OptionPage.show(configText); + option.exportConfig(); + } else { + OptionPage.hide(configText); + configText.value = ''; + } + } + confirm(evt, action) { let ok = document.getElementById('confirmModalOK'); ok.removeEventListener('click', importConfig); @@ -151,8 +163,6 @@ export default class OptionPage { switch(action) { case 'importConfig': { - let configText = document.getElementById('configText') as HTMLTextAreaElement; - if (!configText.value) return false; OptionPage.configureConfirmModal('Are you sure you want to overwrite your existing settings?'); ok.addEventListener('click', importConfig); break; @@ -244,20 +254,45 @@ export default class OptionPage { } exportConfig() { - let configText = document.getElementById('configText') as HTMLTextAreaElement; - configText.value = JSON.stringify(this.cfg, null, 2); + let input = document.getElementById('configInlineInput') as HTMLInputElement; + + if (input.checked) { // inline editor + let configText = document.getElementById('configText') as HTMLTextAreaElement; + configText.value = JSON.stringify(this.cfg, null, 2); + } else { + let date = new Date; + let today = `${date.getUTCFullYear()}-${('0'+(date.getUTCMonth()+1)).slice(-2)}-${('0'+(date.getUTCDate()+1)).slice(-2)}`; + exportToFile(JSON.stringify(this.cfg, null, 2), `apf-backup-${today}.json`); + } + } + + async importConfig(e) { + let input = document.getElementById('configInlineInput') as HTMLInputElement; + if (input.checked) { // inline editor + let configText = document.getElementById('configText') as HTMLTextAreaElement; + this.importConfigText(configText.value); + } else { + let importFileInput = document.getElementById('importFileInput') as HTMLInputElement; + importFileInput.click(); + } + } + + async importConfigFile(e) { + let file = e.target.files[0]; + let importFileInput = document.getElementById('importFileInput') as HTMLInputElement; + let fileText = await readFile(file) as string; + option.importConfigText(fileText); + importFileInput.value = ''; } - async importConfig(evt) { + async importConfigText(cfg: string) { let self = this; try { - let configText = document.getElementById('configText') as HTMLTextAreaElement; - let importedCfg = new WebConfig(JSON.parse(configText.value)); + let importedCfg = new WebConfig(JSON.parse(cfg)); let migration = new DataMigration(importedCfg); migration.runImportMigrations(); - - let resetSuccess = await self.restoreDefaults(evt, true); + let resetSuccess = await self.restoreDefaults(null, true); if (resetSuccess) { self.cfg = importedCfg; @@ -268,11 +303,9 @@ export default class OptionPage { } else { OptionPage.showErrorModal('Failed to import settings.'); } - } else { - OptionPage.showErrorModal('Failed to import settings.'); } - } catch (e) { - OptionPage.showErrorModal(); + } catch(e) { + OptionPage.showErrorModal('Failed to import settings.'); } } @@ -727,6 +760,8 @@ document.querySelectorAll('#audioSubtitleSelection input').forEach(el => { el.ad document.getElementById('bookmarkletFile').addEventListener('click', e => { option.exportBookmarkletFile(); }); document.getElementById('bookmarkletHostedURL').addEventListener('input', e => { option.createBookmarklet(); }); // Config +document.getElementById('configInlineInput').addEventListener('click', e => { option.configInlineToggle(); }); +document.getElementById('importFileInput').addEventListener('change', e => { option.importConfigFile(e); }); document.getElementById('configReset').addEventListener('click', e => { option.confirm(e, 'restoreDefaults'); }); document.getElementById('configExport').addEventListener('click', e => { option.exportConfig(); }); document.getElementById('configImport').addEventListener('click', e => { option.confirm(e, 'importConfig'); }); diff --git a/src/static/optionPage.html b/src/static/optionPage.html index f8a3c716..890db840 100644 --- a/src/static/optionPage.html +++ b/src/static/optionPage.html @@ -306,15 +306,18 @@

Bookmarklet:

+

Configuration

+
+
- + -
- +
+

Password