# Android Companion App The Android companion app lives in a separate repository at `/home/bvandeusen/Nextcloud/Projects/fabled_app`. ## Stack - Flutter + Dart - Riverpod (state management) - GoRouter (navigation) - Dio (HTTP client) - PersistCookieJar (session persistence) - SSE streaming via `fetch` + `ReadableStream` bridge ## Architecture ``` lib/ app.dart # GoRouter + _Shell + _QuickCaptureBar core/constants.dart # Routes.* data/ models/ # note.dart, task.dart, project.dart api/ # notes_api.dart, tasks_api.dart, projects_api.dart repositories/ # notes, tasks, projects repositories providers/ api_client_provider.dart # all API + repository providers notes_provider.dart # NotesNotifier tasks_provider.dart # TasksNotifier projects_provider.dart # ProjectsNotifier screens/ notes/note_edit_screen.dart # chip tag input + ProjectSelector tasks/task_edit_screen.dart # ProjectSelector projects/project_list_screen.dart widgets/ project_selector.dart # reusable DropdownButtonFormField ``` ## Navigation 4-tab shell (Notes · Tasks · Projects · Chat): - Phone: bottom `NavigationBar` - Tablet/landscape: `NavigationRail` Quick Capture bar persists across all tabs. Settings accessible from top-right icon. ## Feature Status | Feature | Status | Notes | |---------|--------|-------| | Notes CRUD | ✅ | Tags chip input; project selector in editor | | Tasks CRUD | ✅ | Project selector in editor | | Projects list | ✅ | Active/archived sections; long-press status change; create dialog | | Chat + SSE | ✅ | Full streaming | | Quick Capture | ✅ | Offline queue with retry | | Tags | ✅ | Chip input in NoteEditScreen; typed as `List` | | Project assignment | ✅ | `ProjectSelector` dropdown in Note + Task editors | | Milestones | ❌ deferred | Too granular for mobile; web UI handles it | | Push notifications | ❌ incompatible | Backend uses browser VAPID; Flutter needs FCM/APNs — separate implementation required | | CalDAV settings | ❌ intentional | Server-side config only; not exposed in mobile app | ## API Compatibility Notes - `GET /api/projects/:id` returns a flat JSON object (not `{project: ...}` wrapper); includes `summary` field. - `POST /api/projects` returns the project dict directly (201). - `PATCH /api/projects/:id` returns the updated project dict. - Task body field is `body` (not `description`) — the app maps `description` → `body` on serialize. ## Self-Update The app supports self-update via the Forgejo release API (`update_provider.dart`). It checks the latest release tag and prompts the user to download and install a new APK when one is available. ## CI Builds are triggered from the Forgejo Actions pipeline in the `fabled_app` repository. The APK is attached to the release as a downloadable artifact.