diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-26 20:55:50 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-26 20:55:50 -1000 |
| commit | a3156a2f399ea03c645ee23b0099d9d722ce7e1e (patch) | |
| tree | 03c813717e77ae27d8aee9e676f1b75a6a01648c /internal/handlers/timeline_logic.go | |
| parent | 70e6e51b6781a3986c51e3496b81c88665286872 (diff) | |
Add Google Tasks integration (#43)
- New GoogleTasksClient for fetching and managing Google Tasks
- Tasks appear in Timeline view with yellow indicator dot
- Tap checkbox to complete/uncomplete tasks via Google API
- Shares credentials file with Google Calendar (GOOGLE_CREDENTIALS_FILE)
- Configure task list via GOOGLE_TASKS_LIST_ID env var (default: @default)
- Supports comma-separated list IDs for multiple lists
New files:
- internal/api/google_tasks.go - Google Tasks API client
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'internal/handlers/timeline_logic.go')
| -rw-r--r-- | internal/handlers/timeline_logic.go | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/internal/handlers/timeline_logic.go b/internal/handlers/timeline_logic.go index 553593d..5ea44b5 100644 --- a/internal/handlers/timeline_logic.go +++ b/internal/handlers/timeline_logic.go @@ -13,7 +13,7 @@ import ( ) // BuildTimeline aggregates and normalizes data into a timeline structure -func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.GoogleCalendarAPI, start, end time.Time) ([]models.TimelineItem, error) { +func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.GoogleCalendarAPI, tasksClient api.GoogleTasksAPI, start, end time.Time) ([]models.TimelineItem, error) { var items []models.TimelineItem now := config.Now() @@ -151,6 +151,33 @@ func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.Googl } } + // 5. Fetch Google Tasks + if tasksClient != nil { + gTasks, err := tasksClient.GetTasksByDateRange(ctx, start, end) + if err == nil { + for _, gTask := range gTasks { + taskTime := start // Default to start of range if no due date + if gTask.DueDate != nil { + taskTime = *gTask.DueDate + } + item := models.TimelineItem{ + ID: gTask.ID, + Type: models.TimelineItemTypeGTask, + Title: gTask.Title, + Time: taskTime, + Description: gTask.Notes, + URL: gTask.URL, + OriginalItem: gTask, + IsCompleted: gTask.Completed, + Source: "gtasks", + ListID: gTask.ListID, + } + item.ComputeDaySection(now) + items = append(items, item) + } + } + } + // Sort items by Time sort.Slice(items, func(i, j int) bool { return items[i].Time.Before(items[j].Time) |
