Skip to content

feat: add Tasks app with Todoist provider#23

Open
HenriqueMorato wants to merge 6 commits into
trilwu:mainfrom
HenriqueMorato:feature/tasks-todoist
Open

feat: add Tasks app with Todoist provider#23
HenriqueMorato wants to merge 6 commits into
trilwu:mainfrom
HenriqueMorato:feature/tasks-todoist

Conversation

@HenriqueMorato

@HenriqueMorato HenriqueMorato commented May 23, 2026

Copy link
Copy Markdown

Summary

What is the goal of this PR?

Adds a Tasks app to the Apps menu that shows todos from a configured provider. First provider is Todoist, talking directly to the REST API.

What changes are included?

  • src/tasks/ — generic domain types (Task, TaskProvider, TasksFilter) and a TasksConfig singleton persisting to /.crosspoint/tasks.json
  • src/tasks/providers/todoist/TodoistProvider implementing TaskProvider, plus TodoistFilter translating the generic filter into Todoist's query DSL
  • src/activities/tasks/TasksActivity — Minimal and Daily layouts, plus a first-launch setup screen pointing users to the JSON config on the SD card
  • src/activities/settings/TasksSettingsActivity — provider, design, date/overdue filters, date format, orientation, forget; opened from inside the Tasks app via Left/Right front buttons (mirrors WeatherActivity)
  • appTasks toggle on CrossPetSettings controls visibility in the Tools menu
  • English i18n keys for all new strings

Additional Context

  • Provider is swappable via the TaskProvider interface — Todoist is just the first. Nothing outside src/tasks/providers/todoist/ is Todoist-specific.
  • TodoistProvider inlines esp_http_client with a lazy 16KB buffer allocated post-TLS handshake to dodge heap fragmentation on the ESP32-C3. HttpDownloader was unsuitable: no custom-header API for Bearer auth, no lazy-alloc for the response body.
  • Task uses fixed char[] fields (no std::string) to stay within the ~380KB heap budget.

The Todoist API token is not entered on-device — there's no on-screen keyboard

  1. First time the user opens the Tasks app, TasksConfig writes a stub /.crosspoint/tasks.json to the SD card with empty todoistApiToken and all other defaults.
  2. The setup screen tells the user: "Edit /.crosspoint/tasks.json on the SD card and set todoistApiToken."
  3. User pops the SD card, opens the JSON on their computer, pastes their Todoist API token, saves, puts the card back.
  4. All other settings (provider, layout, filters, date format, orientation) are exposed via TasksSettingsActivity on-device and persist back into the same JSON. Settings can be edited either through the device UI or by hand-editing the file.
  5. The "Forget" row in settings blanks the token on disk and bounces the user back to the setup screen.

AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? YES

image

- Task POD with fixed char[] fields (no std::string, ESP32-C3 heap budget)
- TasksFilter struct with Date/Overdue enum axes
- TaskProvider pure-virtual interface for swappable backends
- TasksConfig singleton persisting to /.crosspoint/tasks.json
- Stub written on first launch with empty token so users have a JSON to edit
- TodoistProvider singleton implements the TaskProvider interface
- TodoistFilter translates generic TasksFilter to Todoist query DSL
- Inlines esp_http_client with lazy 16KB buffer post-TLS to dodge heap fragmentation on ESP32-C3
- Defines TasksConfig::getActiveProvider() here so TasksConfig stays free of provider dependencies
- HttpDownloader was unsuitable: no custom-header API for Bearer auth, no lazy-alloc for the response body
- TasksActivity renders Minimal (compact list) or Daily (date + day-of-week + list) layout
- First-launch setup screen shown when todoistApiToken is empty, pointing user to /.crosspoint/tasks.json on SD card
- Daily date header suppressed when system clock isn't set (no garbage "Jan 1 1970" rendering)
- appTasks toggle on CrossPetSettings controls visibility in Tools menu
- Added minimal Tasks i18n keys (full settings strings land in Phase 4)
- Day-of-week uses LEXEND_18 bold, matching WeatherActivity's headline-data convention
- New TasksSettingsActivity with 7 rows (provider, design, date filter, overdue filter, date format, orientation, forget)
- Launched from inside TasksActivity via Left or Right front button (mirrors WeatherActivity pattern; no entry in main Settings)
- Up/Down now scroll the task list; Left/Right open settings — explicit button handling instead of ButtonNavigator so the two roles don't conflict
- Confirm in Setup state re-loads config so users can populate the token via SD card and continue without restarting the app
- Settings sub-screen restores activity orientation on close so a change there takes effect on the next render
- Added 16 i18n keys for settings labels and filter values
- Load TasksConfig at boot so settings persist across power cycles
- Switch all input handlers to wasReleased to match parent ToolsActivity's edge convention (Back from sub-activity no longer cascades up the stack)
- Wrap the setup screen message with wrappedText so the JSON path fits on smaller orientations
- Natural-sort task titles so "task 2" comes before "task 10"
- Re-sort tasks by date then title (drop the timed/untimed split — it made order surprising for the common all-untimed-today case)
- Nudge the scroll bar into the side padding so it isn't on top of task titles
- Make TasksSettingsActivity landscape-aware so the hint strip stops overlapping the row list in CW/CCW orientations
- Surface the appTasks toggle in the main CrossPet settings panel alongside the other apps
- Add an "Are you sure?" confirmation before Forget and auto-close settings on confirm so the user lands on the setup screen instead of a stale task list
- esp-tls getaddrinfo() returned EAI_FAIL (errno 202) for api.todoist.com immediately after WiFi associated
- lwIP's resolver needs a beat to initialize on a fresh connection
- Mirrors the pattern already used by WeatherActivity::silentRefresh
@HenriqueMorato HenriqueMorato changed the title add Tasks app with Todoist provider feat: add Tasks app with Todoist provider May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant