Skip to content

Latest commit

 

History

History
106 lines (81 loc) · 4.6 KB

File metadata and controls

106 lines (81 loc) · 4.6 KB

fatto (taskchampion android client) — implementation summary

current state

fatto is a fully functional, nordic-themed android application for task management. it supports local task storage, projects, tags, and bi-directional synchronization with any taskchampion-sync-server.

key features implemented

  • rust backend: thin wrapper around taskchampion 3.x using uniffi. supports async operations via tokio.
  • sync engine: manual, reactive (post-mutation), and background (workmanager) sync.
  • secure storage: credentials stored in encryptedsharedpreferences.
  • ui: jetpack compose material 3 with nordic-themed colors and bundled inter v4.1 fonts
  • management:
    • task list with expandable filter/search and sorting.
    • project list with hierarchical support and pending task counts.
    • tag list with auto-resizing text and pending task counts.
    • specialized filtering for internal system tags (BLOCKING, ACTIVE, BLOCKED, WAITING).
    • task creation with auto-suggestions for projects and tags.
    • task detail bottom sheet with auto-save and date pickers.
    • daily notifications: periodic summary of due/scheduled tasks using WorkManager.
  • testing: rust unit/integration tests and android instrumentation tests (all located in src/androidTest).
  • release optimization: streamlined for 64-bit architectures (arm64-v8a, x86_64) and prepared with F-Droid metadata.

architecture

repo layout

.
├── justfile                  ← refactored build pipeline (prefixed targets)
├── docker-compose.yml        ← local sync server (tss) + taskwarrior client
├── rust/
│   └── taskchampion-android/ ← rust cdylib wrapper
└── android/
    └── app/
        ├── src/main/kotlin/  ← kotlin app (package: com.brokenpip3.fatto)
        ├── src/androidTest/  ← instrumentation tests (ui, repository, app info)
        ├── src/main/res/font ← bundled inter v4.1 fonts (f-droid compatible)
        └── src/main/uniffi/  ← autogenerated uniffi bindings

typography & design

  • nordic frost: uses NordicFrost (0xFFF4F7F9) for high-readability backgrounds.
  • local fonts: inter v4.1 (SIL open font license) is bundled locally to ensure privacy and f-droid compatibility.

development environment

fully managed by nix (flake.nix).

  • rust: stable (android targets: aarch64, x86_64)
  • android: sdk 34, ndk 26.1, aapt2 provided via nix
  • java: 17
  • tooling: just, cargo-ndk, uniffi-bindgen

CI/CD optimization

  • lean nix shells: split into fatto-ci-rust (minimal) and fatto-ci-kotlin (minimal SDK) to reduce runner load.
  • shell-specific caching: gradle caches are isolated by nix shell name and flake.lock hash to prevent aapt2 path mismatches.

justfile recipes

the justfile uses a consistent prefix-based convention (build-*, test-*, run-*, check-*, version-*):

# build rust bindings for kotlin
build-bindings:
    # (internal steps: build-rust, gen-bindings)

# build for all supported android architectures (arm64-v8a, x86_64)
build-rust-all:
    # (calls build-rust for 64-bit ABIs)

# build and bundle release apk (rebranded to Fatto)
build-release:
    # (outputs to dist/fatto-v$VERSION.apk)

# increment version (usage: just version-bump 1.2.1)
version-bump name:
    # (updates android/version.properties)

# deploy debug apk to connected device
run-deploy:
    # (builds bindings and installs app-debug.apk)

missing / future work

  • multi-profile support: allow managing multiple taskchampion replicas/databases.
  • error handling: better ui feedback for network timeouts or sync conflicts.
  • performance: for very large databases, consider incremental loading or paging in the viewmodel.
  • ui polish: swipe actions for quick complete/delete, animations for filtering transitions.

notes for next agent

  • ABI support: intentionally limited to 64-bit (arm64-v8a and x86_64) for APK size and build speed.
  • rust bindings: the rust library name (taskchampion-android) and uniffi package (uniffi.taskchampion_android) were preserved to minimize build system disruption.
  • always run just build-bindings after changing lib.rs to ensure kotlin bindings match.
  • aapt2 path: nix-provided aapt2 is forced via GRADLE_OPTS in flake.nix to ensure compatibility across environments.
  • synthetic tags (PENDING, COMPLETED, etc.) are filtered out in the ui but preserved in the backend.
  • tests: instrumented tests are stabilized and run against the com.brokenpip3.fatto namespace.