todo-app/lib/data/desktop_backup_client.dart
Krzysztof kuhy Rudnicki a0d37c4df8
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file-length / file length <= 250 lines (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
Re-point paths for the ~ reorganisation (home-tidy)
Also bumps Flutter 3.47.3, flutter_secure_storage 11.1.0, idb_shim 2.9.9,
sqflite_common_ffi 2.4.3, very_good_analysis 11 and mcp 2.2.0 so the
freshness gate lets this through; v11 adds async_return_with_no_await, so
the 18 flagged return sites now await explicitly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwtowrowDXx6ccmWVPkCaF
2026-09-11 19:49:03 +02:00

58 lines
2.1 KiB
Dart

import 'package:http/http.dart' as http;
/// Talks to the local desktop wrapper that serves the web build.
///
/// The wrapper exists because a browser cannot write to the filesystem, and two
/// things depend on it:
///
/// * `~/src/todo/BACKLOG.md` — read by the user's tooling and the `todo` MCP
/// server. Without this it would silently go stale after the move to a web
/// build.
/// * an on-disk copy of the note log, so a wiped Chrome profile is not a
/// total-loss event for notes that have not reached GitHub yet.
///
/// Every method is best-effort and swallows failures: the app must remain fully
/// usable when the wrapper is absent, e.g. when the build is opened in a plain
/// browser tab or on mobile.
class DesktopBackupClient {
/// Creates a client targeting [baseUrl] (the wrapper's origin).
DesktopBackupClient({required this.baseUrl, http.Client? httpClient})
: _client = httpClient ?? http.Client();
/// Origin the wrapper listens on, e.g. `http://localhost:8730`.
final String baseUrl;
final http.Client _client;
/// Writes the Markdown backlog export to disk via the wrapper.
Future<void> writeBacklog(String markdown) =>
_post('/backup/backlog', markdown);
/// Writes the serialised note log to disk via the wrapper.
Future<void> writeLog(String json) => _post('/backup/log', json);
/// Reads the wrapper's on-disk copy of the log, or null if unavailable.
Future<String?> readLog() => _get('/backup/log');
/// Reads the on-disk Markdown backlog, or null if unavailable.
Future<String?> readBacklog() => _get('/backup/backlog');
Future<String?> _get(String path) async {
try {
final response = await _client.get(Uri.parse('$baseUrl$path'));
if (response.statusCode != 200 || response.body.isEmpty) return null;
return response.body;
} on Exception {
return null;
}
}
Future<void> _post(String path, String body) async {
try {
await _client.post(Uri.parse('$baseUrl$path'), body: body);
} on Exception {
// Best-effort by design; see the class docs.
}
}
}