[mv3] Add page-wide spinner when restoring/resetting settings

This commit is contained in:
Raymond Hill 2025-12-27 10:12:34 -05:00
parent 2bb3f8c974
commit f7f96140d9
No known key found for this signature in database
GPG key ID: F5630CAE62A14316
4 changed files with 59 additions and 30 deletions

View file

@ -61,11 +61,12 @@ body [data-pane-related] {
padding: 0 var(--default-gap-xxsmall);
}
body[data-pane="settings"] > section[data-pane="settings"],
body[data-pane="rulesets"] > section[data-pane="rulesets"],
body[data-pane="filters"] > section[data-pane="filters"],
body[data-pane="develop"] > section[data-pane="develop"],
body[data-pane="about"] > section[data-pane="about"] {
body[data-pane="settings"]:not(.busy) > section[data-pane="settings"],
body[data-pane="rulesets"]:not(.busy) > section[data-pane="rulesets"],
body[data-pane="filters"]:not(.busy) > section[data-pane="filters"],
body[data-pane="develop"]:not(.busy) > section[data-pane="develop"],
body[data-pane="about"]:not(.busy) > section[data-pane="about"],
body.busy[data-pane] > section[data-pane="busy"] {
display: block;
}

View file

@ -347,3 +347,15 @@ section[data-pane="filters"] aside p {
justify-content: flex-start;
}
}
body.busy section[data-pane="busy"] > div {
justify-content: center;
display: flex;
align-items: stretch;
}
body.busy section[data-pane="busy"] .fa-icon {
animation: spin 1s steps(8) infinite;
fill: var(--surface-3);
font-size: 4em;
margin: 2em;
}

View file

@ -173,6 +173,12 @@
</div>
</section>
<!-- -------- -->
<section data-pane="busy">
<div>
<span class="fa-icon">spinner</span>
</div>
</section>
<!-- -------- -->
<template id="listEntryLeaf">
<div class="listEntry" data-role="leaf">
<span class="detailbar">

View file

@ -145,39 +145,49 @@ async function backupSettings() {
}
async function restoreSettings() {
const input = qs$('section[data-pane="settings"] input[type="file"]');
input.onchange = ev => {
input.onchange = null;
const file = ev.target.files[0];
if ( file === undefined || file.name === '' ) { return; }
const fr = new FileReader();
fr.onload = ( ) => {
fr.onload = null;
if ( typeof fr.result !== 'string' ) { return; }
let data;
try {
data = JSON.parse(fr.result);
} catch {
}
if ( data instanceof Object === false ) { return; }
import('./backup-restore.js').then(api => {
api.restoreFromObject(data);
});
const promise = new Promise(resolve => {
const input = qs$('section[data-pane="settings"] input[type="file"]');
input.onchange = ev => {
dom.cl.add(dom.body, 'busy');
input.onchange = null;
const file = ev.target.files[0];
if ( file === undefined || file.name === '' ) { return resolve(); }
const fr = new FileReader();
fr.onload = ( ) => {
fr.onload = null;
if ( typeof fr.result !== 'string' ) { return resolve(); }
let data;
try {
data = JSON.parse(fr.result);
} catch {
}
if ( data instanceof Object === false ) { return resolve(); }
import('./backup-restore.js').then(api => {
resolve(api.restoreFromObject(data));
});
};
fr.readAsText(file);
};
fr.readAsText(file);
};
// Reset to empty string, this will ensure a change event is properly
// triggered if the user pick a file, even if it's the same as the last
// one picked.
input.value = '';
input.click();
input.oncancel = ( ) => {
resolve();
};
// Reset to empty string, this will ensure a change event is properly
// triggered if the user pick a file, even if it's the same as the last
// one picked.
input.value = '';
input.click();
});
await promise;
dom.cl.remove(dom.body, 'busy');
}
async function resetSettings() {
const response = self.confirm(i18n.getMessage('resetToDefaultConfirm'));
if ( response !== true ) { return; }
dom.cl.add(dom.body, 'busy');
const api = await import('./backup-restore.js');
await api.restoreFromObject({});
dom.cl.remove(dom.body, 'busy');
}
/******************************************************************************/