aboutsummaryrefslogtreecommitdiff
path: root/ext/bg/js/settings.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/bg/js/settings.js')
-rw-r--r--ext/bg/js/settings.js197
1 files changed, 166 insertions, 31 deletions
diff --git a/ext/bg/js/settings.js b/ext/bg/js/settings.js
index 4bf7181f..49bf264d 100644
--- a/ext/bg/js/settings.js
+++ b/ext/bg/js/settings.js
@@ -193,7 +193,7 @@ async function onReady() {
await dictionaryGroupsPopulate(options);
await formMainDictionaryOptionsPopulate(options);
} catch (e) {
- dictionaryErrorShow(e);
+ dictionaryErrorsShow([e]);
}
try {
@@ -203,6 +203,8 @@ async function onReady() {
}
formUpdateVisibility(options);
+
+ storageInfoInitialize();
}
$(document).ready(utilAsync(onReady));
@@ -212,36 +214,63 @@ $(document).ready(utilAsync(onReady));
* Dictionary
*/
-function dictionaryErrorShow(error) {
+function dictionaryErrorToString(error) {
+ if (error.toString) {
+ error = error.toString();
+ } else {
+ error = `${error}`;
+ }
+
+ for (const [match, subst] of dictionaryErrorToString.overrides) {
+ if (error.includes(match)) {
+ error = subst;
+ break;
+ }
+ }
+
+ return error;
+}
+dictionaryErrorToString.overrides = [
+ [
+ 'A mutation operation was attempted on a database that did not allow mutations.',
+ 'Access to IndexedDB appears to be restricted. Firefox seems to require that the history preference is set to "Remember history" before IndexedDB use of any kind is allowed.'
+ ],
+ [
+ 'The operation failed for reasons unrelated to the database itself and not covered by any other error code.',
+ 'Unable to access IndexedDB due to a possibly corrupt user profile. Try using the "Refresh Firefox" feature to reset your user profile.'
+ ],
+ [
+ 'BulkError',
+ 'Unable to finish importing dictionary data into IndexedDB. This may indicate that you do not have sufficient disk space available to complete this operation.'
+ ]
+];
+
+function dictionaryErrorsShow(errors) {
const dialog = $('#dict-error');
- if (error) {
- const overrides = [
- [
- 'A mutation operation was attempted on a database that did not allow mutations.',
- 'Access to IndexedDB appears to be restricted. Firefox seems to require that the history preference is set to "Remember history" before IndexedDB use of any kind is allowed.'
- ],
- [
- 'The operation failed for reasons unrelated to the database itself and not covered by any other error code.',
- 'Unable to access IndexedDB due to a possibly corrupt user profile. Try using the "Refresh Firefox" feature to reset your user profile.'
- ],
- [
- 'BulkError',
- 'Unable to finish importing dictionary data into IndexedDB. This may indicate that you do not have sufficient disk space available to complete this operation.'
- ]
- ];
-
- if (error.toString) {
- error = error.toString();
+ dialog.show().text('');
+
+ if (errors !== null && errors.length > 0) {
+ const uniqueErrors = {};
+ for (let e of errors) {
+ e = dictionaryErrorToString(e);
+ uniqueErrors[e] = uniqueErrors.hasOwnProperty(e) ? uniqueErrors[e] + 1 : 1;
}
- for (const [match, subst] of overrides) {
- if (error.includes(match)) {
- error = subst;
- break;
+ for (const e in uniqueErrors) {
+ const count = uniqueErrors[e];
+ const div = document.createElement('p');
+ if (count > 1) {
+ div.textContent = `${e} `;
+ const em = document.createElement('em');
+ em.textContent = `(${count})`;
+ div.appendChild(em);
+ } else {
+ div.textContent = `${e}`;
}
+ dialog.append($(div));
}
- dialog.show().text(error);
+ dialog.show();
} else {
dialog.hide();
}
@@ -317,7 +346,7 @@ async function onDictionaryPurge(e) {
const dictProgress = $('#dict-purge').show();
try {
- dictionaryErrorShow();
+ dictionaryErrorsShow(null);
dictionarySpinnerShow(true);
await utilDatabasePurge();
@@ -329,12 +358,16 @@ async function onDictionaryPurge(e) {
await dictionaryGroupsPopulate(options);
await formMainDictionaryOptionsPopulate(options);
} catch (e) {
- dictionaryErrorShow(e);
+ dictionaryErrorsShow([e]);
} finally {
dictionarySpinnerShow(false);
dictControls.show();
dictProgress.hide();
+
+ if (storageEstimate.mostRecent !== null) {
+ storageUpdateStats();
+ }
}
}
@@ -344,25 +377,37 @@ async function onDictionaryImport(e) {
const dictProgress = $('#dict-import-progress').show();
try {
- dictionaryErrorShow();
+ dictionaryErrorsShow(null);
dictionarySpinnerShow(true);
const setProgress = percent => dictProgress.find('.progress-bar').css('width', `${percent}%`);
- const updateProgress = (total, current) => setProgress(current / total * 100.0);
+ const updateProgress = (total, current) => {
+ setProgress(current / total * 100.0);
+ if (storageEstimate.mostRecent !== null && !storageUpdateStats.isUpdating) {
+ storageUpdateStats();
+ }
+ };
setProgress(0.0);
+ const exceptions = [];
const options = await optionsLoad();
- const summary = await utilDatabaseImport(e.target.files[0], updateProgress);
+ const summary = await utilDatabaseImport(e.target.files[0], updateProgress, exceptions);
options.dictionaries[summary.title] = {enabled: true, priority: 0, allowSecondarySearches: false};
if (summary.sequenced && options.general.mainDictionary === '') {
options.general.mainDictionary = summary.title;
}
+
+ if (exceptions.length > 0) {
+ exceptions.push(`Dictionary may not have been imported properly: ${exceptions.length} error${exceptions.length === 1 ? '' : 's'} reported.`);
+ dictionaryErrorsShow(exceptions);
+ }
+
await optionsSave(options);
await dictionaryGroupsPopulate(options);
await formMainDictionaryOptionsPopulate(options);
} catch (e) {
- dictionaryErrorShow(e);
+ dictionaryErrorsShow([e]);
} finally {
dictionarySpinnerShow(false);
@@ -520,3 +565,93 @@ async function onAnkiFieldTemplatesReset(e) {
ankiErrorShow(e);
}
}
+
+
+/*
+ * Storage
+ */
+
+async function getBrowser() {
+ if (typeof chrome !== "undefined") {
+ if (typeof browser !== "undefined") {
+ try {
+ const info = await browser.runtime.getBrowserInfo();
+ if (info.name === "Fennec") {
+ return "firefox-mobile";
+ }
+ } catch (e) { }
+ return "firefox";
+ } else {
+ return "chrome";
+ }
+ } else {
+ return "edge";
+ }
+}
+
+function storageBytesToLabeledString(size) {
+ const base = 1000;
+ const labels = ["bytes", "KB", "MB", "GB"];
+ let labelIndex = 0;
+ while (size >= base) {
+ size /= base;
+ ++labelIndex;
+ }
+ const label = size.toFixed(1);
+ return `${label}${labels[labelIndex]}`;
+}
+
+async function storageEstimate() {
+ try {
+ return (storageEstimate.mostRecent = await navigator.storage.estimate());
+ } catch (e) { }
+ return null;
+}
+storageEstimate.mostRecent = null;
+
+async function storageInfoInitialize() {
+ const browser = await getBrowser();
+ const container = document.querySelector("#storage-info");
+ container.setAttribute("data-browser", browser);
+
+ await storageShowInfo();
+
+ container.classList.remove("storage-hidden");
+
+ document.querySelector("#storage-refresh").addEventListener('click', () => storageShowInfo(), false);
+}
+
+async function storageUpdateStats() {
+ storageUpdateStats.isUpdating = true;
+
+ const estimate = await storageEstimate();
+ const valid = (estimate !== null);
+
+ if (valid) {
+ document.querySelector("#storage-usage").textContent = storageBytesToLabeledString(estimate.usage);
+ document.querySelector("#storage-quota").textContent = storageBytesToLabeledString(estimate.quota);
+ }
+
+ storageUpdateStats.isUpdating = false;
+ return valid;
+}
+storageUpdateStats.isUpdating = false;
+
+async function storageShowInfo() {
+ storageSpinnerShow(true);
+
+ const valid = await storageUpdateStats();
+ document.querySelector("#storage-use").classList.toggle("storage-hidden", !valid);
+ document.querySelector("#storage-error").classList.toggle("storage-hidden", valid);
+
+ storageSpinnerShow(false);
+}
+
+function storageSpinnerShow(show) {
+ const spinner = $('#storage-spinner');
+ if (show) {
+ spinner.show();
+ } else {
+ spinner.hide();
+ }
+}