From b3fbaf44bde29de255ab893ea9263956567c8b83 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Mon, 17 Aug 2026 10:53:02 +0100 Subject: [PATCH] docs(android): the plan catches up with the HTML interface Section 3 bis asked whether Delphi controls were needed at all and said to decide before investing further in the interface. It is decided, so it now records the answer and the two traps buried in the bridge - the iframe, and the page having to stay ASCII - rather than leaving them to be re-discovered. Section 1 ter described Skia as the fix for Arabic; it is gone, and what survives of that episode is the packaging constraint, which still governs the build. The table in section 0 claimed template, icons, attachments, timestamps and folders were unread. They are read now; it says which parts, and what is genuinely still missing. Co-Authored-By: Claude Opus 5 --- android-client/PLAN.md | 121 +++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 48 deletions(-) diff --git a/android-client/PLAN.md b/android-client/PLAN.md index 9c8ca3a..fcb96ef 100644 --- a/android-client/PLAN.md +++ b/android-client/PLAN.md @@ -1,6 +1,6 @@ # Client Android — ce qu'il reste à faire -État au 2026-08-15. Le client lit l'instantané et l'affiche ; il n'écrit rien. +État au 2026-08-17. Le client lit l'instantané et l'affiche ; il n'écrit rien. Ce document liste le reste, dans l'ordre où je le ferais. Voir [README.md](README.md) pour l'architecture et les décisions déjà prises. @@ -18,18 +18,21 @@ manques côté téléphone ne demandent **aucun** changement côté serveur. | `folder`, `tags`, `kind` | oui | oui | | `totp_secret` | oui | oui | | `custom_fields` (`label`/`value`/`is_secret`) | oui | oui | -| `template` (carte, clé SSH, serveur…) | oui | **non** | -| `icon_b64`, `icon_custom` | oui | **non** | -| `attachments` (avec `content_b64`) | oui | **non** | -| `created_at`, `updated_at` | oui | **non** | -| `folders` (liste, couleur, icône) | oui | **non** | +| `template` (carte, clé SSH, serveur…) | oui | oui — ligne *Type* | +| `icon_b64` | oui | oui — pastille de la liste | +| `icon_custom` | oui | non — la provenance ne change rien à l'affichage | +| `attachments` — nom, type, taille | oui | oui — nommées, pas ouvrables | +| `attachments` — `content_b64` | oui | **non** — c'est l'enregistrement qui manque | +| `updated_at` | oui | oui | +| `created_at` | oui | **non** | +| `folders` (liste, couleur, icône) | oui | oui — le nom seulement | | `avatar_b64`, `username` (compte) | oui | **non** | -| `tombstones` | oui | **non** | +| `tombstones` | oui | **non** — n'aura de sens qu'avec l'écriture | | `favorite`, `pinned` | **non** — device-local par conception | — | | corbeille | **non** — voyage dans les sauvegardes, pas la sync | — | -Autrement dit : dossiers, icônes, pièces jointes et horodatages sont déjà là, -il ne manque que la lecture. Seules les favoris/épinglés et la corbeille +Ce qui manque encore ne demande donc **rien** au poste Windows : c'est de la +lecture côté téléphone. Seules les favoris/épinglés et la corbeille demanderaient une décision côté Windows — et pour les deux, la décision actuelle est délibérée. @@ -145,22 +148,27 @@ confort, ce qui est le mauvais sens pour un gestionnaire de mots de passe. -## 1 ter. Écritures complexes — Skia (2026-08-15) +## 1 ter. ~~Écritures complexes — Skia~~ — DEVENU INUTILE le 2026-08-17 -Un nom de pièce jointe en arabe s'affichait en désordre. Ce n'était pas un -réglage manqué : le moteur de texte d'origine de FMX ne met pas en forme les -écritures complexes — pas de réordonnancement bidirectionnel, pas de liaison -des lettres. Séparer la taille du nom limitait les dégâts sans les supprimer. +Un nom de pièce jointe en arabe s'affichait en désordre : le moteur de texte +d'origine de FMX ne met pas en forme les écritures complexes — pas de +réordonnancement bidirectionnel, pas de liaison des lettres. `GlobalUseSkia` +réglait cela, au prix de `libsk4d.so` (25 Mo) et d'un **APK passé de 13 à 22 Mo**. -`GlobalUseSkia := True` avant `Application.Initialize` remplace le moteur de -rendu ; Skia embarque HarfBuzz et fait ce travail. Le prix est `libsk4d.so`, -25 Mo (8,9 Mo compressés), et un **APK qui passe de 13 à 22 Mo**. +**Retiré**, avec le style vendu, quand l'interface est passée au moteur du +système (§3 bis) : Skia ne servait qu'aux libellés FMX, et il n'en reste aucun. +Le moteur fait sa propre mise en forme — vérifié sur l'appareil, le même nom +arabe se lit correctement. L'APK **retombe à 12,7 Mo**. -Conséquence sur la fabrication : `Deploy` reconstruit `library\lib` avant -`aapt`, donc la bibliothèque posée à la main disparaît. D'où +Ce qui reste vrai de cet épisode, et qui gouverne encore la fabrication : +`Deploy` reconstruit `library\lib` avant `aapt`, donc tout ce qu'on y pose à la +main disparaît — aujourd'hui nos icônes, hier Skia. D'où [repack-apk.ps1](repack-apk.ps1), qui refait *aapt → zipalign → signature* sur le dossier déjà prêt. Une entrée `DeployFile` en bonne et due forme a été tentée d'abord : MSBuild l'ignore, comme il ignore toutes les autres ici. +[build-apk.ps1](build-apk.ps1) enchaîne les quatre étapes, y compris la +régénération de `web.res` — l'oublier embarque la page d'avant l'édition, et le +symptôme se lit alors comme un bug applicatif. ## 2. Durcissement — petit, à faire avant tout usage réel @@ -222,49 +230,66 @@ Rangé par ce que ça apporte réellement sur un téléphone. À surveiller : quelques PDF suffiraient à peser plusieurs Mo, retéléchargés entièrement à chaque instantané nouveau. -2. ~~**Filtre dossier**~~ — **fait**, liste déroulante à côté de la recherche, - alimentée par le tableau `folders`, et le choix survit à un rafraîchissement - de fond. **Pas de filtre d'étiquette** : la recherche texte couvre déjà les +2. ~~**Filtre dossier**~~ — **fait**, une rangée de pastilles avec leur compte, + alimentée par le tableau `folders`. Le filtrage se fait dans la page, donc + sans aller-retour, et le choix survit à un rafraîchissement de fond. **Pas de filtre d'étiquette** : la recherche texte couvre déjà les étiquettes, en taper le nom suffit. -3. ~~**Icônes**~~ (`icon_b64`) — **fait**, décodées une fois par coffre et non à - chaque frappe (la liste est reconstruite à chaque caractère). Une icône SVG - n'est pas chargeable par FMX : l'entrée retombe sur ses initiales. +3. ~~**Icônes**~~ (`icon_b64`) — **fait**. Elles descendent telles quelles dans + la page, en URI `data:` : le moteur décode, y compris le SVG, que FMX ne + savait pas charger. Sans icône, l'entrée retombe sur son initiale. 4. ~~**`template`**~~ — **fait**, affiché comme *Type* dans le détail. Adapter en plus les intitulés d'une carte bancaire reste à voir. 5. ~~**Tri par nom**~~ — **fait** dans `TVault.Search`. L'ordre de l'instantané est celui de la base, donc arbitraire à l'œil. -6. **`TListView` à la place de `TListBox`** le jour où la reconstruction à - chaque frappe se voit. Marqué `ponytail:` dans le code, pas avant. +6. **Liste virtuelle** le jour où la reconstruction à chaque frappe se voit. Le + `innerHTML` complet est refait à chaque caractère ; sur quelques centaines + d'entrées c'est imperceptible. Marqué `ponytail:` dans la page, pas avant. --- -## 3 bis. Deux questions ouvertes sur l'interface +## 3 bis. ~~Faudrait-il des composants Delphi du tout ?~~ — TRANCHÉ le 2026-08-17 -**Le thème n'est pas encore celui de la recherche globale.** Le bleu et la -pilule ont été repris, pas le reste : espacements, élévation, densité. À -reprendre capture en main plutôt qu'au jugé. +**Non. Il n'en reste aucun.** Les trois écrans sont une page HTML rendue par le +moteur du système ([web/app.html](web/app.html), servie par +[PMA.WebUI.pas](PMA.WebUI.pas)). Une sonde a décidé plutôt qu'un débat : la même +liste peinte par le moteur, en quarante lignes de CSS, rendait mieux que ce qui +avait coûté la journée à peindre à la main — et mettait l'arabe en forme seule. -**Et faudrait-il des composants Delphi du tout ?** Le poste Windows n'affiche -pas de contrôles natifs : il sert `js/app.js` et `css/style.css` dans un -WebView2. Le même montage est possible ici — `TWebBrowser` encapsule le WebView -d'Android — et il réglerait d'un coup ce qui a coûté le plus cher aujourd'hui : -plus de gabarits de style à contourner, plus d'ordre d'empilement à deviner, -une seule feuille de style pour les deux clients. +Ce que la migration a réglé, et qui revenait à chaque écran : un gabarit absent +du style chargé, un ordre d'alignement laissé au hasard, un `HitTest` qui avale +un appui, une vue native qui se peint par-dessus tout. Le dernier à partir a été +l'écran de déverrouillage, pour une raison précise : dans un `TEdit` Android le +curseur ne se place pas où on le touche, donc un jeton long est incorrigible. -Ce que ça demanderait, honnêtement : +**Le pont n'ouvre aucun port.** `evaluateJavascript` descend les données, +une navigation `cmd://` interceptée remonte les actions. Deux pièges y sont +enterrés, à ne pas re-découvrir : -- Un **pont** vers le Keystore, la biométrie et le presse-papiers, comme le - `cmd://` du poste. Ces trois-là resteront en Delphi de toute façon. -- Une **disposition mobile** dans le frontend, qui est écrit pour un écran - large. C'est le vrai coût, et il est dans `js/`, pas ici. -- Trancher où vit le HTML : servi par un serveur local comme sur le poste, ou - chargé depuis les ressources de l'application. +- FMX répond **toujours** au moteur qu'il n'a pas pris la navigation en charge. + Sur un schéma inconnu, le moteur essaie donc de la charger et remplace la page + par son écran d'erreur. D'où l'**iframe jetable**, où l'échec reste confiné. +- Le chargement de la page ne transporte pas l'encodage + (`loadDataWithBaseURL` reçoit `nil`), et `Navigate` refuse une URL `data:`. + **`app.html` doit donc rester en ASCII pur** ; les données, elles, passent par + une chaîne JNI et n'ont pas ce problème. -La crypto, elle, ne changerait pas de camp : `WebCrypto` fait déjà tout ce que -`PMA.Crypto` fait, et c'est le poste qui écrit le format. +**Les secrets ne traversent pas le pont.** La liste reçoit noms, sites et +identifiants — ce qui est déjà à l'écran. Copier depuis une ligne envoie un +**rang**, et Delphi relit le coffre chez lui. Seule l'entrée ouverte a ses +valeurs dans le tas JS, effacées par `PM.wipe` au verrouillage. -À décider avant d'investir davantage dans l'interface actuelle — chaque -correction d'affichage faite aujourd'hui serait perdue. +Reste en Delphi, et y restera : Keystore, biométrie, presse-papiers sensible, +`FLAG_SECURE`, réseau, déchiffrement. + +**Ce que `js/` n'a pas donné.** Le CSS du poste est réutilisable presque tel +quel et c'est lui qui porte l'apparence ; `app.js` non — 12 000 lignes qui +supposent la session, le CSRF et l'API complète. La page du téléphone est +autonome. + +**Le thème n'est pas encore exactement celui de la recherche globale.** Le +dégradé, les blocs translucides et les arrondis sont repris ; espacements, +élévation et densité restent au jugé. C'est maintenant du CSS, donc peu coûteux +à reprendre capture en main. ## 4. Le chemin d'écriture — le gros morceau