feat(todo): the person's projects, sealed and synced, the Inbox made once (ADR 0033, D5, D6)
TodoPerson opens the person's own sync database in their folder, halkyon_app's SyncService behind AppCompatibility, their key (TodoKeys, Train's copied with Todo's own key IDs) and their projects, and closes them in that order, the key last. A project is sealed for its row; a readable, foreign or moved row shows locked, and a device without the account's keys reads and writes nothing. The Inbox is the row under an ID keyed by the account, so every device makes the same one and the instance can't tell which it is; it can't be deleted. Settings shows Sync's card first and the cog its dot while sync fails, as Learn's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
3876e30681
commit
60a8f5b617
1 changed files with 1285 additions and 36 deletions
|
|
@ -3,9 +3,14 @@ import 'package:halkyon_app/halkyon_app.dart';
|
|||
import 'package:halkyon_app/testing.dart';
|
||||
import 'package:halkyon_todo_flutter/src/app/todo_app.dart';
|
||||
import 'package:halkyon_todo_flutter/src/app/todo_dependencies.dart';
|
||||
import 'package:halkyon_todo_flutter/src/core/privacy/todo_keys.dart';
|
||||
import 'package:halkyon_todo_flutter/src/feature/project/data/project_repository.dart';
|
||||
import 'package:halkyon_ui/halkyon_ui.dart';
|
||||
import 'package:material_ui/material_ui.dart';
|
||||
|
||||
import '../support/memory_content_key_gateway.dart';
|
||||
import '../support/memory_project_gateway.dart';
|
||||
|
||||
void main() {
|
||||
final builtIn = Instance.parse('todo.example.org')!;
|
||||
late MemoryInstanceStore store;
|
||||
|
|
@ -86,7 +91,26 @@ void main() {
|
|||
'https://code.halkyon.app/project-halkyon/halkyon',
|
||||
openPerson: (person) async {
|
||||
opened.add(person);
|
||||
return TodoPerson(person);
|
||||
final keys = TodoKeys(
|
||||
MemoryContentKeyGateway(),
|
||||
SodiumContentCipher(),
|
||||
() async => null,
|
||||
);
|
||||
final sync = SyncService(
|
||||
({required onMerge}) async {},
|
||||
debounce: const Duration(days: 1),
|
||||
);
|
||||
final projects = ProjectRepository(MemoryProjectGateway(), keys);
|
||||
return TodoPerson(
|
||||
person,
|
||||
sync: sync,
|
||||
projects: projects,
|
||||
onDispose: () async {
|
||||
await projects.dispose();
|
||||
await sync.dispose();
|
||||
keys.dispose();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
@ -212,19 +236,23 @@ void main() {
|
|||
expect(find.widgetWithText(AppBar, 'Browse'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Settings has the account, then About Halkyon Todo last and '
|
||||
'the version small at the very foot', (tester) async {
|
||||
await start(tester, usedBefore: true);
|
||||
await openSettings(tester);
|
||||
testWidgets(
|
||||
'Settings has Sync first, the account, then About Halkyon Todo last and '
|
||||
'the version small at the very foot',
|
||||
(tester) async {
|
||||
await start(tester, usedBefore: true);
|
||||
await openSettings(tester);
|
||||
|
||||
final order = [
|
||||
'Account',
|
||||
'Sign out',
|
||||
'About Halkyon Todo',
|
||||
'Version 0.1.0 (build 1)',
|
||||
].map((text) => tester.getTopLeft(find.text(text)).dy).toList();
|
||||
expect(order, [...order]..sort());
|
||||
});
|
||||
final order = [
|
||||
'Sync',
|
||||
'Account',
|
||||
'Sign out',
|
||||
'About Halkyon Todo',
|
||||
'Version 0.1.0 (build 1)',
|
||||
].map((text) => tester.getTopLeft(find.text(text)).dy).toList();
|
||||
expect(order, [...order]..sort());
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets("from medium windows on, a rail with Todo's icon on top", (
|
||||
tester,
|
||||
|
|
|
|||
Loading…
Reference in a new issue