diff options
| -rw-r--r-- | ext/js/pages/settings/dictionary-controller.js | 10 | ||||
| -rw-r--r-- | ext/js/pages/settings/dictionary-import-controller.js | 15 | ||||
| -rw-r--r-- | ext/js/pages/settings/main.js | 10 | ||||
| -rw-r--r-- | ext/js/pages/settings/persistent-storage-controller.js | 94 | ||||
| -rw-r--r-- | ext/js/pages/settings/settings-main.js | 10 | ||||
| -rw-r--r-- | ext/js/pages/settings/storage-controller.js | 97 | ||||
| -rw-r--r-- | ext/js/pages/welcome-main.js | 4 | ||||
| -rw-r--r-- | ext/settings-old.html | 1 | ||||
| -rw-r--r-- | ext/settings.html | 1 | 
9 files changed, 144 insertions, 98 deletions
| diff --git a/ext/js/pages/settings/dictionary-controller.js b/ext/js/pages/settings/dictionary-controller.js index e12017f2..17abfa13 100644 --- a/ext/js/pages/settings/dictionary-controller.js +++ b/ext/js/pages/settings/dictionary-controller.js @@ -190,10 +190,9 @@ class DictionaryEntry {  }  class DictionaryController { -    constructor(settingsController, modalController, storageController, statusFooter) { +    constructor(settingsController, modalController, statusFooter) {          this._settingsController = settingsController;          this._modalController = modalController; -        this._storageController = storageController;          this._statusFooter = statusFooter;          this._dictionaries = null;          this._dictionaryEntries = []; @@ -436,7 +435,6 @@ class DictionaryController {          const index = this._dictionaryEntries.findIndex((entry) => entry.dictionaryTitle === dictionaryTitle);          if (index < 0) { return; } -        const storageController = this._storageController;          const statusFooter = this._statusFooter;          const {node} = this._dictionaryEntries[index];          const progressSelector = '.dictionary-delete-progress'; @@ -483,7 +481,7 @@ class DictionaryController {              if (statusFooter !== null) { statusFooter.setTaskActive(progressSelector, false); }              this._setButtonsEnabled(true);              this._isDeleting = false; -            if (storageController !== null) { storageController.updateStats(); } +            this._triggerStorageChanged();          }      } @@ -547,6 +545,10 @@ class DictionaryController {          }      } +    _triggerStorageChanged() { +        yomichan.trigger('storageChanged'); +    } +      static createDefaultDictionarySettings() {          return {              enabled: false, diff --git a/ext/js/pages/settings/dictionary-import-controller.js b/ext/js/pages/settings/dictionary-import-controller.js index 1389b7f0..ce724263 100644 --- a/ext/js/pages/settings/dictionary-import-controller.js +++ b/ext/js/pages/settings/dictionary-import-controller.js @@ -22,10 +22,9 @@   */  class DictionaryImportController { -    constructor(settingsController, modalController, storageController, statusFooter) { +    constructor(settingsController, modalController, statusFooter) {          this._settingsController = settingsController;          this._modalController = modalController; -        this._storageController = storageController;          this._statusFooter = statusFooter;          this._modifying = false;          this._purgeButton = null; @@ -92,7 +91,6 @@ class DictionaryImportController {          if (this._modifying) { return; }          const purgeNotification = this._purgeNotification; -        const storageController = this._storageController;          const prevention = this._preventPageExit();          try { @@ -114,7 +112,7 @@ class DictionaryImportController {              if (purgeNotification !== null) { purgeNotification.hidden = true; }              this._setSpinnerVisible(false);              this._setModifying(false); -            if (storageController !== null) { storageController.updateStats(); } +            this._triggerStorageChanged();          }      } @@ -122,7 +120,6 @@ class DictionaryImportController {          if (this._modifying) { return; }          const statusFooter = this._statusFooter; -        const storageController = this._storageController;          const importInfo = document.querySelector('#dictionary-import-info');          const progressSelector = '.dictionary-import-progress';          const progressContainers = [ @@ -156,7 +153,7 @@ class DictionaryImportController {                  const statusString = `${percent.toFixed(0)}%`;                  for (const progressBar of progressBars) { progressBar.style.width = cssString; }                  for (const label of statusLabels) { label.textContent = statusString; } -                if (storageController !== null) { storageController.updateStats(); } +                this._triggerStorageChanged();              };              const fileCount = files.length; @@ -186,7 +183,7 @@ class DictionaryImportController {              }              this._setSpinnerVisible(false);              this._setModifying(false); -            if (storageController !== null) { storageController.updateStats(); } +            this._triggerStorageChanged();          }      } @@ -342,4 +339,8 @@ class DictionaryImportController {          }          return errors;      } + +    _triggerStorageChanged() { +        yomichan.trigger('storageChanged'); +    }  } diff --git a/ext/js/pages/settings/main.js b/ext/js/pages/settings/main.js index 9785ee0e..3ccf2dd6 100644 --- a/ext/js/pages/settings/main.js +++ b/ext/js/pages/settings/main.js @@ -25,6 +25,7 @@   * GenericSettingController   * ModalController   * PermissionsToggleController + * PersistentStorageController   * PopupPreviewController   * ProfileController   * ScanInputsController @@ -63,7 +64,10 @@ async function setupEnvironmentInfo() {          const settingsController = new SettingsController(optionsFull.profileCurrent);          settingsController.prepare(); -        const storageController = new StorageController(); +        const persistentStorageController = new PersistentStorageController(); +        persistentStorageController.prepare(); + +        const storageController = new StorageController(persistentStorageController);          storageController.prepare();          const genericSettingController = new GenericSettingController(settingsController); @@ -81,10 +85,10 @@ async function setupEnvironmentInfo() {          const profileController = new ProfileController(settingsController, modalController);          profileController.prepare(); -        const dictionaryController = new DictionaryController(settingsController, modalController, storageController, null); +        const dictionaryController = new DictionaryController(settingsController, modalController, null);          dictionaryController.prepare(); -        const dictionaryImportController = new DictionaryImportController(settingsController, modalController, storageController, null); +        const dictionaryImportController = new DictionaryImportController(settingsController, modalController, null);          dictionaryImportController.prepare();          const ankiController = new AnkiController(settingsController); diff --git a/ext/js/pages/settings/persistent-storage-controller.js b/ext/js/pages/settings/persistent-storage-controller.js new file mode 100644 index 00000000..e46dbe87 --- /dev/null +++ b/ext/js/pages/settings/persistent-storage-controller.js @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2021  Yomichan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +class PersistentStorageController { +    constructor() { +        this._persistentStorageCheckbox = false; +    } + +    async prepare() { +        this._persistentStorageCheckbox = document.querySelector('#storage-persistent-checkbox'); +        this._persistentStorageCheckbox.addEventListener('change', this._onPersistentStorageCheckboxChange.bind(this), false); + +        const button = document.querySelector('#storage-persistent-button'); +        if (button !== null) { +            button.hidden = false; +            button.addEventListener('click', this._onPersistStorageButtonClick.bind(this), false); +        } + +        if (!this._isPersistentStorageSupported()) { return; } + +        const info = document.querySelector('#storage-persistent-info'); +        if (info !== null) { info.hidden = false; } + +        const isStoragePeristent = await this.isStoragePeristent(); +        this._updateCheckbox(isStoragePeristent); +    } + +    async isStoragePeristent() { +        try { +            return await navigator.storage.persisted(); +        } catch (e) { +            // NOP +        } +        return false; +    } + +    // Private + +    _onPersistentStorageCheckboxChange(e) { +        const node = e.currentTarget; +        if (node.checked) { +            node.checked = false; +            this._attemptPersistStorage(); +        } else { +            node.checked = true; +        } +    } + +    _onPersistStorageButtonClick() { +        const {checked} = this._persistentStorageCheckbox; +        if (checked) { return; } +        this._persistentStorageCheckbox.checked = !checked; +        this._persistentStorageCheckbox.dispatchEvent(new Event('change')); +    } + +    async _attemptPersistStorage() { +        let isStoragePeristent = false; +        try { +            isStoragePeristent = await navigator.storage.persist(); +        } catch (e) { +            // NOP +        } + +        this._updateCheckbox(isStoragePeristent); + +        const node = document.querySelector('#storage-persistent-fail-warning'); +        if (node !== null) { node.hidden = isStoragePeristent; } + +        yomichan.trigger('storageChanged'); +    } + +    _isPersistentStorageSupported() { +        return isObject(navigator.storage) && typeof navigator.storage.persist === 'function'; +    } + +    _updateCheckbox(isStoragePeristent) { +        this._persistentStorageCheckbox.checked = isStoragePeristent; +        this._persistentStorageCheckbox.readOnly = isStoragePeristent; +    } +} diff --git a/ext/js/pages/settings/settings-main.js b/ext/js/pages/settings/settings-main.js index 273142cd..3618836c 100644 --- a/ext/js/pages/settings/settings-main.js +++ b/ext/js/pages/settings/settings-main.js @@ -30,6 +30,7 @@   * ModalController   * NestedPopupsController   * PermissionsToggleController + * PersistentStorageController   * PopupPreviewController   * PopupWindowController   * ProfileController @@ -79,13 +80,16 @@ async function setupGenericSettingsController(genericSettingController) {          const settingsController = new SettingsController(optionsFull.profileCurrent);          settingsController.prepare(); -        const storageController = new StorageController(); +        const persistentStorageController = new PersistentStorageController(); +        persistentStorageController.prepare(); + +        const storageController = new StorageController(persistentStorageController);          storageController.prepare(); -        const dictionaryController = new DictionaryController(settingsController, modalController, storageController, statusFooter); +        const dictionaryController = new DictionaryController(settingsController, modalController, statusFooter);          dictionaryController.prepare(); -        const dictionaryImportController = new DictionaryImportController(settingsController, modalController, storageController, statusFooter); +        const dictionaryImportController = new DictionaryImportController(settingsController, modalController, statusFooter);          dictionaryImportController.prepare();          const genericSettingController = new GenericSettingController(settingsController); diff --git a/ext/js/pages/settings/storage-controller.js b/ext/js/pages/settings/storage-controller.js index c27c8690..d92ecff0 100644 --- a/ext/js/pages/settings/storage-controller.js +++ b/ext/js/pages/settings/storage-controller.js @@ -16,11 +16,11 @@   */  class StorageController { -    constructor() { +    constructor(persistentStorageController) { +        this._persistentStorageController = persistentStorageController;          this._mostRecentStorageEstimate = null;          this._storageEstimateFailed = false;          this._isUpdating = false; -        this._persistentStorageCheckbox = false;          this._storageUsageNode = null;          this._storageQuotaNode = null;          this._storageUseFiniteNodes = null; @@ -30,7 +30,6 @@ class StorageController {      }      prepare() { -        this._persistentStorageCheckbox = document.querySelector('#storage-persistent-checkbox');          this._storageUsageNodes = document.querySelectorAll('.storage-usage');          this._storageQuotaNodes = document.querySelectorAll('.storage-quota');          this._storageUseFiniteNodes = document.querySelectorAll('.storage-use-finite'); @@ -38,13 +37,23 @@ class StorageController {          this._storageUseValidNodes = document.querySelectorAll('.storage-use-valid');          this._storageUseInvalidNodes = document.querySelectorAll('.storage-use-invalid'); -        this._preparePersistentStorage(); -        this.updateStats(); -        this._persistentStorageCheckbox.addEventListener('change', this._onPersistentStorageCheckboxChange.bind(this), false); -        document.querySelector('#storage-refresh').addEventListener('click', this.updateStats.bind(this), false); +        document.querySelector('#storage-refresh').addEventListener('click', this._onStorageRefreshButtonClick.bind(this), false); +        yomichan.on('storageChanged', this._onStorageChanged.bind(this)); + +        this._updateStats(); +    } + +    // Private + +    _onStorageRefreshButtonClick() { +        this._updateStats();      } -    async updateStats() { +    _onStorageChanged() { +        this._updateStats(); +    } + +    async _updateStats() {          if (this._isUpdating) { return; }          try { @@ -54,7 +63,7 @@ class StorageController {              const valid = (estimate !== null);              // Firefox reports usage as 0 when persistent storage is enabled. -            const finite = valid && (estimate.usage > 0 || !(await this._isStoragePeristent())); +            const finite = valid && (estimate.usage > 0 || !(await this._persistentStorageController.isStoragePeristent()));              if (finite) {                  for (const node of this._storageUsageNodes) {                      node.textContent = this._bytesToLabeledString(estimate.usage); @@ -77,61 +86,6 @@ class StorageController {      // Private -    async _preparePersistentStorage() { -        if (!(navigator.storage && navigator.storage.persist)) { -            // Not supported -            return; -        } - -        const info = document.querySelector('#storage-persistent-info'); -        if (info !== null) { info.hidden = false; } - -        const isStoragePeristent = await this._isStoragePeristent(); -        this._updateCheckbox(isStoragePeristent); - -        const button = document.querySelector('#storage-persistent-button'); -        if (button !== null) { -            button.hidden = false; -            button.addEventListener('click', this._onPersistStorageButtonClick.bind(this), false); -        } -    } - -    _onPersistentStorageCheckboxChange(e) { -        const node = e.currentTarget; -        if (!node.checked) { -            node.checked = true; -            return; -        } -        this._attemptPersistStorage(); -    } - -    _onPersistStorageButtonClick() { -        const {checked} = this._persistentStorageCheckbox; -        if (checked) { return; } -        this._persistentStorageCheckbox.checked = !checked; -        this._persistentStorageCheckbox.dispatchEvent(new Event('change')); -    } - -    async _attemptPersistStorage() { -        if (await this._isStoragePeristent()) { return; } - -        let isStoragePeristent = false; -        try { -            isStoragePeristent = await navigator.storage.persist(); -        } catch (e) { -            // NOP -        } - -        this._updateCheckbox(isStoragePeristent); - -        if (isStoragePeristent) { -            this.updateStats(); -        } else { -            const node = document.querySelector('#storage-persistent-fail-warning'); -            if (node !== null) { node.hidden = false; } -        } -    } -      async _storageEstimate() {          if (this._storageEstimateFailed && this._mostRecentStorageEstimate === null) {              return null; @@ -159,21 +113,6 @@ class StorageController {          return `${label}${labels[labelIndex]}`;      } -    async _isStoragePeristent() { -        try { -            return await navigator.storage.persisted(); -        } catch (e) { -            // NOP -        } -        return false; -    } - -    _updateCheckbox(isStoragePeristent) { -        const checkbox = this._persistentStorageCheckbox; -        checkbox.checked = isStoragePeristent; -        checkbox.readOnly = isStoragePeristent; -    } -      _setElementsVisible(elements, visible) {          visible = !visible;          for (const element of elements) { diff --git a/ext/js/pages/welcome-main.js b/ext/js/pages/welcome-main.js index 27d0af6a..90067282 100644 --- a/ext/js/pages/welcome-main.js +++ b/ext/js/pages/welcome-main.js @@ -62,10 +62,10 @@ async function setupGenericSettingsController(genericSettingController) {          const settingsController = new SettingsController(optionsFull.profileCurrent);          settingsController.prepare(); -        const dictionaryController = new DictionaryController(settingsController, modalController, null, statusFooter); +        const dictionaryController = new DictionaryController(settingsController, modalController, statusFooter);          dictionaryController.prepare(); -        const dictionaryImportController = new DictionaryImportController(settingsController, modalController, null, statusFooter); +        const dictionaryImportController = new DictionaryImportController(settingsController, modalController, statusFooter);          dictionaryImportController.prepare();          const genericSettingController = new GenericSettingController(settingsController); diff --git a/ext/settings-old.html b/ext/settings-old.html index be791bb2..562ca95d 100644 --- a/ext/settings-old.html +++ b/ext/settings-old.html @@ -1319,6 +1319,7 @@          <script src="/js/pages/settings/modal-controller.js"></script>          <script src="/js/pages/settings/modal-jquery.js"></script>          <script src="/js/pages/settings/permissions-toggle-controller.js"></script> +        <script src="/js/pages/settings/persistent-storage-controller.js"></script>          <script src="/js/pages/settings/popup-preview-controller.js"></script>          <script src="/js/pages/settings/profile-conditions-ui.js"></script>          <script src="/js/pages/settings/profile-controller.js"></script> diff --git a/ext/settings.html b/ext/settings.html index 023e8026..9a176886 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -3270,6 +3270,7 @@  <script src="/js/pages/settings/modal-controller.js"></script>  <script src="/js/pages/settings/nested-popups-controller.js"></script>  <script src="/js/pages/settings/permissions-toggle-controller.js"></script> +<script src="/js/pages/settings/persistent-storage-controller.js"></script>  <script src="/js/pages/settings/popup-preview-controller.js"></script>  <script src="/js/pages/settings/popup-window-controller.js"></script>  <script src="/js/pages/settings/profile-conditions-ui.js"></script> |