fix: stop asking about waiting changes after a group edit reached the server #34

A contact stays marked as changed until the group cards on the server
show its membership edits. The engine uploaded those edits as patches
of the group cards after the contacts, but never looked at the contact
again in that run, so it stayed marked until the next sync. Turning
contacts sync off or signing out right after adding a contact to a
group therefore asked whether to drop one waiting change, although
nothing was waiting.

Once the membership patches are accepted, the contacts that have
nothing else to upload are now cleared in the same run, behind the
same version check as any other clean write.
This commit is contained in:
Linus Rath
2026-09-27 07:53:35 +02:00
parent 58b74527b2
commit d088dd14e9
2 changed files with 57 additions and 1 deletions
+25 -1
View File
@@ -710,7 +710,31 @@ export class ContactsSync extends ItemSync {
}
pending.actions.push(action as Pending['actions'][number]);
}
if (byGroup.size) await this.send(acct, [...byGroup.values()]);
if (!byGroup.size) return;
await this.send(acct, [...byGroup.values()]);
await this.cleanAfterMemberships(acct, rows);
}
/**
* A contact stays dirty until the group cards show its membership edits.
* Those that now have nothing else to upload are cleaned right away, so
* nothing looks like it still waits (turning sync off would ask about it).
*/
private async cleanAfterMemberships(acct: string, rowIds: number[]): Promise<void> {
await this.refreshGroups();
const works: Work[] = [];
for (const contact of await this.contactKind.loadByRowIds(rowIds)) {
if (!contact.dirty || contact.deleted || this.isStale(acct, contact.sourceId)) continue;
let plan;
try {
plan = this.contactKind.planUpload(contact, acct);
} catch (error) {
this.plannerFailed(acct, contact.sourceId ?? `row:${contact.rawContactId}`, 'upload', error);
continue;
}
if (plan.kind === 'clean') works.push({ group: plan.ops });
}
await this.env.writer.write(works);
}
// ── Deselection ──