feat(android): folder and 2FA secret can be changed, and the buttons wear icons

The folder had no row of its own - it shared "Folder / tags" with the tags,
so neither could be touched. It is now CHOSEN from the known folders rather
than typed: a typo would file the entry under a folder nothing displays,
here or on the desktop, and it would look lost. Tags stay read-only because
they are an array in the snapshot, and writing one as a string would break
its shape for the desktop.

The 2FA secret gets its own masked row. The code has had a panel for a long
time, but it is computed and renewed every thirty seconds; the secret is what
one sets, changes and removes, and nothing allowed that from the phone.

User, Pass, Copy, Show and Edit become drawings. Four words on a list row left
little room for the entry's name and had to be re-read every time. Every icon
carries an aria-label: replacing a word with a drawing must not take the
information away from someone listening to a screen reader.
This commit is contained in:
r-zakarya
2026-08-21 21:51:42 +01:00
parent c25d68b721
commit 0badc5fcfc
4 changed files with 118 additions and 21 deletions
+15 -8
View File
@@ -166,7 +166,6 @@ function BuildRows(const E: TVaultEntry): TArray<TDetailRow>;
var
LRows: TArray<TDetailRow>;
I: Integer;
LMeta: string;
procedure Add(const ACaption, AValue: string; ASecret: Boolean;
const AField: string = '');
@@ -195,6 +194,12 @@ begin
Add('Site', E.Site, False, 'site');
Add('Username', E.Username, False, 'username');
Add('Password', E.Password, True, 'password');
// LE SECRET, pas le code. Le code a sa propre case en haut, calculee et
// renouvelee toutes les trente secondes ; c'est le secret qui se pose, se
// change et se retire, et sans cette ligne il n'y avait aucun moyen de le
// faire depuis le telephone. Masque comme un mot de passe : il vaut le
// second facteur en entier.
Add('2FA secret', E.Totp, True, 'totp_secret');
end;
for I := 0 to High(E.Fields) do
@@ -207,13 +212,15 @@ begin
Add('Attachment - ' + HumanSize(E.Attachments[I].SizeBytes),
E.Attachments[I].FileName, False);
LMeta := E.Folder;
if E.Tags <> '' then
begin
if LMeta <> '' then LMeta := LMeta + ' - ';
LMeta := LMeta + E.Tags;
end;
Add('Folder / tags', LMeta, False);
// DOSSIER ET ETIQUETTES SEPARES, parce qu'ils ne se modifient pas pareil.
// Le dossier est une chaine simple, choisie parmi celles qui existent - la
// page en fait une liste plutot qu'un champ libre, sinon une faute de frappe
// rangerait l'entree dans un dossier que rien n'affiche.
// Les etiquettes, elles, sont un TABLEAU dans l'instantane : les ecrire comme
// une chaine casserait leur forme pour le poste. Lecture seule tant que le
// patch ne sait pas ecrire un tableau.
Add('Folder', E.Folder, False, 'folder');
Add('Tags', E.Tags, False);
Add('Type', E.Template, False);
// Horodatage tel quel : de l'ISO 8601 UTC, lisible, et le reformater
// demanderait de decider d'un fuseau alors qu'il n'y a rien a arbitrer.