perf(todo): ticks, drags and the chosen tasks show at once, written in one go

What a person does to their tasks shows before the device has sealed
and kept it (Flutter's optimistic state): TodoCubit.showing shows a
change on the tasks at once and on every state read while its write
runs; where the write fails, the tasks show as they are again at once
and a snack bar says so (the keys missing, or "That wasn't saved"),
through writeTasks. A task's check, a task dragged to a day, an hour or
a place in its project, Reschedule, and the selection's date, labels,
priority, deadline, move, complete and delete go through it; Undo stays
where it was, offered once the write is kept.

The chosen tasks were written one at a time, each write opening every
task again (SealedRows.all decrypts all of them), so deleting a hundred
opened them a hundred times. TaskRepository now reads once and writes
together: updateAll, completeAll, deleteAll, move, place and restore,
the automatic reminder asked once, and SealedRows.updateAll seals all
of them before writing any (KeysMissing leaves none written) and fires
one change, so the screen reads once after. What a write changes is
worked out by pure functions shared by the repository and the screen
(movedTo, placedAt, completedContent, withSubTasks in task_views.dart).

Whats-New: Ticking, moving and changing tasks, many at once too, shows at once.
Whats-New-De: Abhaken, Verschieben und Ändern von Aufgaben, auch vieler auf einmal, zeigt sich sofort.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-07 22:57:29 +01:00
commit c954e844f7
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
5 changed files with 757 additions and 204 deletions

View file

@ -31,6 +31,7 @@
"deadlineOn": "Frist {day}",
"deadlineNone": "Keine Frist",
"keysMissing": "Dieses Gerät kann nichts speichern: Es hat die Schlüssel deines Kontos nicht. Melde dich mit deinem Passwort oder deiner Wiederherstellungsphrase an, um sie hinzuzufügen.",
"tasksNotSaved": "Das wurde nicht gespeichert, deine Aufgaben sind wie vorher. Versuch es noch mal.",
"filtersLabelsTitle": "Filter & Labels",
"filtersLabelsHint": "Gespeicherte Ansichten deiner Aufgaben",
"filtersTitle": "Meine Filter",

View file

@ -72,6 +72,10 @@
},
"deadlineNone": "No deadline",
"keysMissing": "This device can't save: it doesn't hold your account's keys. Sign in with your password or recovery phrase to add them.",
"tasksNotSaved": "That wasn't saved, so your tasks are as they were. Try again.",
"@tasksNotSaved": {
"description": "A snack bar after a change to tasks, shown at once, could not be kept on the device and was taken back."
},
"filtersLabelsTitle": "Filters & labels",
"filtersLabelsHint": "Views of your tasks, kept",
"filtersTitle": "My filters",

View file

@ -286,6 +286,12 @@ abstract class AppLocalizations {
/// **'This device can\'t save: it doesn\'t hold your account\'s keys. Sign in with your password or recovery phrase to add them.'**
String get keysMissing;
/// A snack bar after a change to tasks, shown at once, could not be kept on the device and was taken back.
///
/// In en, this message translates to:
/// **'That wasn\'t saved, so your tasks are as they were. Try again.'**
String get tasksNotSaved;
/// No description provided for @filtersLabelsTitle.
///
/// In en, this message translates to:

View file

@ -120,6 +120,10 @@ class AppLocalizationsDe extends AppLocalizations {
String get keysMissing =>
'Dieses Gerät kann nichts speichern: Es hat die Schlüssel deines Kontos nicht. Melde dich mit deinem Passwort oder deiner Wiederherstellungsphrase an, um sie hinzuzufügen.';
@override
String get tasksNotSaved =>
'Das wurde nicht gespeichert, deine Aufgaben sind wie vorher. Versuch es noch mal.';
@override
String get filtersLabelsTitle => 'Filter & Labels';

View file

@ -120,6 +120,10 @@ class AppLocalizationsEn extends AppLocalizations {
String get keysMissing =>
'This device can\'t save: it doesn\'t hold your account\'s keys. Sign in with your password or recovery phrase to add them.';
@override
String get tasksNotSaved =>
'That wasn\'t saved, so your tasks are as they were. Try again.';
@override
String get filtersLabelsTitle => 'Filters & labels';