Skip to content

feat(timeline): activity heatmap mode#33

Merged
zpenka merged 2 commits into
mainfrom
feat/timeline
May 6, 2026
Merged

feat(timeline): activity heatmap mode#33
zpenka merged 2 commits into
mainfrom
feat/timeline

Conversation

@zpenka
Copy link
Copy Markdown
Owner

@zpenka zpenka commented May 6, 2026

Summary

Implements PLAN.md item 2B — a calendar-style heatmap of session activity over the last 8 weeks, with cursor navigation and enter-to-filter.

Data layer (timeline.go):

  • buildHeatmap(sessions, now) returns a 7×8 grid (Mon..Sun rows, oldest..newest weeks). Cells aggregate session counts by day; sessions outside the 8-week window are ignored.
  • heatmapBucket(count) maps to four intensity levels: 0 / 1-2 / 3-5 / 6+. Lipgloss styles render dim → bright.
  • countOn / cellOf lookups by date.

Model:

  • New modeTimeline constant. timelineCursor and dateFilter fields.
  • T from list mode enters timeline mode with cursor on today.
  • h/ moves cursor one day earlier, l/ one day later (capped at today on the right, the heatmap's earliest day on the left).
  • enter applies the date filter and returns to list. esc/q returns without filtering.
  • applyFilter composes the existing fuzzy and bookmark filters with the new date filter; esc in list mode clears it along with the others.

Rendering (render.go):

  • renderTimelineView: weekday-labeled grid + intensity legend + highlighted cursor cell
  • renderTimelineHeader: total session count in the window
  • renderTimelineFooter: highlighted date + count + navigation hints (flashes through the same path as other footers)
  • Help overlay: new Timeline Mode block; list-mode help mentions T

Red commit: 6e97bb2
Green commit: ffcc4d4

Test plan

  • go test -race ./... passes
  • Per-package coverage ≥80% (85.3%)
  • go vet ./... clean
  • gofmt -l . clean

🤖 Generated with Claude Code

Zack Penka and others added 2 commits May 6, 2026 14:52
Add failing tests for plan item 2B: a calendar-style heatmap of
session activity.

Data layer (timeline.go, not yet present):
- buildHeatmap(sessions, now) returns a 7x8 grid (Mon..Sun rows,
  8 weeks of columns with the newest week on the right).
- Cells aggregate sessions by Timestamp.Truncate(24h); sessions
  older than 8 weeks are excluded.
- heatmapBucket(count) maps to intensity levels 0..3 with edges at
  0, 1-2, 3-5, 6+.

Model:
- new modeTimeline constant.
- timelineCursor time.Time field.
- 'T' from list mode enters modeTimeline; cursor starts at today.
- 'h' / 'l' (and arrow equivalents) move the cursor by one day,
  capped at today on the right and ~8 weeks back on the left.
- 'enter' filters visibleSessions to the cursor's date and returns
  to modeList.
- 'esc' returns to modeList without filtering.

Rendering:
- renderTimelineView draws weekday labels (Mon/Wed/Fri visible),
  the cell grid, and a footer that shows the highlighted date.

These tests fail to build because none of buildHeatmap,
heatmapBucket, modeTimeline, or m.timelineCursor exist yet. The
next commit adds timeline.go and the model + render integration.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implement plan item 2B: a calendar-style heatmap showing session
activity over the last 8 weeks, with cursor navigation and
enter-to-filter.

Data layer (timeline.go):
- buildHeatmap(sessions, now) returns a 7x8 grid (Mon..Sun rows,
  oldest..newest weeks). Cells aggregate session counts by day;
  sessions outside the 8-week window are ignored.
- heatmapBucket(count) maps to four intensity levels: 0 / 1-2 /
  3-5 / 6+. Lipgloss styles render dim..bright accordingly.
- countOn / cellOf lookups by date.

Model:
- New modeTimeline constant.
- timelineCursor (highlighted day) and dateFilter (selected day
  filter) fields.
- 'T' from list mode enters timeline mode with the cursor on today.
- handleTimelineKey: h/left moves cursor one day earlier, l/right
  one day later (capped at today on the right and the heatmap's
  earliest day on the left). enter applies the date filter and
  returns to list. esc/q returns without filtering.
- applyFilter composes the existing fuzzy and bookmark filters with
  the new date filter; esc in list mode clears it along with the
  others.

Rendering (render.go):
- renderTimelineView: weekday-labeled grid + intensity legend +
  highlighted cursor cell.
- renderTimelineHeader: total session count in the window.
- renderTimelineFooter: highlighted date and session count, plus
  navigation hints; flashes in the same path as other footers.
- Help overlay: new Timeline Mode block; list-mode help mentions T.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@zpenka zpenka merged commit a345110 into main May 6, 2026
1 check passed
@zpenka zpenka deleted the feat/timeline branch May 6, 2026 20:56
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