feat: vault-aligned server v1 + UX polish
All checks were successful
CI / Windows build (push) Successful in 7m47s

Redesign the optional FastAPI companion around vault files (manifest /
PUT/GET/DELETE + OCR jobs) instead of legacy strokes_json notes. Wire a
client Server settings panel for health/login. Polish shell UX: l10n for
settings/home/board, sticky-board empty state, and a narrow-screen
diagnostics FAB.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-05 19:04:48 +08:00
parent d346cc2670
commit 198da00ecd
20 changed files with 1325 additions and 90 deletions

View File

@@ -20,15 +20,16 @@ import '../editor/canvas/pen_slide_screen.dart';
import 'search_screen.dart';
import 'settings_screen.dart';
// [M1] Relative date helper — no new package dependencies.
String _formatDate(DateTime d) {
// Relative date helper — localized.
String _formatDate(BuildContext context, DateTime d) {
final l = AppLocalizations.of(context);
final now = DateTime.now();
final diff = now.difference(d);
if (diff.inSeconds < 60) return 'Just now';
if (diff.inMinutes < 60) return '${diff.inMinutes}m ago';
if (diff.inHours < 24) return '${diff.inHours}h ago';
if (diff.inSeconds < 60) return l.relativeJustNow;
if (diff.inMinutes < 60) return l.relativeMinutesAgo(diff.inMinutes);
if (diff.inHours < 24) return l.relativeHoursAgo(diff.inHours);
if (diff.inDays == 1 || (diff.inDays == 0 && now.day != d.day)) {
return 'Yesterday';
return l.relativeYesterday;
}
return '${d.month}/${d.day}/${d.year} ${d.hour}:${d.minute.toString().padLeft(2, '0')}';
}
@@ -411,7 +412,7 @@ class _NoteTileState extends ConsumerState<_NoteTile> {
Widget build(BuildContext context) {
final note = widget.note;
// [M1] Use relative date helper
final dateStr = _formatDate(note.updatedAt);
final dateStr = _formatDate(context, note.updatedAt);
final ocrStatusMap = ref.watch(ocrStatusProvider);
final ocrStatus = ocrStatusMap[note.id] ?? OcrStatus.none;
@@ -584,7 +585,7 @@ class _DocumentTileState extends ConsumerState<_DocumentTile> {
Widget build(BuildContext context) {
final document = widget.document;
// [M1] Use relative date helper
final dateStr = _formatDate(document.updatedAt);
final dateStr = _formatDate(context, document.updatedAt);
final isPdf = document.docType == 'pdf';
final subtleColor = Theme.of(context).colorScheme.onSurfaceVariant;