/* * Copyright (C) 2019-2020 Alex Yatskov <alex@foosoft.net> * Author: Alex Yatskov <alex@foosoft.net> * * 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/>. */ /*global apiGetEnvironmentInfo*/ function storageBytesToLabeledString(size) { const base = 1000; const labels = [' bytes', 'KB', 'MB', 'GB']; let labelIndex = 0; while (size >= base) { size /= base; ++labelIndex; } const label = labelIndex === 0 ? `${size}` : size.toFixed(1); return `${label}${labels[labelIndex]}`; } async function storageEstimate() { try { return (storageEstimate.mostRecent = await navigator.storage.estimate()); } catch (e) { // NOP } return null; } storageEstimate.mostRecent = null; async function isStoragePeristent() { try { return await navigator.storage.persisted(); } catch (e) { // NOP } return false; } async function storageInfoInitialize() { storagePersistInitialize(); const {browser, platform} = await apiGetEnvironmentInfo(); document.documentElement.dataset.browser = browser; document.documentElement.dataset.operatingSystem = platform.os; await storageShowInfo(); document.querySelector('#storage-refresh').addEventListener('click', () => storageShowInfo(), false); } async function storageUpdateStats() { storageUpdateStats.isUpdating = true; const estimate = await storageEstimate(); const valid = (estimate !== null); if (valid) { // Firefox reports usage as 0 when persistent storage is enabled. const finite = (estimate.usage > 0 || !(await isStoragePeristent())); if (finite) { document.querySelector('#storage-usage').textContent = storageBytesToLabeledString(estimate.usage); document.querySelector('#storage-quota').textContent = storageBytesToLabeledString(estimate.quota); } document.querySelector('#storage-use-finite').classList.toggle('storage-hidden', !finite); document.querySelector('#storage-use-infinite').classList.toggle('storage-hidden', finite); } 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(); } } async function storagePersistInitialize() { if (!(navigator.storage && navigator.storage.persist)) { // Not supported return; } const info = document.querySelector('#storage-persist-info'); const button = document.querySelector('#storage-persist-button'); const checkbox = document.querySelector('#storage-persist-button-checkbox'); info.classList.remove('storage-hidden'); button.classList.remove('storage-hidden'); let persisted = await isStoragePeristent(); checkbox.checked = persisted; button.addEventListener('click', async () => { if (persisted) { return; } let result = false; try { result = await navigator.storage.persist(); } catch (e) { // NOP } if (result) { persisted = true; checkbox.checked = true; storageShowInfo(); } else { $('.storage-persist-fail-warning').removeClass('storage-hidden'); } }, false); }