2 Commits
Author SHA1 Message Date
tomas.kracmarandClaude Sonnet 5 77e3eeaf7b Release 1.9.0
- Sidebar-navigation redesign: NavigationSplitView with Routes / Schedule /
  Activity Log replaces the 2x2 panel-card grid. Primary actions moved to
  the toolbar (dry-run/write, sync status, Sync Now); Export/Import/Reveal
  Log/Cleanup/Refresh/Recheck Permission moved to a toolbar overflow menu.
- Routes are now a collapsed-by-default list -- click a row to expand its
  editor instead of always showing every field for every route.
- Schedule view leads with live auto-sync status; the manual launchd
  schedule is demoted to an explicit optional section underneath.
- Activity Log is readable rows (status icon + text) with a search filter
  and a Clear button, instead of a monospaced text dump.
- Menu bar dropdown got icons and real Cmd+,/Cmd+Q shortcuts.
- Explored as a design mockup first (published as an Artifact, light+dark),
  direction confirmed before writing any SwiftUI.

Fixed along the way: routes were being silently dropped on most launches.
reloadCalendars() pruned routes against a freshly-created EKEventStore's
calendar fetch right after a permission grant, which can under-report
calendars for a moment (especially remote/Exchange accounts) before they
finish loading -- wrongly concluding a route's calendar was gone. Only
survived because of a routes.v1 legacy backup key that itself never got
updated after its first write, so any real route edit made in an affected
session would have been silently reverted on the next launch. Fixed by
skipping the prune specifically on the post-grant reload
(reloadCalendars(pruneRoutes: false)) and keeping the legacy backup current
on every save instead of frozen.

All unit tests pass. Verified on a real install: routes stopped
disappearing across repeated launches (checked via --status and reading
the UserDefaults plist directly).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 09:37:21 +02:00
tomas.kracmarandClaude Sonnet 5 edddf65288 Release 1.8.0
- Real Settings (Cmd+,) window via PreferencesView, hosting the pure
  @AppStorage-backed defaults that used to live in the main window's
  "General Settings" panel. Both windows share the same live values since
  they're backed by the same UserDefaults keys.
- Menu bar icon reflects idle/syncing/error state; dropdown shows last-sync
  time/result and whether auto-sync is armed, sourced from the same
  lastRunAtISO/lastRunOK/lastRunSummary keys --status reads.
- ContentView.swift split from ~2000 lines into CalendarsSectionView,
  RoutesSectionView, ScheduleSectionView, LogSectionView + a small shared
  CalendarDisplay.swift. View-layer extraction only — state ownership and
  settings persistence deliberately left alone.
- Fixed a latent revert-on-relaunch bug caught while building the Settings
  window: moving preference controls out of ContentView meant they no longer
  re-triggered saveSettingsToDefaults(), so settings.v2 could go stale and
  the next launch would silently revert a just-changed preference via the
  shared applySnapshot path. Split launch-time restore (routes + selection
  only) from Import's full restore.

All 47 unit tests pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 21:26:07 +02:00