feat(apk): Save des reglages actif seulement s'il y a un changement, coche apres enregistrement

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-09-18 10:59:03 +01:00
parent 3c16b41714
commit af6e8a2d9a
+27 -2
View File
@@ -161,6 +161,7 @@
.btn:active { opacity: .62; } .btn:active { opacity: .62; }
.btn.wide { padding: 13px 18px; font-size: 15px; } .btn.wide { padding: 13px 18px; font-size: 15px; }
.btn.main { background: var(--accent); } .btn.main { background: var(--accent); }
.btn:disabled { opacity: .45; }
/* Rouge sourd : assez pour qu'on ne le confonde pas avec Copy, pas assez /* Rouge sourd : assez pour qu'on ne le confonde pas avec Copy, pas assez
pour attirer l'oeil sur la seule action irreversible de l'ecran. */ pour attirer l'oeil sur la seule action irreversible de l'ecran. */
.btn.danger { background: rgba(220, 80, 80, .30); } .btn.danger { background: rgba(220, 80, 80, .30); }
@@ -590,7 +591,7 @@
<div class="in-x" data-clear="sPwd">&#215;</div> <div class="in-x" data-clear="sPwd">&#215;</div>
</div> </div>
<button class="btn wide" id="sScan">Scan the QR shown on the PC</button> <button class="btn wide" id="sScan">Scan the QR shown on the PC</button>
<button class="btn wide main" id="sSave">Save</button> <button class="btn wide" id="sSave" disabled>Save</button>
<div class="note">The sync password never leaves this device. It is what <div class="note">The sync password never leaves this device. It is what
encrypts the copy kept in the repository, so it must be the same on every encrypts the copy kept in the repository, so it must be the same on every
device that shares it; the token only opens the repository. It is asked device that shares it; the token only opens the repository. It is asked
@@ -785,6 +786,7 @@ document.getElementById('settings').addEventListener('click', function (ev) {
var el = document.getElementById(id); var el = document.getElementById(id);
el.value = ''; el.value = '';
if (el.classList.contains('multi')) autoGrow(el); if (el.classList.contains('multi')) autoGrow(el);
syncSaveBtn(false);
el.focus(); el.focus();
}); });
@@ -1667,6 +1669,8 @@ function openSettings() {
document.getElementById('sPinNew').value = ''; document.getElementById('sPinNew').value = '';
document.getElementById('secCode').hidden = !vaultOpen; document.getElementById('secCode').hidden = !vaultOpen;
document.getElementById('sRepoErr').hidden = true; document.getElementById('sRepoErr').hidden = true;
cfgBase = cfgNow();
syncSaveBtn(false);
// La section n'existe que coffre ouvert : le dire tant qu'elle manque, et se // La section n'existe que coffre ouvert : le dire tant qu'elle manque, et se
// taire quand elle est juste en dessous. // taire quand elle est juste en dessous.
document.getElementById('sUnlockHint').textContent = document.getElementById('sUnlockHint').textContent =
@@ -1680,6 +1684,25 @@ function openSettings() {
// ENREGISTRER EST UN GESTE, FERMER N'ENREGISTRE RIEN. Fermer enregistrait : // ENREGISTRER EST UN GESTE, FERMER N'ENREGISTRE RIEN. Fermer enregistrait :
// une URL effacee par erreur partait avec le retour, sans moyen de revenir. // une URL effacee par erreur partait avec le retour, sans moyen de revenir.
// Desormais retour = annuler, et la page repart des valeurs enregistrees. // Desormais retour = annuler, et la page repart des valeurs enregistrees.
// SAVE NE S'ALLUME QUE SI QUELQUE CHOSE A CHANGE, compare aux valeurs
// enregistrees et non a la derniere frappe : taper un caractere puis l'effacer
// le rend de nouveau inactif. Apres un Save : coche, inactif, nouvelle base.
var cfgBase = '';
function cfgNow() {
return JSON.stringify([document.getElementById('sUrl').value.trim(),
document.getElementById('sTok').value.trim(),
document.getElementById('sPwd').value]);
}
function syncSaveBtn(justSaved) {
var b = document.getElementById('sSave'), dirty = cfgNow() !== cfgBase;
b.disabled = !dirty;
b.classList.toggle('main', dirty);
b.textContent = (!dirty && justSaved) ? String.fromCharCode(0x2713) + ' Saved' : 'Save';
}
['sUrl', 'sTok', 'sPwd'].forEach(function (id) {
document.getElementById(id).addEventListener('input', function () { syncSaveBtn(false); });
});
// L'ADRESSE DU DEPOT TELLE QUE LE NAVIGATEUR L'AFFICHE suffit : // L'ADRESSE DU DEPOT TELLE QUE LE NAVIGATEUR L'AFFICHE suffit :
// https://git.example.com/OWNER/REPO (ou .../src/branch/main/FICHIER) devient // https://git.example.com/OWNER/REPO (ou .../src/branch/main/FICHIER) devient
// l'URL de l'API des contenus. Une URL d'API ou d'endpoint PHP passe telle quelle, // l'URL de l'API des contenus. Une URL d'API ou d'endpoint PHP passe telle quelle,
@@ -1728,7 +1751,8 @@ document.getElementById('sSave').addEventListener('click', function () {
elPwd.value = document.getElementById('sPwd').value; elPwd.value = document.getElementById('sPwd').value;
pushConfig(); pushConfig();
document.getElementById('sRepoErr').hidden = true; document.getElementById('sRepoErr').hidden = true;
toast('Saved'); cfgBase = cfgNow();
syncSaveBtn(true);
}); });
function closeSettings() { function closeSettings() {
@@ -1917,6 +1941,7 @@ var PM = {
u.value = shortRepoUrl(url); u.value = shortRepoUrl(url);
autoGrow(u); autoGrow(u);
document.getElementById('sTok').value = tok; document.getElementById('sTok').value = tok;
syncSaveBtn(false);
toast('URL and token pasted - type the sync password, then Save'); toast('URL and token pasted - type the sync password, then Save');
document.getElementById('sPwd').focus(); document.getElementById('sPwd').focus();
}, },