mirror of
https://github.com/kuhyx/todo-app.git
synced 2026-11-10 19:07:02 +01:00
First step of moving the desktop app off Flutter's Linux embedder, which tops
out at ~20fps at 4K (see docs/desktop-performance-findings.md). Android is
unaffected and keeps every existing code path.
The blocker was that `dart:io` was imported by note_repository, capture_screen
and settings_screen. On web it compiles to a stub and then throws at runtime --
the first web build rendered a blank white window. So each `dart:io` use now
sits behind a conditional export, with the shared logic hoisted into pure Dart:
- note_repository loses `dart:io`/sqlite entirely. Platform wiring moves to
repository_factory{,_io,_web}, and the legacy sqlite import moves to its own
io-only library. The HLC-from-updated_at seeding is preserved verbatim, so
independently-migrating devices still resolve pre-cutover edits by real edit
time.
- Notes persist to IndexedDB on web, not localStorage: the log is the primary
copy of the backlog and localStorage caps at ~5-10MB and is evicted eagerly.
- BACKLOG.md and the explicit Export keep working through a local wrapper
(added next). A browser cannot write `~/todo/BACKLOG.md`, and the user's
tooling plus the todo MCP server read that path, so leaving it to rot was not
an option. Writes are best-effort so the app still works with no wrapper.
- Notes are also mirrored to the wrapper's on-disk copy, so a wiped Chrome
profile is not a total-loss event for notes that have not reached GitHub yet.
`openRepository` is split so `openRepositoryIn` keeps the migration tests; the
suite stays at 174 green and 100% coverage.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.4 KiB
Dart
44 lines
1.4 KiB
Dart
// coverage:ignore-file
|
|
// App bootstrap: opens the platform's note store and calls runApp. Exercised
|
|
// end-to-end by running the app, not unit tests.
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:todo/data/note_repository.dart';
|
|
import 'package:todo/data/repository_factory.dart';
|
|
import 'package:todo/frame_stats.dart';
|
|
import 'package:todo/ui/capture_screen.dart';
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
installFrameStats();
|
|
|
|
// Where the log lives, and whether a legacy sqlite DB needs importing, is
|
|
// platform-specific and resolved by a conditional import: `dart:io` cannot be
|
|
// imported at all in a web compile, and the desktop app is now a web build.
|
|
final repository = await openRepository();
|
|
|
|
runApp(TodoApp(repository: repository));
|
|
}
|
|
|
|
/// Root widget. Holds the single [NoteRepository] instance and hands it
|
|
/// to the screens that need it.
|
|
class TodoApp extends StatelessWidget {
|
|
/// Creates a [TodoApp] wrapping the given [repository].
|
|
const TodoApp({required this.repository, super.key});
|
|
|
|
/// The single, app-wide note store, injected into every screen.
|
|
final NoteRepository repository;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'todo',
|
|
theme: ThemeData(
|
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
|
useMaterial3: true,
|
|
),
|
|
home: CaptureScreen(repository: repository),
|
|
);
|
|
}
|
|
}
|