To Do Widget is a personal, offline-first task list for Android and Windows. Android runs as a normal mobile application. Windows runs as a compact, frameless widget that can remain above other windows, hide to the system tray, remember its size and position, and start when the user signs in.
The same Google account owns one private task list on both platforms. Drift and SQLite remain the local source of truth, while Firebase Authentication and Cloud Firestore provide identity and cross-device synchronization.
- Create, edit, complete, restore, reorder, and delete tasks.
- Add private notes and subtask checklists inside the task editor. Notes and subtasks are intentionally hidden from the main task cards.
- Assign an optional deadline. Deadline tasks appear first and are ordered by the earliest deadline.
- Keep tasks without deadlines in a manually reorderable
ANYTIMEsection. - Keep completed tasks visible with a strike-through for 48 hours, then move them to searchable History.
- Work offline using a transactional local mutation outbox.
- Sync automatically when connectivity returns.
- Authenticate with Google on Android and through a browser-assisted flow on Windows.
- Pin, unpin, resize, move, hide, restore, and launch the Windows widget at sign-in.
- Temporarily enlarge a small Windows widget while date and time dialogs are open, then restore its previous bounds.
| Area | Implementation |
|---|---|
| UI | Flutter and Material 3 |
| State management | Riverpod |
| Local database | Drift over SQLite |
| Cloud database | Cloud Firestore |
| Authentication | Firebase Authentication with Google |
| Android background work | WorkManager |
| Windows shell integration | window_manager, tray_manager, and launch_at_startup |
| Windows browser authentication | Firebase Hosting plus a localhost callback |
Firebase client configuration is generated locally and is not tracked in this repository. Use your own Firebase project and identifiers before distributing a fork.
lib/
core/
platform/ Windows window, tray, and startup behavior
theme/ Palette and typography
features/
auth/ Android and Windows Google sign-in
tasks/
application/ Riverpod providers
data/ Drift repository, outbox, and Firestore sync
domain/ Task, subtask, feed, and repository contracts
presentation/ Task list, history, editor, and task tiles
firebase_options.dart Local FlutterFire configuration (ignored by Git)
main.dart Firebase and platform initialization
firebase_hosting/
desktop-auth.html Windows browser sign-in bridge
test/
features/tasks/ Sorting, lifecycle, repository, and subtask tests
Install Flutter (3.41.9 or newer), Git, and the toolchain for the platform you will run:
- Windows: Visual Studio 2022 with Desktop development with C++, CMake, and a Windows SDK.
- Android: Android Studio or the Android SDK, platform tools, and JDK 17.
Confirm that Flutter recognizes the required tooling:
flutter doctor -vClone the repository, open a PowerShell window in its root, then install packages and generate Drift's database code:
git clone <your-repository-url>
Set-Location to_do_widget
flutter pub get
dart run build_runner buildThis app needs Firebase Authentication, Cloud Firestore, and Firebase Hosting for Windows Google sign-in. Create or select your own Firebase project, then generate its local configuration:
npm install -g firebase-tools
dart pub global activate flutterfire_cli
Copy-Item firebase.json.example firebase.json
flutterfire configure --project=<firebase-project-id> --platforms=android,windows --android-package-name=com.pohbo.todo_widget
firebase deploy --only firestore:rules,firestore:indexes,hostingIn Firebase Console, create Firestore and enable the Google sign-in
provider. Android also requires the SHA-1 and SHA-256 fingerprints for each
APK-signing key. Keep the Firebase Hosting deployment current whenever
firebase_hosting/desktop-auth.html changes.
android/app/google-services.json and lib/firebase_options.dart are
intentionally ignored by Git. They are required to build the app, so generate
them locally with the command above. They are not private credentials: the
compiled Android and Windows apps embed equivalent client configuration for
Firebase to use. Protect data with Firebase Authentication, Firestore Security
Rules, App Check where appropriate, and restricted API keys; never commit
service-account files, OAuth client secrets, signing keys, or passwords.
flutter run -d windowsOr run on an Android device/emulator:
flutter devices
flutter run -d <android-device-id>Before submitting changes, run:
dart format --output=none --set-exit-if-changed lib test
flutter analyze
flutter testFor the complete Firebase provisioning, signing, deployment, and troubleshooting guide, see SETUP.md.
flutter build windows --release
flutter build apk --releaseOutputs:
- Windows:
build/windows/x64/runner/Release/to_do_widget.exe - Android:
build/app/outputs/flutter-apk/app-release.apk
An MSIX is not required to run or test the Windows release. Create one only when an installer is needed:
dart run msix:createThe Android release configuration currently uses the debug signing key for local testing. Configure a private release keystore before distribution.
The UI watches Drift, never Firestore directly. Every local mutation updates the local task and appends an outbox entry in the same SQLite transaction. The sync service commits those mutations to Firestore using revisioned, field-level merge transactions. This allows an offline reorder to avoid overwriting unrelated task text.
Task deletions are tombstones rather than immediate local removal, preventing an offline device from recreating a deleted task. Dates are stored in UTC and rendered in the device's local timezone. Subtasks are stored as one checklist field, so concurrent edits to the same checklist use last-committed-write semantics.
The local schema is versioned. Any change to a Drift table must increment
schemaVersion, add a migration, and regenerate app_database.g.dart.
Windows must not call Firebase's native
signInWithProvider(GoogleAuthProvider()); that operation is unsupported on
non-mobile Firebase C++ targets. The application instead opens the hosted
bridge, completes Google authentication in the default browser, validates a
random state value, and returns the short-lived credential through an
ephemeral 127.0.0.1 HTTP callback.
The bridge is initially opened on web.app and moves authentication onto the
matching firebaseapp.com domain. Keep this same-domain behavior: changing it
can cause an endless Google account-selection loop in browsers that isolate
third-party storage.
- README.md: product overview, architecture summary, and common commands for people working with the repository.
- SETUP.md: detailed environment, Firebase, authentication, signing, build, deployment, and troubleshooting guide.
- CLAUDE.md: concise project memory and instructions specifically for Claude-based coding sessions.
- AGENTS.md: implementation invariants, validation requirements, and operating rules for any coding agent.
The expected pre-handoff checks are:
dart format --output=none --set-exit-if-changed lib test
flutter analyze
flutter test
flutter build windows --release
flutter build apk --releaseIf the Windows executable is running, close it before rebuilding; otherwise
the linker can fail with LNK1104 because the output file is locked.