Put every optimistic action on one helper and fix the ones that failed silently - #6715
Draft
AndyScherzinger wants to merge 5 commits into
Draft
AndyScherzinger wants to merge 5 commits into
AndyScherzinger wants to merge 5 commits into
Conversation
Four call sites had each grown their own copy of "apply locally, retry once on a transient failure, revert when it finally fails, revert when cancelled", with the retry predicate spelled out twice and one of them shipping a guard bug. optimisticAction() now carries that shape, including the case where the server refuses in the payload rather than in the status code, and the case where an answer means the change was already applied - which must not revert anything. No behaviour change; the repository tests of reactions, deletions, edits, pinning and dismissals carry the migration. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Marking a conversation read or unread, favoriting, archiving and the important and sensitive toggles now go through the shared optimistic helper, so every one of them retries a connection problem once and takes its change back when the screen is left mid-request. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
The notification level, the message expiration and the call notification switch logged their failure and left the screen showing a setting the server never accepted. They now go back to the previous value and say so. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
… once Deleting left the row in place until the worker had finished and the list had been fetched again. It now disappears on confirmation, reusing the guard that hides a conversation being left, and comes back if the delete fails. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
6 tasks
The helper was only exercised through the repositories that use it, so the rules every optimistic action depends on - applied before the answer, taken back on a refusal or a cancellation, kept after one hiccup - had no test of their own. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #6694 — review that one first, this branch targets
feat/noid/optimisticReactionsand will be retargeted to master once it merges.#6694 shipped five optimistic chat actions, each with its own hand-rolled apply/retry/revert block. This branch pulls that shape into one helper, puts the conversation list and conversation info actions on it, and fixes the two places where an action told the user it had worked when it had not.
refactor(chat): extract the optimistic action pattern into one helper—optimisticAction(apply, isConfirmed, request)inutils/OptimisticAction.kt.applywrites the local state and returns its own undo action, or null when nothing changed, in which case nothing is undone later either. A transient failure is retried once, any failure or a cancellation takes the change back, and the undo runs underNonCancellableso a revert cannot itself be cancelled half-way. MigratingOfflineFirstChatRepositoryandReactionsRepositoryImplonto it removes 112 lines with no behaviour change.perf(conversations): keep list and info actions correct when they fail— mark as read, mark as unread, favorite, archive and the important and sensitive toggles now go through the same helper. The two toggles gain a retry they never had; all six gain cancellation safety, so leaving the screen mid-request no longer leaves the change applied although the server may never have heard of it.fix(conversation info): tell the user when a setting did not save—DatabaseStorageModule.saveStringandsaveBooleancaught every failure and only logged it, so the notification level, the message expiration and the call notification switch kept showing a setting the server had refused, with no error anywhere. The failure now reaches the view model, which puts the previous value back and shows the error snackbar.perf(conversation list): drop a deleted conversation from the list at once— the row stayed in the list until the worker had finished and the list had been fetched again. It now disappears on confirmation and comes back if the delete fails, reusing the guard that hides a conversation being left.test(utils): cover the optimistic action contract directly—optimisticActionwas only exercised through the repositories using it. Seven tests now assert the rules every optimistic action depends on: applied before the answer, taken back on a refusal, taken back on a refusal the server reports in the payload, taken back when the screen is left mid-request, nothing taken back when nothing was applied, and one hiccup retried without losing the change.🖼️ Screenshots
No UI was added or changed — the same controls, the same snackbars, applied earlier.
🏁 Checklist
🤖 AI (if applicable)