feat: add coloured calendar system indicators
Add a selectable single-dot or per-system indicator mode. Date systems now carry configurable colours; results are cached per displayed month and invalidated when paths/settings change. Refine calendar hierarchy, spacing, hover, and today states.
This commit is contained in:
+37
-27
@@ -51,14 +51,14 @@ Detaches all leaves of `WAYPOINT_VIEW_TYPE`.
|
||||
|
||||
```typescript
|
||||
interface WaypointSettings {
|
||||
calendar: CalendarSettings; // firstDayOfWeek (0=Sun,1=Mon), showNoteIndicators
|
||||
calendar: CalendarSettings; // week start, indicator visibility/style, daily indicator colour
|
||||
daily: PeriodNoteSettings;
|
||||
weekly: PeriodNoteSettings;
|
||||
monthly: PeriodNoteSettings;
|
||||
quarterly: PeriodNoteSettings;
|
||||
yearly: PeriodNoteSettings;
|
||||
dateSystems: DateSystemSettings[]; // day-scoped systems beyond the daily note, in menu order
|
||||
recentFiles: RecentFilesSettings; // maxItems, updateOn, omittedPaths[], omittedTags[], filterTags[]
|
||||
recentFiles: RecentFilesSettings; // maxItems, updateOn, omittedPaths[], omittedTags[], filterTags[]
|
||||
display: DisplaySettings; // px sizing for bookmark rows, fonts, icons, calendar cells
|
||||
}
|
||||
|
||||
@@ -70,8 +70,10 @@ interface PeriodNoteSettings {
|
||||
}
|
||||
|
||||
interface CalendarSettings {
|
||||
firstDayOfWeek: number; // 0 = Sunday, 1 = Monday
|
||||
showNoteIndicators: boolean; // dot on days with existing .md files
|
||||
firstDayOfWeek: number; // 0 = Sunday, 1 = Monday
|
||||
showNoteIndicators: boolean; // show or hide all calendar markers
|
||||
indicatorMode: 'any' | 'systems'; // one neutral dot, or one coloured dot per date system
|
||||
dailyIndicatorColor: string; // daily's colour in systems mode
|
||||
}
|
||||
|
||||
interface RecentFilesSettings {
|
||||
@@ -157,24 +159,24 @@ A **date system** is a folder of notes whose filenames begin with a date. Daily
|
||||
|
||||
### `DateSystemSettings`
|
||||
|
||||
```typescript
|
||||
interface DateSystemSettings {
|
||||
id: string; // stable across edits + reordering, so settings rows can key on it
|
||||
name: string; // menu label, e.g. "Journal"
|
||||
folder: string; // e.g. "periodic/journal"
|
||||
nameFormat: string; // moment format string; may contain "{title}"
|
||||
templateFile: string; // may omit the .md extension
|
||||
typeProperty: string; // fallback frontmatter `type:` value
|
||||
icon: string; // Lucide icon name for the menu item
|
||||
id: string; // stable across edits + reordering, so settings rows can key on it
|
||||
name: string; // menu label, e.g. "Journal"
|
||||
folder: string; // e.g. "periodic/journal"
|
||||
nameFormat: string; // moment format string; may contain "{title}"
|
||||
templateFile: string; // may omit the .md extension
|
||||
typeProperty: string; // fallback frontmatter `type:` value
|
||||
icon: string; // Lucide icon name for the menu item
|
||||
indicatorColor: string; // calendar dot colour in systems mode
|
||||
}
|
||||
```
|
||||
|
||||
Configured systems live in `settings.dateSystems`, where array order is menu order. `DEFAULT_DATE_SYSTEM` (in `settings.ts`, typed `Omit<DateSystemSettings, 'id'>`) supplies the field defaults for a newly added row **and** the merge base for saved ones, so a system persisted before a field existed still loads with that field defined. `DEFAULT_SETTINGS.dateSystems` ships two:
|
||||
|
||||
| `id` | `name` | Folder | `nameFormat` | Notes per date |
|
||||
|---|---|---|---|---|
|
||||
| `journal` | Journal | `periodic/journal` | `YYYY-MM-DD - [Journal]` | one |
|
||||
| `meetings` | Meeting | `periodic/meetings` | `YYYY-MM-DD - {title}` | many |
|
||||
| `id` | `name` | Folder | `nameFormat` | Indicator colour | Notes per date |
|
||||
|---|---|---|---|---|---|
|
||||
| `journal` | Journal | `periodic/journal` | `YYYY-MM-DD - [Journal]` | green (`#22c55e`) | one |
|
||||
| `meetings` | Meeting | `periodic/meetings` | `YYYY-MM-DD - {title}` | violet (`#a855f7`) | many |
|
||||
|
||||
### Templater folder triggers
|
||||
|
||||
@@ -210,21 +212,26 @@ Imports nothing from `'obsidian'` — callers make every moment call and pass th
|
||||
### Plugin API (`main.ts`)
|
||||
|
||||
```typescript
|
||||
/** One existing note of a date system, with the label the menu should show. */
|
||||
interface DateSystemNote {
|
||||
file: TFile;
|
||||
label: string; // free-text title for many-per-date systems, else the system name
|
||||
label: string; // free-text title for many-per-date systems, else the system name
|
||||
}
|
||||
|
||||
/** A day-scoped system and the notes it already holds for one date. */
|
||||
interface DateSystemNotes {
|
||||
system: DateSystemSettings;
|
||||
notes: DateSystemNote[]; // sorted by basename; empty when the date has no note
|
||||
multiple: boolean; // nameFormat carries {title}, i.e. many notes per date
|
||||
notes: DateSystemNote[];
|
||||
multiple: boolean; // nameFormat carries {title}
|
||||
}
|
||||
|
||||
interface DateSystemIndicator {
|
||||
id: string;
|
||||
name: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
dateSystems(): DateSystemSettings[]
|
||||
findDateSystemNotes(date: moment.Moment): DateSystemNotes[]
|
||||
getDateSystemIndicators(dates: moment.Moment[]): Map<string, DateSystemIndicator[]>
|
||||
openDateSystemNote(
|
||||
system: DateSystemSettings,
|
||||
date: moment.Moment,
|
||||
@@ -232,6 +239,8 @@ openDateSystemNote(
|
||||
): Promise<void>
|
||||
```
|
||||
|
||||
**`getDateSystemIndicators(dates)`** — returns one `{ id, name, color }` marker per configured system with one or more notes on a requested day. The calendar calls it once for the visible month only in `indicatorMode: 'systems'`. It makes one vault pass, caches the result by displayed dates and date-system settings, and invalidates it on markdown create/delete/rename or any Settings change. It does not run on ordinary markdown edits: content edits cannot change a filename-derived indicator.
|
||||
|
||||
**`dateSystems()`** — every day-scoped system in menu order: the daily periodic note, synthesized into a `DateSystemSettings` from `settings.daily`, followed by `settings.dateSystems`. The daily note is therefore not a special case in any consumer.
|
||||
|
||||
**`findDateSystemNotes(date)`** — **one** vault scan per call, not one per system. It formats each usable system's `before`/`after` affixes for `date` once, then walks the markdown file list a single time, bucketing each file into the system that claims it (`isInFolder` + `matchesSystemName`). Systems whose formats have no date token are omitted rather than offering an unsafe create action. It returns the remaining `DateSystemNotes` in `dateSystems()` order, each bucket sorted by basename. The calendar's day context menu is built from exactly one of these calls per right-click.
|
||||
@@ -348,7 +357,7 @@ The last section (`waypoint-section:last-child`) gets `margin-top: auto`, pushin
|
||||
- **Breadcrumb:** Q-label, month name, year — each clickable to open that period note.
|
||||
- **Nav buttons:** ◀/▶ shift month ±1. "Today" resets to current month.
|
||||
- **Week number column:** Clicking a week number opens the weekly note for that week's Monday; middle-clicking opens it in a new tab.
|
||||
- **Day cells:** Left-click opens the daily note, middle-click opens it in a new tab, right-click opens the day context menu (below). `.other-month` dimmed. `.today` has accent border. `.has-note` gets a dot indicator, decided by the synchronous O(1) `plugin.hasNoteForDate(dateStr)` (a `Set` lookup — no per-cell vault scan).
|
||||
- **Day cells:** Left-click opens the daily note, middle-click opens it in a new tab, right-click opens the day context menu (below). `.other-month` is muted; `.today` has an inset accent ring; hover receives a quiet fill. With `indicatorMode: 'any'`, `.has-note` shows the existing single neutral dot through the O(1) `plugin.hasNoteForDate(dateStr)` lookup. With `indicatorMode: 'systems'`, the view calls `getDateSystemIndicators()` once for the month and renders one tooltip-labelled coloured dot per matching daily/journal/meeting/custom system.
|
||||
- **Grid generation:** `getMonthGrid(year, month, firstDayOfWeek)` in `date-utils.ts` produces up to 6 weeks, each with 7 `CalendarDay` objects containing `moment`, `dayOfMonth`, `isToday`, `isCurrentMonth`, `isoWeekNumber`.
|
||||
|
||||
**Day context menu (right-click):** Built from a single `plugin.findDateSystemNotes(day.date)` call. The first entry is a non-clickable header showing the full date. Then, per system in `dateSystems()` order:
|
||||
@@ -423,17 +432,18 @@ All classes prefixed with `waypoint-`. Uses Obsidian CSS variables throughout:
|
||||
|
||||
- `--font-ui-small`, `--font-ui-medium`, `--font-semibold`, `--font-medium`, `--font-light`
|
||||
- `--text-muted`, `--text-faint`, `--text-accent`, `--text-on-accent`, `--text-error`
|
||||
- `--background-modifier-border`, `--background-modifier-active-hover`, `--background-primary`, `--background-secondary`
|
||||
- `--background-modifier-border`, `--background-modifier-active-hover`, `--background-modifier-hover`, `--background-primary`, `--background-primary-alt`, `--background-secondary`
|
||||
- `--interactive-accent`
|
||||
- `--cursor-link` (pointer cursor, with a `pointer` fallback)
|
||||
|
||||
Key layout:
|
||||
- `.waypoint-view` — flex column, `overflow-y: auto`, 8px padding.
|
||||
- `.waypoint-section` — `flex-shrink: 0`, 16px bottom margin. Last section gets `margin-top: auto` (pins calendar to bottom).
|
||||
- `.waypoint-section-header` — uppercase, muted, with bottom border.
|
||||
- Calendar table — `table-layout: fixed`, `border-collapse: collapse`.
|
||||
- `.waypoint-day.today` — accent color text + 1px accent border.
|
||||
- `.waypoint-day.has-note::after` — 4px dot indicator.
|
||||
- `.waypoint-calendar` — padded, bordered surface with separated day cells for clear scan lines.
|
||||
- Calendar table — `table-layout: fixed`, `border-collapse: separate`, 2px horizontal / 3px vertical cell spacing.
|
||||
- `.waypoint-day.today` — accent text with an inset accent ring, avoiding layout shifts.
|
||||
- `.waypoint-day.has-note::after` — neutral single-dot indicator.
|
||||
- `.waypoint-day-indicators` / `.waypoint-day-indicator` — compact ordered dot row; `--waypoint-indicator-color` carries each configured system colour.
|
||||
- `.waypoint-bm-chevron` — `rotate(-90deg)` on collapsed groups.
|
||||
- `.waypoint-bm-drop-line` / `.waypoint-bm-drop-below` — 3px accent border for drag indicators.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user