feat: add calendar notes directory preference#642
Draft
Conversation
Add a user preference to set a custom directory for calendar notes (daily/weekly notes with ISO date filenames like 2026-01-26.md). Changes: - Add src/utils/config.ts with config schema and path utilities - Add src/hooks/config.ts with hooks for reading/saving config - Update global-state.ts to derive note IDs based on config - Update hooks/note.ts to save notes to the correct directory - Add Notes section in settings page with UI to change the directory - Store config in .lumen/config.json (committed to repo) The config supports a single calendarNotesDirectory setting that applies to both daily and weekly notes. When not set, notes are stored in the repository root (the current default behavior).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
colebemis
commented
Jan 26, 2026
Member
Author
colebemis
left a comment
There was a problem hiding this comment.
Note ids should always be just the filepath without the ".md". That shouldn't change when a calendar note directory is specified. What needs to update is, for example, when we type "today" and hit enter it would insert "[[path/to/2025-01-01]]" instead of [[2025-01-01]]. Also "[[path/to/2025-01-01]]" should render as the formatted date instead of "path/to/2025-01-01". Clicking on the calendar nav item and command menu should go to path/to/yyyy-mm-dd instead of yyyy-mm-dd. And so on
|
|
||
| const GITHUB_USER_STORAGE_KEY = "github_user" as const | ||
| const MARKDOWN_FILES_STORAGE_KEY = "markdown_files" as const | ||
| const CONFIG_STORAGE_KEY = "lumen_config" as const |
Member
Author
There was a problem hiding this comment.
This key should be repo specific because eventually we might want to have multiple repos cloned at once
Based on feedback, note IDs should be the full path (e.g., journal/2026-01-26), not just the basename. Changes: - Simplified config utils: removed getNoteFilepath/getNoteIdFromFilepath - Added buildCalendarNoteId and getCalendarNoteBasename helpers - Updated notesAtom to use filepath as ID directly - Updated note hooks to use simple ID + .md for filepath - Updated command-menu to use buildCalendarNoteId for navigation - Updated tests Still TODO: - Update nav-items.tsx (calendar nav item) - Update calendar-header.tsx (today button) - Update link rendering to display calendar note IDs nicely
- nav-items.tsx: Use useBuildCalendarNoteId for Calendar link navigation, update hasDailyNoteAtom to check full path, use isCalendarNoteId for detecting active calendar view - calendar-header.tsx: Update Today/This week button and prev/next navigation to use buildCalendarNoteId - note-link.tsx: Use isCalendarNoteId + getCalendarNoteBasename to detect and properly route calendar notes like 'journal/2026-01-26' - date-link.tsx / week-link.tsx: Accept noteId (full path) and extract basename for formatting display - property-value.tsx: Use useBuildCalendarNoteId for date property links Wikilinks like [[journal/2026-01-26]] now display as formatted dates (e.g., 'January 26, 2026') instead of showing the path.
Updated three files to use getCalendarNoteBasename() before checking if a note ID is a valid date/week string: - src/routes/_appRoot.notes_.$.tsx: Extract basename for isDailyNote/ isWeeklyNote checks, template rendering, date formatting, and DaysOfWeek component - src/components/days-of-week.tsx: Use useBuildCalendarNoteId() to create full note IDs for navigation and lookup, while keeping basename for date formatting - src/components/note-preview.tsx: Use basename for birthday label calculation when viewing calendar notes This fixes calendar and calendar header rendering when using the calendarNotesDirectory config (e.g., note IDs like journal/2026-01-26).
Convert dateCompletion to useDateCompletion hook that uses useBuildCalendarNoteId() to insert the full note path. Now typing 'today' and hitting enter inserts [[journal/2026-01-26]] instead of [[2026-01-26]] when calendarNotesDirectory is configured.
When notes have paths like 'journal/2026-W04', the formatWeek and formatDate functions need just the basename (2026-W04), not the full path. This was causing 'Invalid week: 0NaN-WNaN' errors. Fixes: - parse-note.ts: Use getCalendarNoteBasename() before formatDate/formatWeek - note-preview.tsx: Use getCalendarNoteBasename() for date/week distance formatting
When using VITE_GITHUB_PAT for dev authentication, the token was not being saved to localStorage. This meant users had to click 'Sign in' every time the page reloaded. The OAuth flow worked because resolveUser() saves to localStorage when processing URL params. The PAT flow triggered SIGN_IN directly without saving to localStorage. Fixed by saving to localStorage in the setGitHubUser action when handling the SIGN_IN event.
The Calendar component was receiving full note IDs like 'journal/2025-01-26' but passing them directly to parseISO() and comparing them against date/week strings without extracting the basename first. This caused 'Invalid week: 0NaN-WNaN' errors when clicking calendar nav links when a calendarNotesDirectory was configured. Fixed by: - Importing getCalendarNoteBasename from utils/config - Extracting activeBasename from activeNoteId before parsing - Using activeBasename for all date/week comparisons in Calendar, MonthGrid, and MonthWeekRow components
Issue 1: Root date notes should not be calendar notes when directory is configured - Updated isCalendarNoteId() to accept optional calendarNotesDir parameter - When directory is configured, only notes in that directory are calendar notes - A file like 2026-01-26.md at root is NOT a calendar note when journal/ is configured - Added useIsCalendarNoteId() hook for React components - Updated note-link.tsx and nav-items.tsx to use the hook Issue 2: Calendar component navigation should use configured directory - Updated calendar.tsx to use useBuildCalendarNoteId() for all links - Calendar dates/weeks now navigate to correct paths (e.g., journal/2026-01-26) - Note lookups also use full IDs with directory prefix Added comprehensive tests for isCalendarNoteId with directory parameter.
…onfig - note-preview.tsx: Use useIsCalendarNoteId() hook to properly check if current note is a calendar note (respects configured directory) before showing birthday labels - parse-note.ts: Use basename instead of full id when determining note type (daily/weekly), so notes like 'journal/2026-01-26' are correctly recognized as daily notes Fixes calendar directory config not being respected in note type detection and birthday label display.
parseNote() now accepts optional calendarNotesDir parameter to enforce that daily/weekly notes must be in the configured calendar directory. Examples with calendarNotesDirectory: 'journal': - journal/2026-01-26 → daily note ✓ (correct prefix + valid date) - 2026-01-26 → NOT a daily note ✗ (missing required prefix) - other/2026-01-26 → NOT a daily note ✗ (wrong prefix) Examples with no directory configured (empty string): - 2026-01-26 → daily note ✓ (no prefix needed) - journal/2026-01-26 → NOT a daily note ✗ (has prefix when none expected) Backward compatible: when calendarNotesDir is undefined, only basename is checked (previous behavior). Fixes #642
…etection Previously, the note route was using isValidDateString/isValidWeekString on just the basename to determine if a note was a calendar note. This ignored the calendarNotesDir config, causing bugs where root date notes (e.g., /notes/2026-01-26) would incorrectly show calendar UI even when config specified a different directory (e.g., 'journal/'). Now: - For template selection (before note is parsed), use isCalendarNoteId() which checks both basename AND directory config - For UI rendering (calendar, headers, DaysOfWeek), use parsedNote.type which is already correctly computed by parseNote() This ensures consistent behavior: note.type from parseNote() is THE source of truth for whether a note is daily/weekly/note/template.
Shorter JSON key for user-facing config file. Co-Authored-By: Claude Opus 4.5 <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
Add a user preference to configure which directory contains calendar notes (daily and weekly notes with ISO date filenames like
2026-01-26.mdor2025-W04.md).What This Does
Users can now set a custom directory for calendar notes in Settings → Notes. For example, setting it to
journalmeans:journal/2026-01-26.mdinstead of2026-01-26.mdjournal/2025-W04.mdinstead of2025-W04.mdKey Implementation Details
Config Storage
.lumen/config.jsonat repo root (committed to git, shared across clones){ calendarNotesDirectory?: string }Note Type Detection
parseNote(id, content, calendarNotesDir)usesisCalendarNoteId()which enforces two conditions:YYYY-MM-DD) or week (YYYY-Wnn)"": Note must be at root (no/in path)journal): Note must start withjournal/and have the date as the immediate childThis ensures a note like
random/2026-01-26.mdis NOT treated as a daily note when the config is set tojournal.Calendar Navigation
useBuildCalendarNoteId()hook returns a function that prepends the configured directorygetCalendarNoteBasename()for date parsing<Link to="/notes/$" params={{ _splat: "journal/2026-01-26" }}>Files Changed
src/utils/config.ts- Config schema, parsing, path utilities (isCalendarNoteId,buildCalendarNoteId, etc.)src/hooks/config.ts- React hooks (useCalendarNotesDirectory,useBuildCalendarNoteId,useSaveConfig)src/global-state.ts- Atoms for config state, passescalendarNotesDirtoparseNote()src/utils/parse-note.ts- Accepts optionalcalendarNotesDirparameter for type detectionsrc/components/calendar.tsx- Uses hooks to build correct note IDs and extract basenamessrc/routes/_appRoot.notes_.$.tsx- UsesisCalendarNoteIdand hooks for consistent behaviorBehavior Notes
Test Coverage
isCalendarNoteIdwith/without directory config (empty, configured, nested paths)buildCalendarNoteIdpath constructiongetCalendarNoteBasenameextractioncalendarNotesDirparameter