feat(android): an entry can be deleted from the phone
Both, or nothing: the row leaves the snapshot AND a tombstone takes its place. Removing the row alone does not delete - the desktop still holds its own copy, and the next pull would bring it back as an entry we never had. The time matters too: the desktop's arbitration keeps an entry edited AFTER the deletion rather than killing it a second time. No trash on the phone, deliberately. The desktop's is a `deleted` flag that does not travel in sync, so a deletion stopping there would propagate nowhere. Hence a button at the very bottom, in two taps, that disarms itself after four seconds - a button left armed gets touched by accident much later, and this is the one action with no way back. The confirmation is in the page because the engine cannot offer one: a JavaScript prompt needs a WebChromeClient FMX does not provide. Not exercised on the device: it would have destroyed a real entry.
This commit is contained in:
+33
@@ -242,6 +242,8 @@ type
|
||||
/// Ajoute une entree au coffre. Le mot de passe voyage par le pont,
|
||||
/// comme 'setfield' - meme regle, meme journalisation muette.
|
||||
procedure CreateEntry(const ATitle, ASite, AUser, APwd, AKind: string);
|
||||
/// Supprime l'entree ouverte, pierre tombale comprise. Sans retour.
|
||||
procedure DeleteCurrentEntry;
|
||||
procedure ReopenEntryByUuid(const AUuid: string);
|
||||
procedure OnClipTimer(Sender: TObject);
|
||||
procedure OnDeadline(Sender: TObject);
|
||||
@@ -901,6 +903,34 @@ begin
|
||||
end);
|
||||
end;
|
||||
|
||||
/// SUPPRIMER - la seule action sans retour depuis le telephone.
|
||||
///
|
||||
/// Elle ne met pas a la corbeille : celle du poste ne voyage pas dans la
|
||||
/// synchronisation, donc s'y arreter ne supprimerait nulle part. Elle retire la
|
||||
/// ligne ET pose la pierre tombale, ce qui fait disparaitre l'entree du poste
|
||||
/// au prochain tirage.
|
||||
///
|
||||
/// La page demande confirmation avant d'en arriver ici.
|
||||
procedure TForm8.DeleteCurrentEntry;
|
||||
var
|
||||
LUuid, LTitle: string;
|
||||
begin
|
||||
if FCurrent.Uuid = '' then
|
||||
begin
|
||||
RefuseChange('This entry has no uuid - cannot be deleted');
|
||||
Exit;
|
||||
end;
|
||||
LUuid := FCurrent.Uuid;
|
||||
LTitle := FCurrent.Display;
|
||||
// Pas de rang a rouvrir : l'entree n'existera plus. AdoptVault ramene la
|
||||
// liste, ce qui est exactement ou l'on veut se retrouver.
|
||||
CommitChange('Deleted: ' + LTitle, 'entry deleted from phone', '',
|
||||
function (APlain: string): string
|
||||
begin
|
||||
Result := DeleteEntry(APlain, LUuid);
|
||||
end);
|
||||
end;
|
||||
|
||||
procedure TForm8.CreateEntry(const ATitle, ASite, AUser, APwd, AKind: string);
|
||||
begin
|
||||
// Une entree sans rien pour la reconnaitre serait une ligne muette dans la
|
||||
@@ -1061,6 +1091,9 @@ begin
|
||||
TNetEncoding.URL.Decode(Param('p')),
|
||||
TNetEncoding.URL.Decode(Param('k')))
|
||||
|
||||
else if LAction = 'delentry' then
|
||||
DeleteCurrentEntry
|
||||
|
||||
else if LAction = 'setfield' then
|
||||
SaveEntryField(TNetEncoding.URL.Decode(Param('f')),
|
||||
TNetEncoding.URL.Decode(Param('v')))
|
||||
|
||||
Reference in New Issue
Block a user