diff --git a/android-client/web/app.html b/android-client/web/app.html
index 9bb3d5a..6dd1330 100644
--- a/android-client/web/app.html
+++ b/android-client/web/app.html
@@ -161,6 +161,7 @@
.btn:active { opacity: .62; }
.btn.wide { padding: 13px 18px; font-size: 15px; }
.btn.main { background: var(--accent); }
+ .btn:disabled { opacity: .45; }
/* 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. */
.btn.danger { background: rgba(220, 80, 80, .30); }
@@ -590,7 +591,7 @@
×
-
+
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
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);
el.value = '';
if (el.classList.contains('multi')) autoGrow(el);
+ syncSaveBtn(false);
el.focus();
});
@@ -1667,6 +1669,8 @@ function openSettings() {
document.getElementById('sPinNew').value = '';
document.getElementById('secCode').hidden = !vaultOpen;
document.getElementById('sRepoErr').hidden = true;
+ cfgBase = cfgNow();
+ syncSaveBtn(false);
// La section n'existe que coffre ouvert : le dire tant qu'elle manque, et se
// taire quand elle est juste en dessous.
document.getElementById('sUnlockHint').textContent =
@@ -1680,6 +1684,25 @@ function openSettings() {
// ENREGISTRER EST UN GESTE, FERMER N'ENREGISTRE RIEN. Fermer enregistrait :
// une URL effacee par erreur partait avec le retour, sans moyen de revenir.
// 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 :
// 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,
@@ -1728,7 +1751,8 @@ document.getElementById('sSave').addEventListener('click', function () {
elPwd.value = document.getElementById('sPwd').value;
pushConfig();
document.getElementById('sRepoErr').hidden = true;
- toast('Saved');
+ cfgBase = cfgNow();
+ syncSaveBtn(true);
});
function closeSettings() {
@@ -1917,6 +1941,7 @@ var PM = {
u.value = shortRepoUrl(url);
autoGrow(u);
document.getElementById('sTok').value = tok;
+ syncSaveBtn(false);
toast('URL and token pasted - type the sync password, then Save');
document.getElementById('sPwd').focus();
},