fix(android): the merge lost folders, and the pending dot was on one screen

Two defects found by re-reading before adding more, along with a test plan.

MergeSnapshots merged entries and tombstones but not folders. A folder created
on the phone - offline, or just before another device published - vanished
from the list while the entries kept its name: filed under a folder nothing
displays, unfindable without knowing it. That is exactly what EnsureFolder was
written against, come back through another door.

The pending dot sat on the padlock, which only exists in the list. After
locking one lands on the home screen - precisely where one decides to sync -
and it said nothing there. It is on Sync as well now.

TESTS.md records what the reading checked and what it left alone, with reasons
for the two defects deliberately not fixed, and a scenario that says what each
step must PRODUCE rather than only what to do.
This commit is contained in:
r-zakarya
2026-08-22 15:24:01 +01:00
parent af2a0dfed8
commit 92ceb1e8c9
3 changed files with 164 additions and 3 deletions
+18 -1
View File
@@ -203,7 +203,8 @@ end;
function MergeSnapshots(const ALocalJson, ARemoteJson: string): string;
var
LLocal, LMerged: TJSONObject;
LLocalEntries, LOutEntries, LLocalStones, LOutStones: TJSONArray;
LLocalEntries, LOutEntries, LLocalStones, LOutStones,
LLocalFolders: TJSONArray;
LEntry, LOther: TJSONObject;
I, J: Integer;
LUuid, LMine, LTheirs, LKilled: string;
@@ -223,6 +224,22 @@ begin
LMerged.AddPair('tombstones', LOutStones);
end;
// 0. LES DOSSIERS DU LOCAL REJOIGNENT CEUX DU DISTANT.
//
// Oubli trouve a la relecture : la fusion ne portait qu'entrees et
// pierres tombales. Un dossier cree ici - hors connexion, ou juste avant
// qu'un autre appareil publie - disparaissait donc de `folders`, tandis
// que les entrees gardaient son nom. Elles se retrouvaient rangees dans
// un dossier que rien n'affiche : introuvables sans le savoir.
//
// Additif, jamais destructif : on n'enleve pas un dossier du distant
// parce qu'il manque ici, c'est aussi la regle du poste.
if LLocal.TryGetValue<TJSONArray>('folders', LLocalFolders) then
for I := 0 to LLocalFolders.Count - 1 do
if LLocalFolders.Items[I] is TJSONObject then
EnsureFolder(LMerged,
(LLocalFolders.Items[I] as TJSONObject).GetValue<string>('name', ''));
// 1. Les pierres tombales locales rejoignent celles du distant. Avant les
// entrees : l'etape suivante s'en sert pour arbitrer.
if LLocal.TryGetValue<TJSONArray>('tombstones', LLocalStones) then