From 85691bb2f1e79ad26d5f9822510c866315cac888 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Fri, 28 Aug 2026 21:47:53 +0100 Subject: [PATCH] feat(android): un bouton pour jeter le coffre local, en debogage seulement Il vit en bas des reglages, apres tout le reste, et demande deux appuis : un effacement sans retour ne se declenche pas sur un doigt qui glisse. Absent en release, et pas seulement cache : la commande du pont n'est pas compilee et Delphi ne devoile la section que dans une version de debogage. Le bouton ne peut donc pas reapparaitre par accident. Verifie - Release compte 8060 lignes contre 8072 en debug, soit exactement ce bloc. DropLocalVault efface le cache, le conteneur local et le drapeau d'attente, chacun sous son propre try : un fichier absent ou verrouille ne doit pas empecher les deux autres de partir. Les reglages du depot restent - c'est le coffre qu'on jette, pas la facon d'aller le rechercher. Co-Authored-By: Claude Opus 5 --- android-client/PMA.Store.pas | 18 ++++++++++++++++++ android-client/web/app.html | 35 +++++++++++++++++++++++++++++++++++ mainApk.pas | 24 ++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/android-client/PMA.Store.pas b/android-client/PMA.Store.pas index fec9f5c..7536ce1 100644 --- a/android-client/PMA.Store.pas +++ b/android-client/PMA.Store.pas @@ -157,6 +157,14 @@ procedure ClearVault; function HasLocalContainer: Boolean; function LoadLocalContainer: string; procedure SaveLocalContainer(const AContainer: string); +/// Efface TOUT ce que l'appareil detient du coffre : le cache, le conteneur +/// local et le drapeau d'attente. Ne touche pas aux reglages du depot - c'est +/// le coffre qu'on jette, pas la facon d'aller le rechercher. +/// +/// SANS RETOUR, et sans garde ici : l'appelant est le seul a savoir si +/// quelqu'un l'a demande. Reserve au debogage. +procedure DropLocalVault; + /// Efface le conteneur local. A n'appeler QU'APRES avoir publie son contenu : /// c'est le geste qui fait passer l'autorite au depot, et il est sans retour. procedure DropLocalContainer; @@ -290,6 +298,16 @@ begin TFile.Delete(LocalContainerPath); end; +procedure DropLocalVault; +begin + // Chacun sous son propre try : un fichier absent ou verrouille ne doit pas + // empecher les deux autres de partir - un effacement a moitie fait laisse + // l'appareil dans un etat que personne n'a voulu. + try if TFile.Exists(VaultPath) then TFile.Delete(VaultPath); except end; + try DropLocalContainer; except end; + try SetPendingFlag(False); except end; +end; + function PendingPath: string; begin Result := TPath.Combine(TPath.GetHomePath, PENDING_FILE); diff --git a/android-client/web/app.html b/android-client/web/app.html index 9e1217b..f3384b0 100644 --- a/android-client/web/app.html +++ b/android-client/web/app.html @@ -605,6 +605,19 @@ atteignable depuis l'accueil comme depuis le coffre. -->
+ + + @@ -1606,6 +1619,24 @@ document.getElementById('sPinSet').addEventListener('click', function () { send('pinset?c=' + encodeURIComponent(v)); document.getElementById('sPinNew').value = ''; }); +document.getElementById('sWipe').addEventListener('click', function (ev) { + // DEUX APPUIS, comme pour retirer le code : un effacement sans retour ne se + // declenche pas sur un doigt qui glisse. + var b = ev.currentTarget; + if (b.getAttribute('data-armed') === null) { + b.setAttribute('data-armed', '1'); + b.textContent = 'Really delete - tap again'; + setTimeout(function () { + b.removeAttribute('data-armed'); + b.textContent = 'Delete the local vault'; + }, 4000); + return; + } + b.removeAttribute('data-armed'); + b.textContent = 'Delete the local vault'; + send('wipelocal'); + closeSettings(); +}); document.getElementById('sPinClear').addEventListener('click', function (ev) { var b = ev.currentTarget; if (b.getAttribute('data-armed') === null) { @@ -1828,6 +1859,10 @@ var PM = { document.body.classList.add('on-history'); send('state?view=history'); }, + /// Version de debogage : Delphi le dit, la page l'affiche. Jamais l'inverse. + showDebug: function () { + document.getElementById('secDebug').hidden = false; + }, setVersion: function (v) { document.getElementById('sVersion').textContent = v; }, diff --git a/mainApk.pas b/mainApk.pas index a433d55..f581344 100644 --- a/mainApk.pas +++ b/mainApk.pas @@ -446,6 +446,12 @@ begin FPending := HasPendingFlag; PushConfig; WebCall('PM.setVersion("Coffre 1.0.0")'); +{$IFDEF DEBUG} + // L'effacement du coffre local n'existe QUE dans les versions de debogage. + // La page ne montre le bouton que si Delphi le lui dit, et Delphi ne le dit + // qu'ici : une version publiee n'a donc ni le bouton ni la commande. + WebCall('PM.showDebug()'); +{$ENDIF} ShowUnlock; {$IFNDEF DEBUG} // Le journal quitte l'ecran d'accueil, sans quitter l'application : un appui @@ -1743,6 +1749,22 @@ begin else if LAction = 'icon' then SetEntryIcon(Param('a') = 'fetch') +{$IFDEF DEBUG} + // JETER LE COFFRE LOCAL - debogage seulement, et absent a la compilation + // en release : la commande n'existe pas, pas plus que le bouton. + else if LAction = 'wipelocal' then + begin + LockVault; + DropLocalVault; + FPending := False; + FETag := ''; + FVaultUnreadable := False; + Log('DEBUG: local vault dropped'); + ShowUnlock; + WebCall('PM.toast("Local vault deleted")'); + end +{$ENDIF} + else if LAction = 'pinset' then SetUnlockCode(TNetEncoding.URL.Decode(Param('c'))) @@ -1983,8 +2005,6 @@ begin procedure var LPlain, LOwner: string; - LKey, LSalt: TBytes; - LIters: Integer; LDoc: TJSONObject; begin try