feat(timeline): activity heatmap mode#33
Merged
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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/cellOflookups by date.Model:
modeTimelineconstant.timelineCursoranddateFilterfields.Tfrom 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).enterapplies the date filter and returns to list.esc/qreturns without filtering.applyFiltercomposes the existing fuzzy and bookmark filters with the new date filter;escin list mode clears it along with the others.Rendering (
render.go):renderTimelineView: weekday-labeled grid + intensity legend + highlighted cursor cellrenderTimelineHeader: total session count in the windowrenderTimelineFooter: highlighted date + count + navigation hints (flashes through the same path as other footers)TRed commit:
6e97bb2Green commit:
ffcc4d4Test plan
go test -race ./...passesgo vet ./...cleangofmt -l .clean🤖 Generated with Claude Code