94 lines
4.0 KiB
JavaScript
94 lines
4.0 KiB
JavaScript
globalThis.Wegwichtel ??= {};
|
|
(function (ns) {
|
|
'use strict';
|
|
const LOCAL_REFERENCE = 5 * 1024 * 1024;
|
|
let initialized = false;
|
|
let lastError = '';
|
|
let refreshTask = null;
|
|
|
|
function format(bytes) {
|
|
return `${(bytes / 1000000).toLocaleString(ns.I18n.language, { maximumFractionDigits: 1 })} MB`;
|
|
}
|
|
|
|
function localBytes() {
|
|
const storage = globalThis.localStorage;
|
|
if (!storage) return null;
|
|
let bytes = 0;
|
|
for (let index = 0; index < storage.length; index += 1) {
|
|
const key = storage.key(index);
|
|
if (key != null) bytes += 2 * (key.length + (storage.getItem(key) || '').length);
|
|
}
|
|
return bytes;
|
|
}
|
|
|
|
function show(selector, usage, quota, text) {
|
|
for (const panel of document.querySelectorAll('[data-storage-usage]')) {
|
|
const meter = panel.querySelector(`[data-storage-${selector}-meter]`);
|
|
const label = panel.querySelector(`[data-storage-${selector}-text]`);
|
|
if (meter) {
|
|
meter.hidden = !quota;
|
|
if (quota) { meter.max = quota; meter.value = Math.min(usage, quota); }
|
|
}
|
|
if (label) label.textContent = text;
|
|
}
|
|
}
|
|
|
|
function siteDescription(usage, quota, known) {
|
|
if (!known) return ns.I18n.t("storage-usage.der.freie.platz.konnte.nicht.gemessen.werden");
|
|
const warning = usage / quota >= .9 ? ns.I18n.t("storage-usage.fast.voll.entferne.inhalte.die.du.nicht") : '';
|
|
return ns.I18n.t("storage-usage.app.bilder.und.ton.des.verfugbaren.platzes", { value1: Math.round(usage / quota * 100), value2: format(Math.max(0, quota - usage)), value3: warning });
|
|
}
|
|
|
|
function localDescription(local) {
|
|
if (local == null) return ns.I18n.t("storage-usage.texte.und.einstellungen.konnen.hier.gerade.nicht");
|
|
const warning = local >= LOCAL_REFERENCE * .9 ? ns.I18n.t("storage-usage.der.balken.ist.fast.voll.grosse.bilder") : '';
|
|
return ns.I18n.t("storage-usage.texte.und.einstellungen.ungefahr.belegt.der.balken", { value1: format(local), value2: warning });
|
|
}
|
|
|
|
async function refresh() {
|
|
if (refreshTask) return refreshTask;
|
|
refreshTask = (async () => {
|
|
let estimate = null;
|
|
try { estimate = await navigator.storage?.estimate?.(); } catch { /* Display unknown rather than a guessed quota. */ }
|
|
const usage = estimate?.usage;
|
|
const quota = estimate?.quota;
|
|
const known = Number.isFinite(usage) && Number.isFinite(quota) && quota > 0;
|
|
show('site', usage, known ? quota : null, siteDescription(usage, quota, known));
|
|
let local = null;
|
|
try { local = localBytes(); } catch { /* Storage can be blocked by browser settings. */ }
|
|
show('local', local, local == null ? null : LOCAL_REFERENCE, localDescription(local));
|
|
for (const panel of document.querySelectorAll('[data-storage-usage]')) {
|
|
const warning = panel.querySelector('[data-storage-warning]');
|
|
if (warning) { warning.hidden = !lastError; warning.textContent = lastError; }
|
|
}
|
|
})().finally(() => { refreshTask = null; });
|
|
return refreshTask;
|
|
}
|
|
|
|
function reportError(error) {
|
|
let current = error;
|
|
while (current) {
|
|
if (current.name === 'QuotaExceededError') {
|
|
lastError = ns.I18n.t("storage-usage.der.platz.ist.voll.entferne.gespeicherte.strecken");
|
|
break;
|
|
}
|
|
current = current.cause;
|
|
}
|
|
void refresh();
|
|
}
|
|
|
|
function initialize() {
|
|
if (initialized) return;
|
|
initialized = true;
|
|
document.addEventListener('wegwichtel:local-routes-changed', () => { lastError = ''; void refresh(); });
|
|
document.addEventListener('wegwichtel:storage-error', event => reportError(event.detail));
|
|
document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') void refresh(); });
|
|
globalThis.addEventListener?.('storage', () => { void refresh(); });
|
|
globalThis.addEventListener?.('focus', () => { void refresh(); });
|
|
for (const button of document.querySelectorAll('[data-storage-refresh]')) button.addEventListener('click', () => { void refresh(); });
|
|
void refresh();
|
|
}
|
|
|
|
ns.StorageUsage = Object.freeze({ initialize, refresh, reportError });
|
|
}(globalThis.Wegwichtel));
|