mirror of
https://github.com/kuhyx/todo-app.git
synced 2026-11-10 18:07:03 +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>
36 lines
1.4 KiB
Dart
36 lines
1.4 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:share_plus/share_plus.dart';
|
|
|
|
/// Writes the Markdown export somewhere the user can get at it, and returns a
|
|
/// human-readable description of where it went.
|
|
///
|
|
/// On mobile this opens the system share sheet; on a `dart:io` desktop host it
|
|
/// writes the canonical `~/todo/BACKLOG.md`.
|
|
Future<String> exportBacklog(String markdown, int noteCount) async {
|
|
// coverage:ignore-start
|
|
// Mobile-only share path: Platform.isAndroid/isIOS are always false on the
|
|
// Linux test host, so these lines are structurally unreachable in CI and
|
|
// excluded from the coverage denominator. Verified on-device.
|
|
if (Platform.isAndroid || Platform.isIOS) {
|
|
final dir = await getTemporaryDirectory();
|
|
final file = File('${dir.path}/todo-backlog.md');
|
|
await file.writeAsString(markdown);
|
|
await SharePlus.instance.share(
|
|
ShareParams(
|
|
files: [XFile(file.path, mimeType: 'text/markdown')],
|
|
subject: 'todo backlog ($noteCount notes)',
|
|
),
|
|
);
|
|
return 'Shared $noteCount notes';
|
|
}
|
|
// coverage:ignore-end
|
|
final home = Platform.environment['HOME'] ?? Directory.current.path;
|
|
final dir = Directory('$home/todo');
|
|
if (!dir.existsSync()) dir.createSync(recursive: true);
|
|
final file = File('${dir.path}/BACKLOG.md');
|
|
await file.writeAsString(markdown);
|
|
return 'Exported $noteCount notes to ${file.path}';
|
|
}
|