Storage controller refactor (#905)
* Use hidden instead of storage-hidden class * Refactor storage events * Make ID more generic * Update how persistent storage is activated * Add null checks * Update HTML/ID * Disallow disabling persistent storage * Refactoring * Update more IDs * Disable multiple simultaneous stats updates * Store node references * Move undefined assignment
This commit is contained in:
parent
3174f3c657
commit
199dd7d763
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
.storage-hidden {
|
.help-block[hidden] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,15 +20,35 @@ class StorageController {
|
|||||||
this._mostRecentStorageEstimate = null;
|
this._mostRecentStorageEstimate = null;
|
||||||
this._storageEstimateFailed = false;
|
this._storageEstimateFailed = false;
|
||||||
this._isUpdating = false;
|
this._isUpdating = false;
|
||||||
|
this._persistentStorageCheckbox = false;
|
||||||
|
this._storageUsageNode = null;
|
||||||
|
this._storageQuotaNode = null;
|
||||||
|
this._storageUseFiniteNode = null;
|
||||||
|
this._storageUseInfiniteNode = null;
|
||||||
|
this._storageUseUndefinedNode = null;
|
||||||
|
this._storageUseNode = null;
|
||||||
|
this._storageErrorNode = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare() {
|
prepare() {
|
||||||
|
this._persistentStorageCheckbox = document.querySelector('#storage-persistent-checkbox');
|
||||||
|
this._storageUsageNode = document.querySelector('#storage-usage');
|
||||||
|
this._storageQuotaNode = document.querySelector('#storage-quota');
|
||||||
|
this._storageUseFiniteNode = document.querySelector('#storage-use-finite');
|
||||||
|
this._storageUseInfiniteNode = document.querySelector('#storage-use-infinite');
|
||||||
|
this._storageUseUndefinedNode = document.querySelector('#storage-use-undefined');
|
||||||
|
this._storageUseNode = document.querySelector('#storage-use');
|
||||||
|
this._storageErrorNode = document.querySelector('#storage-error');
|
||||||
|
|
||||||
this._preparePersistentStorage();
|
this._preparePersistentStorage();
|
||||||
this.updateStats();
|
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.updateStats.bind(this), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateStats() {
|
async updateStats() {
|
||||||
|
if (this._isUpdating) { return; }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this._isUpdating = true;
|
this._isUpdating = true;
|
||||||
|
|
||||||
@ -39,15 +59,16 @@ class StorageController {
|
|||||||
// Firefox reports usage as 0 when persistent storage is enabled.
|
// Firefox reports usage as 0 when persistent storage is enabled.
|
||||||
const finite = (estimate.usage > 0 || !(await this._isStoragePeristent()));
|
const finite = (estimate.usage > 0 || !(await this._isStoragePeristent()));
|
||||||
if (finite) {
|
if (finite) {
|
||||||
document.querySelector('#storage-usage').textContent = this._bytesToLabeledString(estimate.usage);
|
this._storageUsageNode.textContent = this._bytesToLabeledString(estimate.usage);
|
||||||
document.querySelector('#storage-quota').textContent = this._bytesToLabeledString(estimate.quota);
|
this._storageQuotaNode.textContent = this._bytesToLabeledString(estimate.quota);
|
||||||
}
|
}
|
||||||
document.querySelector('#storage-use-finite').classList.toggle('storage-hidden', !finite);
|
this._storageUseFiniteNode.hidden = !finite;
|
||||||
document.querySelector('#storage-use-infinite').classList.toggle('storage-hidden', finite);
|
this._storageUseInfiniteNode.hidden = finite;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('#storage-use').classList.toggle('storage-hidden', !valid);
|
if (this._storageUseUndefinedNode !== null) { this._storageUseUndefinedNode.hidden = !valid; }
|
||||||
document.querySelector('#storage-error').classList.toggle('storage-hidden', valid);
|
if (this._storageUseNode !== null) { this._storageUseNode.hidden = !valid; }
|
||||||
|
if (this._storageErrorNode !== null) { this._storageErrorNode.hidden = valid; }
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
} finally {
|
} finally {
|
||||||
@ -63,35 +84,53 @@ class StorageController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const info = document.querySelector('#storage-persist-info');
|
const info = document.querySelector('#storage-persistent-info');
|
||||||
const button = document.querySelector('#storage-persist-button');
|
if (info !== null) { info.hidden = false; }
|
||||||
const checkbox = document.querySelector('#storage-persist-button-checkbox');
|
|
||||||
|
|
||||||
info.classList.remove('storage-hidden');
|
const isStoragePeristent = await this._isStoragePeristent();
|
||||||
button.classList.remove('storage-hidden');
|
this._updateCheckbox(isStoragePeristent);
|
||||||
|
|
||||||
let persisted = await this._isStoragePeristent();
|
const button = document.querySelector('#storage-persistent-button');
|
||||||
checkbox.checked = persisted;
|
if (button !== null) {
|
||||||
|
button.hidden = false;
|
||||||
|
button.addEventListener('click', this._onPersistStorageButtonClick.bind(this), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
button.addEventListener('click', async () => {
|
_onPersistentStorageCheckboxChange(e) {
|
||||||
if (persisted) {
|
const node = e.currentTarget;
|
||||||
return;
|
if (!node.checked) {
|
||||||
}
|
node.checked = true;
|
||||||
let result = false;
|
return;
|
||||||
try {
|
}
|
||||||
result = await navigator.storage.persist();
|
this._attemptPersistStorage();
|
||||||
} catch (e) {
|
}
|
||||||
// NOP
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
_onPersistStorageButtonClick() {
|
||||||
persisted = true;
|
const {checked} = this._persistentStorageCheckbox;
|
||||||
checkbox.checked = true;
|
if (checked) { return; }
|
||||||
this.updateStats();
|
this._persistentStorageCheckbox.checked = !checked;
|
||||||
} else {
|
this._persistentStorageCheckbox.dispatchEvent(new Event('change'));
|
||||||
document.querySelector('.storage-persist-fail-warning').classList.remove('storage-hidden');
|
}
|
||||||
}
|
|
||||||
}, false);
|
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() {
|
async _storageEstimate() {
|
||||||
@ -128,4 +167,10 @@ class StorageController {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_updateCheckbox(isStoragePeristent) {
|
||||||
|
const checkbox = this._persistentStorageCheckbox;
|
||||||
|
checkbox.checked = isStoragePeristent;
|
||||||
|
checkbox.readOnly = isStoragePeristent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -796,7 +796,7 @@
|
|||||||
<h3>Storage</h3>
|
<h3>Storage</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="storage-persist-info" class="storage-hidden">
|
<div id="storage-persistent-info" hidden>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Web browsers may sometimes clear stored data if the device is running low on storage space.
|
Web browsers may sometimes clear stored data if the device is running low on storage space.
|
||||||
This can result in the stored dictionary data being deleted unexpectedly, causing Yomichan to stop working for no apparent reason.
|
This can result in the stored dictionary data being deleted unexpectedly, causing Yomichan to stop working for no apparent reason.
|
||||||
@ -804,16 +804,19 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="storage-use" class="storage-hidden">
|
<div id="storage-use" hidden>
|
||||||
<p class="help-block storage-hidden" id="storage-use-finite">
|
<p class="help-block" id="storage-use-undefined">
|
||||||
|
Yomichan is using an indeterminate amount of storage.
|
||||||
|
</p>
|
||||||
|
<p class="help-block" id="storage-use-finite" hidden>
|
||||||
Yomichan is using approximately <strong id="storage-usage"></strong> of <strong id="storage-quota"></strong>.
|
Yomichan is using approximately <strong id="storage-usage"></strong> of <strong id="storage-quota"></strong>.
|
||||||
</p>
|
</p>
|
||||||
<p class="help-block storage-hidden" id="storage-use-infinite">
|
<p class="help-block" id="storage-use-infinite" hidden>
|
||||||
Yomichan is permitted <strong>unlimited storage</strong>.
|
Yomichan is permitted <strong>unlimited storage</strong>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="storage-error" class="storage-hidden">
|
<div id="storage-error" hidden>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Could not detect how much storage Yomichan is using.
|
Could not detect how much storage Yomichan is using.
|
||||||
</p>
|
</p>
|
||||||
@ -832,22 +835,24 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button class="btn btn-default" id="storage-refresh"><span class="btn-inner-middle">Refresh</span></button>
|
<button class="btn btn-default" id="storage-refresh"><span class="btn-inner-middle">Refresh</span></button>
|
||||||
<button class="btn btn-default storage-hidden ignore-form-changes" id="storage-persist-button"><span class="storage-button-inner"><input type="checkbox" class="btn-inner-middle storage-button-checkbox" id="storage-persist-button-checkbox" readonly /><span class="btn-inner-middle">Persistent Storage</span></span></button>
|
<button class="btn btn-default ignore-form-changes" id="storage-persistent-button" hidden><span class="storage-button-inner"><input type="checkbox" class="btn-inner-middle storage-button-checkbox" id="storage-persistent-checkbox" readonly /><span class="btn-inner-middle">Persistent Storage</span></span></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p></p>
|
<p></p>
|
||||||
|
|
||||||
<div data-show-for-browser="firefox-mobile"><div class="alert alert-warning storage-persist-fail-warning storage-hidden">
|
<div id="storage-persistent-fail-warning" hidden>
|
||||||
<p>It may not be possible to enable Persistent Storage on Firefox for Android.</p>
|
<div data-show-for-browser="firefox-mobile"><div class="alert alert-warning">
|
||||||
</div></div>
|
<p>It may not be possible to enable Persistent Storage on Firefox for Android.</p>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
<div data-show-for-browser="chrome"><div class="alert alert-warning storage-persist-fail-warning storage-hidden">
|
<div data-show-for-browser="chrome"><div class="alert alert-warning">
|
||||||
<p>
|
<p>
|
||||||
It may not be possible to enable Persistent Storage on Chrome-based browsers.
|
It may not be possible to enable Persistent Storage on Chrome-based browsers.
|
||||||
However, the Yomichan extension has permission for unlimited storage which should
|
However, the Yomichan extension has permission for unlimited storage which should
|
||||||
prevent Chrome from deleting data.<sup><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=680392#c15" target="_blank" rel="noopener">[1]</a></sup>
|
prevent Chrome from deleting data.<sup><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=680392#c15" target="_blank" rel="noopener">[1]</a></sup>
|
||||||
</p>
|
</p>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
Loading…
Reference in New Issue
Block a user