Calendar mode (v0.0.1): Week / Day / Month / Year / Today views — the lifelog hub #39

Open
opened 2026-09-24 15:12:46 +00:00 by kayg · 4 comments
Owner

Owner direction (DESIGN §29, §30): Calendar is the lifelog hub and ships in v0.0.1 over local data; CalDAV accounts follow in separate issues.

Views and defaults:

  • Desktop default: Week. Mobile default: Today — a flat, scrollable list of days with everything in them.
  • Day, Week, Month, Year, plus Today, switched by the Apple-style segmented control; ‹ Today › pager; big month/year title; keyboard shortcuts (T today, ←/→, 1–4 views).
  • Everything by date (C4): log entries, events (external ones marked subtly by an icon), notes saved, files saved, photos as thumbnails. Events and log entries are stretched blocks; notes, files and photos are points in time in a slim activity lane under the all-day lane. Plan vs actual: in each day column, events (plan) and log entries (actual) sit side by side (Toggl-style), visually distinct; a now-line distinct from both.
  • Busy days (C8): one stacked thumbnail per type per hour ("38 photos", "12 files"), fanning out on hover; per-type toggles for the activity lane.
  • Month (C10): day cells with events and a faint cover photo of the day. Year (C10): an activity heat map (Timepage-style) with photo-day dots.
  • "It will be messy but life is also chaotic": make heavy use of hover previews, thumbnails, interactions and micro-animations so the calendar stays very pretty (calternal.js motion, magnetic hover, pill bounce; reduced-motion respected).
  • Data comes from real APIs: notes/journal (/api/v1/notes/...), files (change feed / listing by mtime), photos (when the photos plugin exists; until then files with image types). A new aggregated endpoint GET /api/v1/calendar/range?from=&to= may be added server-side to return compact per-day buckets fast (budget: week view first paint < 150 ms warm).

Acceptance: real data only; screenshots at 1440×900 and 390×844 in Paper White and Tokyo Night for week, day, month, year, today, a busy day with stacks, hover previews; Playwright e2e for navigation and creation.

Context for the owning job

  • Repo: kayg/calternal (~/Developer/calternal). Read CLAUDE.md, CONTEXT.md and docs/DESIGN.md (§9, §17, §24, §25, §29, §30) first.
  • Vocabulary: a log entry is a retrospective - HH:MM[ - HH:MM] title #tags ^blockid line under ## 📝 Log in a daily note (Notes/Journal/YYYYMMDD-dailynote.md); an event is a scheduled calendar item from an external CalDAV provider. calternal is not a calendar store: log entries are authoritative for calternal's own time data; external events live at their provider.
  • calternal started as a lifelogging app and stays one; Calendar is the lifelog hub (everything by date). The mode tray defaults to Files, Calendar, Photos.
  • Owner rules: file over app; server is the single writer; data loss is unacceptable; performance first but never at the cost of finesse; UI copies Apple Calendar's structure (the owner shared macOS Calendar Week and Day screenshots: Day/Week/Month/Year segmented control top centre, large "September 2026" title with the month bold, ‹ Today › pager top right, all-day lane, hour grid with 09:00-style labels, red circle on today's date, event blocks with a coloured left rule and title/location/time lines, Day view with a mini month and an inspector on the right) plus Fantastical and BusyCal day/week ideas, rendered in the calternal.js design system (copy components verbatim, Claude reviews screenshots side by side); never ship sample/mock data; atomic commits; adversarial testing after API work; good enough, not perfect.
  • Comment on this issue when you start (branch, base SHA), on each finding, when blocked, and when finished (head SHA + gate output). Never close it.
Owner direction (DESIGN §29, §30): Calendar is the lifelog hub and ships in v0.0.1 over local data; CalDAV accounts follow in separate issues. Views and defaults: - **Desktop default: Week. Mobile default: Today** — a flat, scrollable list of days with everything in them. - Day, Week, Month, Year, plus Today, switched by the Apple-style segmented control; ‹ Today › pager; big month/year title; keyboard shortcuts (T today, ←/→, 1–4 views). - Everything by date (C4): log entries, events (external ones marked subtly by an icon), notes saved, files saved, photos as thumbnails. Events and log entries are stretched blocks; notes, files and photos are points in time in a slim **activity lane** under the all-day lane. Plan vs actual: in each day column, events (plan) and log entries (actual) sit side by side (Toggl-style), visually distinct; a now-line distinct from both. - Busy days (C8): one **stacked thumbnail per type per hour** ("38 photos", "12 files"), fanning out on hover; per-type toggles for the activity lane. - Month (C10): day cells with events and a faint **cover photo** of the day. Year (C10): an **activity heat map** (Timepage-style) with photo-day dots. - "It will be messy but life is also chaotic": make heavy use of **hover previews, thumbnails, interactions and micro-animations** so the calendar stays very pretty (calternal.js motion, magnetic hover, pill bounce; reduced-motion respected). - Data comes from real APIs: notes/journal (`/api/v1/notes/...`), files (change feed / listing by mtime), photos (when the photos plugin exists; until then files with image types). A new aggregated endpoint `GET /api/v1/calendar/range?from=&to=` may be added server-side to return compact per-day buckets fast (budget: week view first paint < 150 ms warm). Acceptance: real data only; screenshots at 1440×900 and 390×844 in Paper White and Tokyo Night for week, day, month, year, today, a busy day with stacks, hover previews; Playwright e2e for navigation and creation. ## Context for the owning job - Repo: kayg/calternal (~/Developer/calternal). Read CLAUDE.md, CONTEXT.md and docs/DESIGN.md (§9, §17, §24, §25, §29, §30) first. - Vocabulary: a **log entry** is a retrospective `- HH:MM[ - HH:MM] title #tags ^blockid` line under `## 📝 Log` in a daily note (`Notes/Journal/YYYYMMDD-dailynote.md`); an **event** is a scheduled calendar item from an external CalDAV provider. calternal is **not** a calendar store: log entries are authoritative for calternal's own time data; external events live at their provider. - calternal started as a lifelogging app and stays one; Calendar is the lifelog hub (everything by date). The mode tray defaults to Files, Calendar, Photos. - Owner rules: file over app; server is the single writer; data loss is unacceptable; performance first but never at the cost of finesse; UI copies Apple Calendar's structure (the owner shared macOS Calendar Week and Day screenshots: Day/Week/Month/Year segmented control top centre, large "September 2026" title with the month bold, ‹ Today › pager top right, all-day lane, hour grid with 09:00-style labels, red circle on today's date, event blocks with a coloured left rule and title/location/time lines, Day view with a mini month and an inspector on the right) plus Fantastical and BusyCal day/week ideas, rendered in the calternal.js design system (copy components verbatim, Claude reviews screenshots side by side); never ship sample/mock data; atomic commits; adversarial testing after API work; good enough, not perfect. - Comment on this issue when you start (branch, base SHA), on each finding, when blocked, and when finished (head SHA + gate output). Never close it.
Author
Owner

Owner decision (PKM round, DESIGN §31): Today/Day show the day's log entries with their attached tasks and notes (calternal.js attach-to-latest-log-entry model), tasks on their day plus a sidebar for undated/standalone tasks (K3), bookmarks in the activity lane (#51), and tagged items link to tag pages. Daily notes are app-managed: never show an editable daily-note body.

Owner decision (PKM round, DESIGN §31): Today/Day show the day's log entries with their attached tasks and notes (calternal.js attach-to-latest-log-entry model), tasks on their day plus a sidebar for undated/standalone tasks (K3), bookmarks in the activity lane (#51), and tagged items link to tag pages. Daily notes are app-managed: never show an editable daily-note body.
Author
Owner

Calendar UI job started (web). Branch worktree-agent-aaab58e5ba9b15ba9, base afe8c7a.

Scope: Week / Day / Month / Year / Today views (#39), creation on the grid with the past-or-now → log entry, future → event rule (#42; events show a disabled state until a calendar account can be connected), the popover preview with a pin (#43). Data comes from the existing notes, tasks and files endpoints behind one adapter module, so it can switch to /api/v1/calendar/range (#56) when that lands. #53 repair hints: the journal API does not expose unparsed lines yet, so that part is skipped.

Calendar UI job started (web). Branch `worktree-agent-aaab58e5ba9b15ba9`, base `afe8c7a`. Scope: Week / Day / Month / Year / Today views (#39), creation on the grid with the past-or-now → log entry, future → event rule (#42; events show a disabled state until a calendar account can be connected), the popover preview with a pin (#43). Data comes from the existing notes, tasks and files endpoints behind one adapter module, so it can switch to `/api/v1/calendar/range` (#56) when that lands. #53 repair hints: the journal API does not expose unparsed lines yet, so that part is skipped.
Author
Owner

Calendar UI job finished. Branch worktree-agent-aaab58e5ba9b15ba9, head 60d5c7f, base afe8c7a. Not pushed or merged.

What was built:

  • Views: Week (desktop default), Day with a mini month and a side panel you can resize, Month with a faint cover photo per day, Year as a heat map with dots on photo days, Today (phone default, a list of days that loads more as you scroll). Apple layout: Day/Week/Month/Year control at the top centre, a big "September 2026" title, ‹ Today › pager, all-day lane, activity lane, 09:00 hour grid, today's date in a filled circle, a now line. Shortcuts: T, ←/→, 1–4 (5 = Today), N = new log entry.
  • Links: /calendar/{today|day|week|month|year}/<date>, /d/<date>#^<block-id> opens the Day view with that log entry selected. /today and /calendar open the device default. Copy link on views, days, log entries, tasks, notes and files.
  • #42: drag (or double-click; tap on touch) on the grid. Past or now creates a log entry through POST /notes/journal/log. The future shows "No calendar account is connected yet", and save is turned off.
  • #43: a popover with a pin at the top right. When pinned, it stays open when you click outside, scroll or change dates. Esc closes it. On a phone it shows as a bottom sheet. On the Day view, the side panel shows the details. Hover previews for log blocks and activity stacks.
  • Activity lane: one stack per type per hour (notes, photos, files) that fans out on hover, with a hover preview. You can turn each type on or off.
  • Data: real API only. The adapter (apps/web/src/lib/calendar/data.ts) has the same shape as /api/v1/calendar/range (#56), so switching to it only changes that file.
  • Server change: the journal API now returns each entry's block id (needed for deep links). OpenAPI and the client were regenerated.

Gates: bun run check 0 errors 0 warnings; bun run test 88 passed; bun run build ok; bash packages/api-client/check-generated.sh exit 0; cargo test -p calternal-plugin-notes ok, fmt and clippy clean; bun e2e/calendar.mjs "calendar e2e: all flows passed".

Gaps:

  • Moving or resizing log entries, undo, delete and edit from the popover all need a log-line patch API. None exists yet.
  • An entry that runs past one line does not yet become a linked note.
  • #53 repair hints: the journal API does not return unparsed lines, so this part is skipped.
  • Files and photos come from the Files change feed until #56 lands. Anything older than the feed's retention does not show.
  • Linked files under an entry show as text. There is no way yet to look up a note's id from its path.
  • /f/<id> and /t/<id> links follow the §33 pattern, but those pages are not in this branch.
Calendar UI job finished. Branch `worktree-agent-aaab58e5ba9b15ba9`, head `60d5c7f`, base `afe8c7a`. Not pushed or merged. What was built: - Views: Week (desktop default), Day with a mini month and a side panel you can resize, Month with a faint cover photo per day, Year as a heat map with dots on photo days, Today (phone default, a list of days that loads more as you scroll). Apple layout: Day/Week/Month/Year control at the top centre, a big "**September** 2026" title, ‹ Today › pager, all-day lane, activity lane, 09:00 hour grid, today's date in a filled circle, a now line. Shortcuts: T, ←/→, 1–4 (5 = Today), N = new log entry. - Links: `/calendar/{today|day|week|month|year}/<date>`, `/d/<date>#^<block-id>` opens the Day view with that log entry selected. `/today` and `/calendar` open the device default. Copy link on views, days, log entries, tasks, notes and files. - #42: drag (or double-click; tap on touch) on the grid. Past or now creates a log entry through `POST /notes/journal/log`. The future shows "No calendar account is connected yet", and save is turned off. - #43: a popover with a pin at the top right. When pinned, it stays open when you click outside, scroll or change dates. Esc closes it. On a phone it shows as a bottom sheet. On the Day view, the side panel shows the details. Hover previews for log blocks and activity stacks. - Activity lane: one stack per type per hour (notes, photos, files) that fans out on hover, with a hover preview. You can turn each type on or off. - Data: real API only. The adapter (`apps/web/src/lib/calendar/data.ts`) has the same shape as `/api/v1/calendar/range` (#56), so switching to it only changes that file. - Server change: the journal API now returns each entry's block `id` (needed for deep links). OpenAPI and the client were regenerated. Gates: `bun run check` 0 errors 0 warnings; `bun run test` 88 passed; `bun run build` ok; `bash packages/api-client/check-generated.sh` exit 0; `cargo test -p calternal-plugin-notes` ok, fmt and clippy clean; `bun e2e/calendar.mjs` "calendar e2e: all flows passed". Gaps: - Moving or resizing log entries, undo, delete and edit from the popover all need a log-line patch API. None exists yet. - An entry that runs past one line does not yet become a linked note. - #53 repair hints: the journal API does not return unparsed lines, so this part is skipped. - Files and photos come from the Files change feed until #56 lands. Anything older than the feed's retention does not show. - Linked files under an entry show as text. There is no way yet to look up a note's id from its path. - `/f/<id>` and `/t/<id>` links follow the §33 pattern, but those pages are not in this branch.
Author
Owner

Hygiene review: the final Calendar UI head 60d5c7f0a60589c3e2b123b23f6358ee5ee2a30c is not in origin/dev. The Calendar mode UI remains unmerged, so #39 stays open.

Hygiene review: the final Calendar UI head `60d5c7f0a60589c3e2b123b23f6358ee5ee2a30c` is not in `origin/dev`. The Calendar mode UI remains unmerged, so #39 stays open.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#39
No description provided.