Releases: rohanrony/notchdock
Releases · rohanrony/notchdock
Release list
Release v0.16.0
Changelog
All notable changes to this project will be documented in this file.
[0.16.0] - 2026-08-24
Added
- European Football Expansion: Added native support for La Liga (
esp.1) and German Bundesliga (ger.1) to the Sports Widget, integrating directly with existing soccer pipelines (linescores, goal events, soccer statistics, table standings, and penalty shootouts).
[0.15.1] - 2026-07-10
Fixed
- Quick Notes Default State: Enabled the Quick Notes widget by default for upgrading and new users, automatically migrating existing user settings lists to prevent user confusion.
[0.15.0] - 2026-07-10
Added
- Quick Notes Testing Suite: Added unit tests covering search filtering (
testQuickNotesSearchFiltering), note body selection and debounce saving (testQuickNotesSelectNoteAndEdit), default onboarding note seeding (testQuickNotesDemoSeeding), permission-denied error states (testQuickNotesOfflineAndPermissionDenied), and note title renaming updates (testQuickNotesUpdateTitle). ExtendedtestQuickNotesStripMetadatato verify class-span style conversions for underline and strikethrough styling, and addedtestRichNSTextViewFormattingto verify custom text editor layout formatting controls and keyboard shortcuts (Command+B/I/U). - Widget Authorization UI: Added explicit local storage authorization flow for Quick Access and ToDo widgets in their respective Settings tabs, resolving macOS Keychain developer prompts gracefully.
- Onboarding Sync: Synchronized widget authorization checks between the Setup Assistant (Onboarding Guide) and the General Settings tabs via shared
@AppStoragekeys. - Quick Notes Widget: Integrated a minimalistic rich-text notes widget that syncs natively with macOS Apple Notes using asynchronous
NSAppleScriptcommands. Features a split-pane layout (30% sidebar list, 70% rich-text editor), search overlay, character/word counters, sync status indicators, and dedicated sync folder selection. - Quick Notes Word/Character Counter: Added a live
"X words • Y characters"counter to the leading position of the Quick Notes footer toolbar row, wired to thegetStats()helper and updating on every body change (spec § 2.2). - Onboarding & Permission flow: Added a permission card for Quick Notes Sync and registered Quick Notes in the Setup Assistant paginated widget guide.
- Testing: Added unit test
testQuickNotesItemManagementto verify note creation, HTML cleaning, AppleScript date parsing, list fetching, and Apple Event descriptor mapping. - Testing: Added unit tests
testQuickNotesStatComputation,testQuickNotesSyncFolderPersistence,testQuickNotesCreateAndDeleteNote,testQuickNotesTitleDerivation, andtestQuickNotesStripMetadatafor comprehensive Quick Notes ViewModel coverage. - Documentation: Added
§ 1.7 Quick Notes Widget Verification Planto11-testing-and-build-workflow.mdwith 14 manual test steps covering the full widget lifecycle. - Calendar Widget Interactive Layout: Restructured the expanded Calendar panel to support a 3-column layout (Month Grid -> Schedule Item List -> Detail Pane) that aligns vertically to the height of the calendar month grid dynamically using a custom SwiftUI
HeightPreferenceKeymeasurement. - Calendar Reminder Check Toggles: Integrated Apple Calendar-style checkbox toggles for Scheduled Reminders directly in the expanded schedule list, allowing users to mark to-dos completed with visual feedback and automatic syncing back to the system Reminders store.
- Testing: Added unit test
testCalendarWidgetSelectionAndReminderTogglesto verify item selection transitions and selection retention logic. - Documentation: Updated the Calendar widget specification documentation to reflect the new layout structure, selection workflow, and reminder checklist toggle details.
- Timer Widget Slider: Designed and integrated a premium, custom Apple-style slider in the expanded Timer widget. The slider behaves dynamically: it allows setting the baseline duration (1 to 60 minutes) when stopped, featuring smooth hover/drag scale animations and automated text-field focus dismissal, and operates as a non-interactive remaining time progress bar when running.
- Stocks Widget Timeframe Selector: Integrated a dropdown menu (1D, 5D, 1M, 3M, 6M, 1Y, 5Y, Max) in the expanded panel header to query stock details and history charts over customized timeframes.
- Stocks Interactive Chart Hover: Added support for continuous hover tracking over sparkline charts, displaying a vertical indicator scrub line, a trend line intersection dot, and an Apple-esque glassmorphic floating price tooltip overlay.
- Testing: Added unit test
testTimerTotalDurationAndProgressto verify the total duration, progress percentages, and slider setting logic. - Testing: Added unit test
testStocksTimeframeAndLazyLoadingLogicto verify the timeframe selection properties and settings persistence. - Documentation: Updated the Timer widget documentation and verification plan with visual specifications and manual test steps for the new slider.
- Documentation: Updated the Stocks widget documentation and verification plan with timeframe selector and rate limit lazy loading specifications.
- ToDo Widget Folders (Sub-Tabs): Integrated multiple folders (e.g. "Work", "Personal") in the expanded ToDo panel with horizontal centering (GeometryReader) and drag-and-drop reordering.
- ToDo Folders Settings: Added an active folder picker, folder renaming, a new folder creation row, and a drag-and-drop reorderable folders list in the ToDo settings view.
- Testing: Added unit test
testToDoFolderLogicto verify adding, renaming, reordering, and deleting folders. - Documentation: Updated the ToDo widget specification to reflect folder tabs, settings management, and Keychain migration schemas.
Fixed
- Keychain Helper Unit Test: Fixed assertion mismatch in
testAuthorizeKeychain_WritesAndReadsSuccessfully()where it asserted the item should exist after test run, ignoring thatauthorizeKeychain()deletes/cleans up the password item before returning. - Notch View Collapse Logic: Fixed issues causing the expanded Notch view to collapse prematurely when clicking bottom toolbar buttons (Bold, Italic, Checklist, Underline, Strikethrough, Table) in the Quick Notes widget, and when moving the mouse afterwards. Implemented real-time cursor coordinate checking (
NSEvent.mouseLocation) with padding bounds verification to ignore spurious window resign-key focus events, and removed temporary hover disable checks from collapse handlers to prevent the panel from getting stuck open on quick hover-out moves. - Quick Notes Aesthetics & Alignment: Refactored the Quick Notes layout to integrate seamlessly and transparently with the native black NotchDock tray, removing the redundant outer card background and outline borders to eliminate the nested 'double box' design. Vertically inset the vertical divider (
.padding(.vertical, 12)) and reduced its opacity to prevent lines from crashing into the tray boundaries. Bound the widget and editor widths dynamically toappState.currentTrayWidthto eliminate both horizontal empty gaps and tray-width fluctuations when switching notes. Overrode the parent container's global horizontal padding using a negative padding (.padding(.horizontal, -16)) and applied custom margins directly to the Sidebar VStack (.padding(.leading, 10)) and Editor VStack (.padding(.trailing, 10)), bringing the content closer to the edges to match the tight, compact layout of other NotchDock widgets. Aligned all internal editor margins and balanced vertical margins (.padding(.vertical, 6)) to make the bottom navbar perfectly symmetric and close to the tray's bottom edge. - Quick Notes Widget Performance: Shifted rich-text HTML generation to a background queue with transaction safety inside
textDidChange, pre-compiled staticNSRegularExpressions to avoid expensive regex compile cycles on every keystroke, and offloaded word/character count updates to background tasks with cached@Publishedproperties, resolving main-thread lag when typing and ensuring immediate, snappy collapse animations. - Quick Notes Toolbar Focus: Replaced
NSApp.keyWindow?.firstResponderwith a static weak reference (RichNSTextView.lastFocused) in all Quick Notes toolbar formatting actions to ensure formatting functions work reliably even when the window temporarily loses key status. - Hover Dismissal: Replaced SwiftUI's
.onHoverwith a customNSTrackingAreaonNotchDockHostingViewfor rock-solid, instant hover-out dismissal that mathematically matches the exact dynamic tray boundaries, fixing edge cases where fast mouse movements or view animations caused the tray to stay stuck open. - Stocks Widget Deadlock: Resolved startup circular initialization deadlock by replacing singleton-level
AppState.sharedqueries infetchQuotes()with a decoupled localisExpandedVisibleflag managed by SwiftUI view lifecycle hooks. - Stocks Widget API Optimization: Configured rate-limit aware lazy loading of watchlist quotes to only fetch full watchlist details when the expanded Stocks panel is active, and only the pinned stock in the background.
- Stocks Widget Chevron Layout: Applied
.menuIndicator(.hidden)to use the system native dropdown indicator arrow on the right side of the timeframe text, matching the visual size and position of the Sports widget. - ToDo Widget Compiler Warning: Fixed "Result of call to 'withAnimation' is unused" Xcode compiler warning in
deleteFolder(at:)by discarding the unused return value. - ToDo & Stocks Layout Padding: Tightened list header paddings in both ToDo and Stocks widgets, pulling headers closer to the menu bar and reducing grid padding for a premium, compact layout.
[0.14.10] - 2026-07-07
Added
- **Widg...
Release v0.15.1
Changelog
All notable changes to this project will be documented in this file.
[0.15.1] - 2026-07-10
Fixed
- Quick Notes Default State: Enabled the Quick Notes widget by default for upgrading and new users, automatically migrating existing user settings lists to prevent user confusion.
[0.15.0] - 2026-07-10
Added
- Quick Notes Testing Suite: Added unit tests covering search filtering (
testQuickNotesSearchFiltering), note body selection and debounce saving (testQuickNotesSelectNoteAndEdit), default onboarding note seeding (testQuickNotesDemoSeeding), permission-denied error states (testQuickNotesOfflineAndPermissionDenied), and note title renaming updates (testQuickNotesUpdateTitle). ExtendedtestQuickNotesStripMetadatato verify class-span style conversions for underline and strikethrough styling, and addedtestRichNSTextViewFormattingto verify custom text editor layout formatting controls and keyboard shortcuts (Command+B/I/U). - Widget Authorization UI: Added explicit local storage authorization flow for Quick Access and ToDo widgets in their respective Settings tabs, resolving macOS Keychain developer prompts gracefully.
- Onboarding Sync: Synchronized widget authorization checks between the Setup Assistant (Onboarding Guide) and the General Settings tabs via shared
@AppStoragekeys. - Quick Notes Widget: Integrated a minimalistic rich-text notes widget that syncs natively with macOS Apple Notes using asynchronous
NSAppleScriptcommands. Features a split-pane layout (30% sidebar list, 70% rich-text editor), search overlay, character/word counters, sync status indicators, and dedicated sync folder selection. - Quick Notes Word/Character Counter: Added a live
"X words • Y characters"counter to the leading position of the Quick Notes footer toolbar row, wired to thegetStats()helper and updating on every body change (spec § 2.2). - Onboarding & Permission flow: Added a permission card for Quick Notes Sync and registered Quick Notes in the Setup Assistant paginated widget guide.
- Testing: Added unit test
testQuickNotesItemManagementto verify note creation, HTML cleaning, AppleScript date parsing, list fetching, and Apple Event descriptor mapping. - Testing: Added unit tests
testQuickNotesStatComputation,testQuickNotesSyncFolderPersistence,testQuickNotesCreateAndDeleteNote,testQuickNotesTitleDerivation, andtestQuickNotesStripMetadatafor comprehensive Quick Notes ViewModel coverage. - Documentation: Added
§ 1.7 Quick Notes Widget Verification Planto11-testing-and-build-workflow.mdwith 14 manual test steps covering the full widget lifecycle. - Calendar Widget Interactive Layout: Restructured the expanded Calendar panel to support a 3-column layout (Month Grid -> Schedule Item List -> Detail Pane) that aligns vertically to the height of the calendar month grid dynamically using a custom SwiftUI
HeightPreferenceKeymeasurement. - Calendar Reminder Check Toggles: Integrated Apple Calendar-style checkbox toggles for Scheduled Reminders directly in the expanded schedule list, allowing users to mark to-dos completed with visual feedback and automatic syncing back to the system Reminders store.
- Testing: Added unit test
testCalendarWidgetSelectionAndReminderTogglesto verify item selection transitions and selection retention logic. - Documentation: Updated the Calendar widget specification documentation to reflect the new layout structure, selection workflow, and reminder checklist toggle details.
- Timer Widget Slider: Designed and integrated a premium, custom Apple-style slider in the expanded Timer widget. The slider behaves dynamically: it allows setting the baseline duration (1 to 60 minutes) when stopped, featuring smooth hover/drag scale animations and automated text-field focus dismissal, and operates as a non-interactive remaining time progress bar when running.
- Stocks Widget Timeframe Selector: Integrated a dropdown menu (1D, 5D, 1M, 3M, 6M, 1Y, 5Y, Max) in the expanded panel header to query stock details and history charts over customized timeframes.
- Stocks Interactive Chart Hover: Added support for continuous hover tracking over sparkline charts, displaying a vertical indicator scrub line, a trend line intersection dot, and an Apple-esque glassmorphic floating price tooltip overlay.
- Testing: Added unit test
testTimerTotalDurationAndProgressto verify the total duration, progress percentages, and slider setting logic. - Testing: Added unit test
testStocksTimeframeAndLazyLoadingLogicto verify the timeframe selection properties and settings persistence. - Documentation: Updated the Timer widget documentation and verification plan with visual specifications and manual test steps for the new slider.
- Documentation: Updated the Stocks widget documentation and verification plan with timeframe selector and rate limit lazy loading specifications.
- ToDo Widget Folders (Sub-Tabs): Integrated multiple folders (e.g. "Work", "Personal") in the expanded ToDo panel with horizontal centering (GeometryReader) and drag-and-drop reordering.
- ToDo Folders Settings: Added an active folder picker, folder renaming, a new folder creation row, and a drag-and-drop reorderable folders list in the ToDo settings view.
- Testing: Added unit test
testToDoFolderLogicto verify adding, renaming, reordering, and deleting folders. - Documentation: Updated the ToDo widget specification to reflect folder tabs, settings management, and Keychain migration schemas.
Fixed
- Keychain Helper Unit Test: Fixed assertion mismatch in
testAuthorizeKeychain_WritesAndReadsSuccessfully()where it asserted the item should exist after test run, ignoring thatauthorizeKeychain()deletes/cleans up the password item before returning. - Notch View Collapse Logic: Fixed issues causing the expanded Notch view to collapse prematurely when clicking bottom toolbar buttons (Bold, Italic, Checklist, Underline, Strikethrough, Table) in the Quick Notes widget, and when moving the mouse afterwards. Implemented real-time cursor coordinate checking (
NSEvent.mouseLocation) with padding bounds verification to ignore spurious window resign-key focus events, and removed temporary hover disable checks from collapse handlers to prevent the panel from getting stuck open on quick hover-out moves. - Quick Notes Aesthetics & Alignment: Refactored the Quick Notes layout to integrate seamlessly and transparently with the native black NotchDock tray, removing the redundant outer card background and outline borders to eliminate the nested 'double box' design. Vertically inset the vertical divider (
.padding(.vertical, 12)) and reduced its opacity to prevent lines from crashing into the tray boundaries. Bound the widget and editor widths dynamically toappState.currentTrayWidthto eliminate both horizontal empty gaps and tray-width fluctuations when switching notes. Overrode the parent container's global horizontal padding using a negative padding (.padding(.horizontal, -16)) and applied custom margins directly to the Sidebar VStack (.padding(.leading, 10)) and Editor VStack (.padding(.trailing, 10)), bringing the content closer to the edges to match the tight, compact layout of other NotchDock widgets. Aligned all internal editor margins and balanced vertical margins (.padding(.vertical, 6)) to make the bottom navbar perfectly symmetric and close to the tray's bottom edge. - Quick Notes Widget Performance: Shifted rich-text HTML generation to a background queue with transaction safety inside
textDidChange, pre-compiled staticNSRegularExpressions to avoid expensive regex compile cycles on every keystroke, and offloaded word/character count updates to background tasks with cached@Publishedproperties, resolving main-thread lag when typing and ensuring immediate, snappy collapse animations. - Quick Notes Toolbar Focus: Replaced
NSApp.keyWindow?.firstResponderwith a static weak reference (RichNSTextView.lastFocused) in all Quick Notes toolbar formatting actions to ensure formatting functions work reliably even when the window temporarily loses key status. - Hover Dismissal: Replaced SwiftUI's
.onHoverwith a customNSTrackingAreaonNotchDockHostingViewfor rock-solid, instant hover-out dismissal that mathematically matches the exact dynamic tray boundaries, fixing edge cases where fast mouse movements or view animations caused the tray to stay stuck open. - Stocks Widget Deadlock: Resolved startup circular initialization deadlock by replacing singleton-level
AppState.sharedqueries infetchQuotes()with a decoupled localisExpandedVisibleflag managed by SwiftUI view lifecycle hooks. - Stocks Widget API Optimization: Configured rate-limit aware lazy loading of watchlist quotes to only fetch full watchlist details when the expanded Stocks panel is active, and only the pinned stock in the background.
- Stocks Widget Chevron Layout: Applied
.menuIndicator(.hidden)to use the system native dropdown indicator arrow on the right side of the timeframe text, matching the visual size and position of the Sports widget. - ToDo Widget Compiler Warning: Fixed "Result of call to 'withAnimation' is unused" Xcode compiler warning in
deleteFolder(at:)by discarding the unused return value. - ToDo & Stocks Layout Padding: Tightened list header paddings in both ToDo and Stocks widgets, pulling headers closer to the menu bar and reducing grid padding for a premium, compact layout.
[0.14.10] - 2026-07-07
Added
- Widget Guides: Created a centralized guide system with custom step-by-step guides for all 7 application widgets.
- Onboarding Guides: Inserted a "Widget Guides" step into the Setup Assistant flow allowing users to browse through instructions for each widget.
- Settings Guides: Added "How to Use" guid...
Release v0.15.0
Changelog
All notable changes to this project will be documented in this file.
[0.15.0] - 2026-07-10
Added
- Quick Notes Testing Suite: Added unit tests covering search filtering (
testQuickNotesSearchFiltering), note body selection and debounce saving (testQuickNotesSelectNoteAndEdit), default onboarding note seeding (testQuickNotesDemoSeeding), permission-denied error states (testQuickNotesOfflineAndPermissionDenied), and note title renaming updates (testQuickNotesUpdateTitle). ExtendedtestQuickNotesStripMetadatato verify class-span style conversions for underline and strikethrough styling, and addedtestRichNSTextViewFormattingto verify custom text editor layout formatting controls and keyboard shortcuts (Command+B/I/U). - Widget Authorization UI: Added explicit local storage authorization flow for Quick Access and ToDo widgets in their respective Settings tabs, resolving macOS Keychain developer prompts gracefully.
- Onboarding Sync: Synchronized widget authorization checks between the Setup Assistant (Onboarding Guide) and the General Settings tabs via shared
@AppStoragekeys. - Quick Notes Widget: Integrated a minimalistic rich-text notes widget that syncs natively with macOS Apple Notes using asynchronous
NSAppleScriptcommands. Features a split-pane layout (30% sidebar list, 70% rich-text editor), search overlay, character/word counters, sync status indicators, and dedicated sync folder selection. - Quick Notes Word/Character Counter: Added a live
"X words • Y characters"counter to the leading position of the Quick Notes footer toolbar row, wired to thegetStats()helper and updating on every body change (spec § 2.2). - Onboarding & Permission flow: Added a permission card for Quick Notes Sync and registered Quick Notes in the Setup Assistant paginated widget guide.
- Testing: Added unit test
testQuickNotesItemManagementto verify note creation, HTML cleaning, AppleScript date parsing, list fetching, and Apple Event descriptor mapping. - Testing: Added unit tests
testQuickNotesStatComputation,testQuickNotesSyncFolderPersistence,testQuickNotesCreateAndDeleteNote,testQuickNotesTitleDerivation, andtestQuickNotesStripMetadatafor comprehensive Quick Notes ViewModel coverage. - Documentation: Added
§ 1.7 Quick Notes Widget Verification Planto11-testing-and-build-workflow.mdwith 14 manual test steps covering the full widget lifecycle. - Calendar Widget Interactive Layout: Restructured the expanded Calendar panel to support a 3-column layout (Month Grid -> Schedule Item List -> Detail Pane) that aligns vertically to the height of the calendar month grid dynamically using a custom SwiftUI
HeightPreferenceKeymeasurement. - Calendar Reminder Check Toggles: Integrated Apple Calendar-style checkbox toggles for Scheduled Reminders directly in the expanded schedule list, allowing users to mark to-dos completed with visual feedback and automatic syncing back to the system Reminders store.
- Testing: Added unit test
testCalendarWidgetSelectionAndReminderTogglesto verify item selection transitions and selection retention logic. - Documentation: Updated the Calendar widget specification documentation to reflect the new layout structure, selection workflow, and reminder checklist toggle details.
- Timer Widget Slider: Designed and integrated a premium, custom Apple-style slider in the expanded Timer widget. The slider behaves dynamically: it allows setting the baseline duration (1 to 60 minutes) when stopped, featuring smooth hover/drag scale animations and automated text-field focus dismissal, and operates as a non-interactive remaining time progress bar when running.
- Stocks Widget Timeframe Selector: Integrated a dropdown menu (1D, 5D, 1M, 3M, 6M, 1Y, 5Y, Max) in the expanded panel header to query stock details and history charts over customized timeframes.
- Stocks Interactive Chart Hover: Added support for continuous hover tracking over sparkline charts, displaying a vertical indicator scrub line, a trend line intersection dot, and an Apple-esque glassmorphic floating price tooltip overlay.
- Testing: Added unit test
testTimerTotalDurationAndProgressto verify the total duration, progress percentages, and slider setting logic. - Testing: Added unit test
testStocksTimeframeAndLazyLoadingLogicto verify the timeframe selection properties and settings persistence. - Documentation: Updated the Timer widget documentation and verification plan with visual specifications and manual test steps for the new slider.
- Documentation: Updated the Stocks widget documentation and verification plan with timeframe selector and rate limit lazy loading specifications.
- ToDo Widget Folders (Sub-Tabs): Integrated multiple folders (e.g. "Work", "Personal") in the expanded ToDo panel with horizontal centering (GeometryReader) and drag-and-drop reordering.
- ToDo Folders Settings: Added an active folder picker, folder renaming, a new folder creation row, and a drag-and-drop reorderable folders list in the ToDo settings view.
- Testing: Added unit test
testToDoFolderLogicto verify adding, renaming, reordering, and deleting folders. - Documentation: Updated the ToDo widget specification to reflect folder tabs, settings management, and Keychain migration schemas.
Fixed
- Keychain Helper Unit Test: Fixed assertion mismatch in
testAuthorizeKeychain_WritesAndReadsSuccessfully()where it asserted the item should exist after test run, ignoring thatauthorizeKeychain()deletes/cleans up the password item before returning. - Notch View Collapse Logic: Fixed issues causing the expanded Notch view to collapse prematurely when clicking bottom toolbar buttons (Bold, Italic, Checklist, Underline, Strikethrough, Table) in the Quick Notes widget, and when moving the mouse afterwards. Implemented real-time cursor coordinate checking (
NSEvent.mouseLocation) with padding bounds verification to ignore spurious window resign-key focus events, and removed temporary hover disable checks from collapse handlers to prevent the panel from getting stuck open on quick hover-out moves. - Quick Notes Aesthetics & Alignment: Refactored the Quick Notes layout to integrate seamlessly and transparently with the native black NotchDock tray, removing the redundant outer card background and outline borders to eliminate the nested 'double box' design. Vertically inset the vertical divider (
.padding(.vertical, 12)) and reduced its opacity to prevent lines from crashing into the tray boundaries. Bound the widget and editor widths dynamically toappState.currentTrayWidthto eliminate both horizontal empty gaps and tray-width fluctuations when switching notes. Overrode the parent container's global horizontal padding using a negative padding (.padding(.horizontal, -16)) and applied custom margins directly to the Sidebar VStack (.padding(.leading, 10)) and Editor VStack (.padding(.trailing, 10)), bringing the content closer to the edges to match the tight, compact layout of other NotchDock widgets. Aligned all internal editor margins and balanced vertical margins (.padding(.vertical, 6)) to make the bottom navbar perfectly symmetric and close to the tray's bottom edge. - Quick Notes Widget Performance: Shifted rich-text HTML generation to a background queue with transaction safety inside
textDidChange, pre-compiled staticNSRegularExpressions to avoid expensive regex compile cycles on every keystroke, and offloaded word/character count updates to background tasks with cached@Publishedproperties, resolving main-thread lag when typing and ensuring immediate, snappy collapse animations. - Quick Notes Toolbar Focus: Replaced
NSApp.keyWindow?.firstResponderwith a static weak reference (RichNSTextView.lastFocused) in all Quick Notes toolbar formatting actions to ensure formatting functions work reliably even when the window temporarily loses key status. - Hover Dismissal: Replaced SwiftUI's
.onHoverwith a customNSTrackingAreaonNotchDockHostingViewfor rock-solid, instant hover-out dismissal that mathematically matches the exact dynamic tray boundaries, fixing edge cases where fast mouse movements or view animations caused the tray to stay stuck open. - Stocks Widget Deadlock: Resolved startup circular initialization deadlock by replacing singleton-level
AppState.sharedqueries infetchQuotes()with a decoupled localisExpandedVisibleflag managed by SwiftUI view lifecycle hooks. - Stocks Widget API Optimization: Configured rate-limit aware lazy loading of watchlist quotes to only fetch full watchlist details when the expanded Stocks panel is active, and only the pinned stock in the background.
- Stocks Widget Chevron Layout: Applied
.menuIndicator(.hidden)to use the system native dropdown indicator arrow on the right side of the timeframe text, matching the visual size and position of the Sports widget. - ToDo Widget Compiler Warning: Fixed "Result of call to 'withAnimation' is unused" Xcode compiler warning in
deleteFolder(at:)by discarding the unused return value. - ToDo & Stocks Layout Padding: Tightened list header paddings in both ToDo and Stocks widgets, pulling headers closer to the menu bar and reducing grid padding for a premium, compact layout.
[0.14.10] - 2026-07-07
Added
- Widget Guides: Created a centralized guide system with custom step-by-step guides for all 7 application widgets.
- Onboarding Guides: Inserted a "Widget Guides" step into the Setup Assistant flow allowing users to browse through instructions for each widget.
- Settings Guides: Added "How to Use" guide cards at the bottom of settings views for Calendar, Music, Quick Access, Sports, Stocks, Timer, and ToDo widgets.
- Testing: Added unit test
testWidgetGuidesContentAndStructureto verify guide content, icons, and ...
Release v0.14.10
Changelog
All notable changes to this project will be documented in this file.
[Unreleased]
Added
[0.14.10] - 2026-07-07
Added
- Module Guides: Created a centralized guide system with custom step-by-step guides for all 7 application modules.
- Onboarding Guides: Inserted a "Module Guides" step into the Setup Assistant flow allowing users to browse through instructions for each widget.
- Settings Guides: Added "How to Use" guide cards at the bottom of settings views for Calendar, Music, Quick Access, Sports, Stocks, Timer, and ToDo modules.
- Testing: Added unit test
testModuleGuidesContentAndStructureto verify guide content, icons, and layout structure. - Stocks Module Drag-and-Drop Reordering: Direct, intuitive drag-and-drop support to reorder watchlist categories (tabs) and individual stock items within watchlists inside the expanded panel view.
- Stocks Module Drag Affordance: Integrated a subtle, premium drag handle (
line.3.horizontal) on the far-left of each stock card in the expanded list, showing low opacity (0.12) normally and fading up to0.35on hover. - Testing: Added unit test cases for the new
moveWatchlist(from:to:)method insidetestStocksReorderingLogicinnotchdockTests.swift.
Fixed
- Settings Theme: Converted color tokens in
ThemeTokensto dynamic colors using theNSColordynamic provider, and removed the forced.darkcolor scheme fromSettingsView. This allows the settings panel to dynamically support a premium Light Mode (with light gray background, solid white cards, and dark gray text) and Dark Mode depending on the system color scheme, while the main app (NotchPanel/IslandView and OnboardingView) remains in the dark color scheme as requested. - Testing: Added
testSettingsViewInitializationunit test to verify settings view construction.
[0.14.9] - 2026-07-06
Added
- Setup Assistant (Onboarding): Polished, premium onboarding flow that opens automatically on first launch to guide users through required permissions. Includes clear cards for:
- Calendar & Reminders: Checks local EventKit authorization.
- Music & Spotify Control: Checks AppleScript Automation authorization.
- ToDo Checklist: Labeled as "Local Storage Enabled" with an interactive "Grant Access" button to prompt for macOS Keychain password authorization.
- Quick Access Snippets: Labeled as "Local Storage Enabled" with an interactive "Grant Access" button to prompt for macOS Keychain password authorization.
- Setup Assistant Settings Relaunch: Added an option under Settings > General > System to manually relaunch the Setup Assistant at any time.
- Testing: Added unit test
testOnboardingWizardStateTrackingto verify the setup assistant lifecycle and completion persistence. - Documentation: Added docs/13-setup-assistant.md detailing the Setup Assistant implementation and mechanics.
[0.14.8] - 2026-06-30
Fixed
- Music Module: Resolved permission status bug where the "Apple Music" authorization state remained stuck in "Access Not Requested" (Allow Access) when permission had already been granted in System Settings. Clicking "Allow Access" now verifies permission inline via an AppleScript query; if already authorized, it updates the state to
.authorizedand bypasses opening the System Settings app. - Testing: Added unit test
testMusicRequestPermissionBehaviorto verify the state updates of both authorized and denied permission scenarios.
[0.14.6] - 2026-06-30
Added
- Sports Module: Penalty shootout support for soccer matches, including bracketed shootout scores displayed next to regulation scores in both the expanded card view and the match stats popup.
- Sports Module: Custom robust decoders for
ESPNLinescoreandESPNCompetitorto safely parse shootout goals represented as Double, Int, or String in the JSON responses. - Sports Module: Status detail fallback parser
parseShootoutFromStatusDetailinmakeGameto extract shootout scores from the status string when native linescores are absent.
Changed
- Sports Module: Decoupled shootout scores into dedicated
homeShootoutScore/awayShootoutScoreproperties to ensure period linescores grids and match stats tables remain clean of shootout elements.
Fixed
- Updater: Enabled Sparkle's sandboxed updater installer launcher service (
SUEnableInstallerLauncherService = YES/INFOPLIST_KEY_SUEnableInstallerLauncherService) to resolve updater launch failure abort errors during updates in the macOS App Sandbox. - Resolved missing application icon in built app by extracting PNG files from
AppIcon.icnsand adding them to the asset catalogAssets.xcassets/AppIcon.appiconset. - Updated
.gitignoreto prevent PNG files inside.xcassetsdirectories from being ignored by Git. - Testing & State Synchronization: Fixed state reset bug where assigning
isExpanded = falseoractiveExtensionIDto their current values in observers redundantly clearedselectedGameForStatsby introducing transition check guards (oldValue && !isExpandedandoldValue != activeExtensionID). - Testing: Guarded the hover-out collapse block in
IslandView.swiftto prevent spurious initial hover events from triggering collapse timers when views first render. - Testing: Silenced real ESPN API data tasks during tests by adding
isTestingchecks insidefetchScores(),fetchPastAndUpcomingGames(), andfetchGameStats(for:)inSportsModule.swift, preventing background network requests from leaking and corrupting mock test states in subsequent tests.
[0.14.5] - 2026-06-30
Added
- Integrated codesigning of the final packaged DMG (
NotchDock.dmg) using the Developer ID Application certificate.
Changed
- Post-processed Sparkle update feed (
appcast.xml) enclosure URLs to point directly to GitHub Release assets instead of the local website domain.
[0.14.4] - 2026-06-29
Changed
- Roadmap: Removed redundant "Planned" badges/texts from the Apps Roadmap settings view.
- Testing: Added UI test
testAppsRoadmapViewto verify the Apps Roadmap page loads and the "Planned" badges do not exist.
Fixed
- Fixed Xcode build warning by removing
Info.plistfrom target membership exceptions list in the Folder Sync configurations, preventing it from being copied as a raw bundle resource. - Testing: Resolved unit test host background pollution by introducing dynamic framework-based test runner detection to disable background fetching and polling timers in
CalendarViewModel,SportsViewModel,StocksViewModel, andAppStateat startup. - Testing: Fixed a timing bug in
testNewCalendarNotchviewLogicDetailed()by setting the test event start date to 20 minutes ago and extending its duration to 3 hours, aligning it with the expected key, duration, and phase assertions. - Testing: Synchronized Combine updates in unit tests by introducing run loop spinning (
spinRunLoop()) to allow asynchronous notifications to deliver before assertions are evaluated. - Testing: Fixed test isolation issues in
testStocksViewModelLogic()by resetting the view model's pinned tickers and index. - Testing: Implemented a global
resetSharedStates()setup & teardown cleanup innotchdockTests.swiftthat runs before and after each test case, resetting all shared singletons (AppState.shared,SportsViewModel.shared,StocksViewModel.shared,TimerViewModel.shared) and flushing Combine main loop dispatches, guaranteeing complete test-to-test execution isolation. - Testing: Fixed
testNotchLogMaxLimit()false positive substring match on 'Log line 1' by checking for exact line suffix match instead of simple substring containment. - Testing: Restored original
switchIntervalvalues properly during test setup and teardown insidetestSingleAppUpdatesLoopingAndSwitching()to avoid local developer config leaks. - Stocks Module: Corrected a state update race condition in
clampPinnedIndexby triggering it synchronously insidepinnedTickers.didSetrather than asynchronously via a Combine subscription, preventingwillSettiming races. - Sports Module: Corrected a date grouping sort order assertion in
testSportsDateGrouping(). - AppState: Wrapped
selectedGameForStatsstate resets inAppStateinsideif !isTestingguards to prevent asynchronous layout updates in the running host application from resetting the view model's stats selection tonilduring test runs.
[0.14.1] - 2026-06-28
Fixed
- Resolved Sparkle update error by introducing a physical
Info.plisttemplate to correctly merge custom Sparkle keys (SUFeedURL,SUPublicEDKey) during the Xcode build process.
[0.14.0] - 2026-06-28
Added
- Privacy Policy: Created a premium, responsive
releases/privacy.htmlpolicy document detailing NotchDock's local-first architecture and third-party data handlers. - Settings: Added a direct link to the hosted Privacy Policy (
https://notchdock.app/privacy.html) on the About screen. - Testing: Updated the
testSettingsLinksunit test to assert the new Privacy Policy URL inSettingsLinks. - Settings: Disclaimer footnote in the About section stating third-party data is public, provided "as-is", and not affiliated with ESPN or Yahoo Finance.
- Settings: Free Public Beta badge and monetization explanation text on the About page.
- Testing: UI test to verify the disclaimer, beta badge, and beta description text displays on the About settings page.
- Sports Module: Premium Game Stats Popup loading experience with stable layout heights, pulsing skeleton loader screens, and staggered progressive fade-in/slide-up animations on data load completion.
Changed
- Sports Module: Added horizontal padding to the stats popup views (...
Release v0.14.9
Changelog
All notable changes to this project will be documented in this file.
[Unreleased]
[0.14.9] - 2026-07-06
Added
- Setup Assistant (Onboarding): Polished, premium onboarding flow that opens automatically on first launch to guide users through required permissions. Includes clear cards for:
- Calendar & Reminders: Checks local EventKit authorization.
- Music & Spotify Control: Checks AppleScript Automation authorization.
- ToDo Checklist: Labeled as "Local Storage Enabled" with an interactive "Grant Access" button to prompt for macOS Keychain password authorization.
- Quick Access Snippets: Labeled as "Local Storage Enabled" with an interactive "Grant Access" button to prompt for macOS Keychain password authorization.
- Setup Assistant Settings Relaunch: Added an option under Settings > General > System to manually relaunch the Setup Assistant at any time.
- Testing: Added unit test
testOnboardingWizardStateTrackingto verify the setup assistant lifecycle and completion persistence. - Documentation: Added docs/13-setup-assistant.md detailing the Setup Assistant implementation and mechanics.
[0.14.8] - 2026-06-30
Fixed
- Music Module: Resolved permission status bug where the "Apple Music" authorization state remained stuck in "Access Not Requested" (Allow Access) when permission had already been granted in System Settings. Clicking "Allow Access" now verifies permission inline via an AppleScript query; if already authorized, it updates the state to
.authorizedand bypasses opening the System Settings app. - Testing: Added unit test
testMusicRequestPermissionBehaviorto verify the state updates of both authorized and denied permission scenarios.
[0.14.6] - 2026-06-30
Added
- Sports Module: Penalty shootout support for soccer matches, including bracketed shootout scores displayed next to regulation scores in both the expanded card view and the match stats popup.
- Sports Module: Custom robust decoders for
ESPNLinescoreandESPNCompetitorto safely parse shootout goals represented as Double, Int, or String in the JSON responses. - Sports Module: Status detail fallback parser
parseShootoutFromStatusDetailinmakeGameto extract shootout scores from the status string when native linescores are absent.
Changed
- Sports Module: Decoupled shootout scores into dedicated
homeShootoutScore/awayShootoutScoreproperties to ensure period linescores grids and match stats tables remain clean of shootout elements.
Fixed
- Updater: Enabled Sparkle's sandboxed updater installer launcher service (
SUEnableInstallerLauncherService = YES/INFOPLIST_KEY_SUEnableInstallerLauncherService) to resolve updater launch failure abort errors during updates in the macOS App Sandbox. - Resolved missing application icon in built app by extracting PNG files from
AppIcon.icnsand adding them to the asset catalogAssets.xcassets/AppIcon.appiconset. - Updated
.gitignoreto prevent PNG files inside.xcassetsdirectories from being ignored by Git. - Testing & State Synchronization: Fixed state reset bug where assigning
isExpanded = falseoractiveExtensionIDto their current values in observers redundantly clearedselectedGameForStatsby introducing transition check guards (oldValue && !isExpandedandoldValue != activeExtensionID). - Testing: Guarded the hover-out collapse block in
IslandView.swiftto prevent spurious initial hover events from triggering collapse timers when views first render. - Testing: Silenced real ESPN API data tasks during tests by adding
isTestingchecks insidefetchScores(),fetchPastAndUpcomingGames(), andfetchGameStats(for:)inSportsModule.swift, preventing background network requests from leaking and corrupting mock test states in subsequent tests.
[0.14.5] - 2026-06-30
Added
- Integrated codesigning of the final packaged DMG (
NotchDock.dmg) using the Developer ID Application certificate.
Changed
- Post-processed Sparkle update feed (
appcast.xml) enclosure URLs to point directly to GitHub Release assets instead of the local website domain.
[0.14.4] - 2026-06-29
Changed
- Roadmap: Removed redundant "Planned" badges/texts from the Apps Roadmap settings view.
- Testing: Added UI test
testAppsRoadmapViewto verify the Apps Roadmap page loads and the "Planned" badges do not exist.
Fixed
- Fixed Xcode build warning by removing
Info.plistfrom target membership exceptions list in the Folder Sync configurations, preventing it from being copied as a raw bundle resource. - Testing: Resolved unit test host background pollution by introducing dynamic framework-based test runner detection to disable background fetching and polling timers in
CalendarViewModel,SportsViewModel,StocksViewModel, andAppStateat startup. - Testing: Fixed a timing bug in
testNewCalendarNotchviewLogicDetailed()by setting the test event start date to 20 minutes ago and extending its duration to 3 hours, aligning it with the expected key, duration, and phase assertions. - Testing: Synchronized Combine updates in unit tests by introducing run loop spinning (
spinRunLoop()) to allow asynchronous notifications to deliver before assertions are evaluated. - Testing: Fixed test isolation issues in
testStocksViewModelLogic()by resetting the view model's pinned tickers and index. - Testing: Implemented a global
resetSharedStates()setup & teardown cleanup innotchdockTests.swiftthat runs before and after each test case, resetting all shared singletons (AppState.shared,SportsViewModel.shared,StocksViewModel.shared,TimerViewModel.shared) and flushing Combine main loop dispatches, guaranteeing complete test-to-test execution isolation. - Testing: Fixed
testNotchLogMaxLimit()false positive substring match on 'Log line 1' by checking for exact line suffix match instead of simple substring containment. - Testing: Restored original
switchIntervalvalues properly during test setup and teardown insidetestSingleAppUpdatesLoopingAndSwitching()to avoid local developer config leaks. - Stocks Module: Corrected a state update race condition in
clampPinnedIndexby triggering it synchronously insidepinnedTickers.didSetrather than asynchronously via a Combine subscription, preventingwillSettiming races. - Sports Module: Corrected a date grouping sort order assertion in
testSportsDateGrouping(). - AppState: Wrapped
selectedGameForStatsstate resets inAppStateinsideif !isTestingguards to prevent asynchronous layout updates in the running host application from resetting the view model's stats selection tonilduring test runs.
[0.14.1] - 2026-06-28
Fixed
- Resolved Sparkle update error by introducing a physical
Info.plisttemplate to correctly merge custom Sparkle keys (SUFeedURL,SUPublicEDKey) during the Xcode build process.
[0.14.0] - 2026-06-28
Added
- Privacy Policy: Created a premium, responsive
releases/privacy.htmlpolicy document detailing NotchDock's local-first architecture and third-party data handlers. - Settings: Added a direct link to the hosted Privacy Policy (
https://notchdock.app/privacy.html) on the About screen. - Testing: Updated the
testSettingsLinksunit test to assert the new Privacy Policy URL inSettingsLinks. - Settings: Disclaimer footnote in the About section stating third-party data is public, provided "as-is", and not affiliated with ESPN or Yahoo Finance.
- Settings: Free Public Beta badge and monetization explanation text on the About page.
- Testing: UI test to verify the disclaimer, beta badge, and beta description text displays on the About settings page.
- Sports Module: Premium Game Stats Popup loading experience with stable layout heights, pulsing skeleton loader screens, and staggered progressive fade-in/slide-up animations on data load completion.
Changed
- Sports Module: Added horizontal padding to the stats popup views (statistics, key performers, match events, and skeleton loaders) to keep the contents aligned and visually balanced within the wider popover window.
Fixed
- Sports Module: Resolved an extraneous closing brace compiler error at the top level of the module file.
[0.13.10] - 2026-06-27
Added
- Automated Apple Developer ID code signing, DMG notarization, and verification integration in
release.sh. - Sparkle 2 auto-update framework support and automated update feed (
appcast.xml) generation.
Changed
- Segregated debug and release build sandbox containers using a
.debugbundle identifier suffix for development. - Restructured and renamed
package.shtorelease.shand consolidated release workflow documentation.
[0.13.6] - 2026-06-24
Added
- Sports Module Improvements:
- Pinned Sports live score display with a score-triggered 5-second automatic compact panel expansion.
- Interactive Game Stats popup displaying possession, shots, passing accuracy, and match incidents.
- Automatic dismissal logic for the temporary NotchPanel expansion with hover detection override (canceling collapse on hover).
- Scoreboard fetch resilience with support for date-specific endpoints, result deduplication, and fallback handling when APIs fail.
- Throttling and cooldown policies for sports scoreboard and statistics API requests to handle rate limits.
- Music Module Improvements:
- Dynamic check for music automation permission with clean status indicators.
- Automatic compact view hide timeout after 2 minutes of paused music playback.
- Settings & Diagnostics:
- Dynamic contact support, issue reporting, and user guide links in the Settings sidebar.
- Robust diagnostic logging and export system for troubleshooti...
Release v0.14.8
Changelog
All notable changes to this project will be documented in this file.
[0.14.8] - 2026-06-30
Fixed
- Music Module: Resolved permission status bug where the "Apple Music" authorization state remained stuck in "Access Not Requested" (Allow Access) when permission had already been granted in System Settings. Clicking "Allow Access" now verifies permission inline via an AppleScript query; if already authorized, it updates the state to
.authorizedand bypasses opening the System Settings app. - Testing: Added unit test
testMusicRequestPermissionBehaviorto verify the state updates of both authorized and denied permission scenarios.
[0.14.6] - 2026-06-30
Added
- Sports Module: Penalty shootout support for soccer matches, including bracketed shootout scores displayed next to regulation scores in both the expanded card view and the match stats popup.
- Sports Module: Custom robust decoders for
ESPNLinescoreandESPNCompetitorto safely parse shootout goals represented as Double, Int, or String in the JSON responses. - Sports Module: Status detail fallback parser
parseShootoutFromStatusDetailinmakeGameto extract shootout scores from the status string when native linescores are absent.
Changed
- Sports Module: Decoupled shootout scores into dedicated
homeShootoutScore/awayShootoutScoreproperties to ensure period linescores grids and match stats tables remain clean of shootout elements.
Fixed
- Updater: Enabled Sparkle's sandboxed updater installer launcher service (
SUEnableInstallerLauncherService = YES/INFOPLIST_KEY_SUEnableInstallerLauncherService) to resolve updater launch failure abort errors during updates in the macOS App Sandbox. - Resolved missing application icon in built app by extracting PNG files from
AppIcon.icnsand adding them to the asset catalogAssets.xcassets/AppIcon.appiconset. - Updated
.gitignoreto prevent PNG files inside.xcassetsdirectories from being ignored by Git. - Testing & State Synchronization: Fixed state reset bug where assigning
isExpanded = falseoractiveExtensionIDto their current values in observers redundantly clearedselectedGameForStatsby introducing transition check guards (oldValue && !isExpandedandoldValue != activeExtensionID). - Testing: Guarded the hover-out collapse block in
IslandView.swiftto prevent spurious initial hover events from triggering collapse timers when views first render. - Testing: Silenced real ESPN API data tasks during tests by adding
isTestingchecks insidefetchScores(),fetchPastAndUpcomingGames(), andfetchGameStats(for:)inSportsModule.swift, preventing background network requests from leaking and corrupting mock test states in subsequent tests.
[0.14.5] - 2026-06-30
Added
- Integrated codesigning of the final packaged DMG (
NotchDock.dmg) using the Developer ID Application certificate.
Changed
- Post-processed Sparkle update feed (
appcast.xml) enclosure URLs to point directly to GitHub Release assets instead of the local website domain.
[0.14.4] - 2026-06-29
Changed
- Roadmap: Removed redundant "Planned" badges/texts from the Apps Roadmap settings view.
- Testing: Added UI test
testAppsRoadmapViewto verify the Apps Roadmap page loads and the "Planned" badges do not exist.
Fixed
- Fixed Xcode build warning by removing
Info.plistfrom target membership exceptions list in the Folder Sync configurations, preventing it from being copied as a raw bundle resource. - Testing: Resolved unit test host background pollution by introducing dynamic framework-based test runner detection to disable background fetching and polling timers in
CalendarViewModel,SportsViewModel,StocksViewModel, andAppStateat startup. - Testing: Fixed a timing bug in
testNewCalendarNotchviewLogicDetailed()by setting the test event start date to 20 minutes ago and extending its duration to 3 hours, aligning it with the expected key, duration, and phase assertions. - Testing: Synchronized Combine updates in unit tests by introducing run loop spinning (
spinRunLoop()) to allow asynchronous notifications to deliver before assertions are evaluated. - Testing: Fixed test isolation issues in
testStocksViewModelLogic()by resetting the view model's pinned tickers and index. - Testing: Implemented a global
resetSharedStates()setup & teardown cleanup innotchdockTests.swiftthat runs before and after each test case, resetting all shared singletons (AppState.shared,SportsViewModel.shared,StocksViewModel.shared,TimerViewModel.shared) and flushing Combine main loop dispatches, guaranteeing complete test-to-test execution isolation. - Testing: Fixed
testNotchLogMaxLimit()false positive substring match on 'Log line 1' by checking for exact line suffix match instead of simple substring containment. - Testing: Restored original
switchIntervalvalues properly during test setup and teardown insidetestSingleAppUpdatesLoopingAndSwitching()to avoid local developer config leaks. - Stocks Module: Corrected a state update race condition in
clampPinnedIndexby triggering it synchronously insidepinnedTickers.didSetrather than asynchronously via a Combine subscription, preventingwillSettiming races. - Sports Module: Corrected a date grouping sort order assertion in
testSportsDateGrouping(). - AppState: Wrapped
selectedGameForStatsstate resets inAppStateinsideif !isTestingguards to prevent asynchronous layout updates in the running host application from resetting the view model's stats selection tonilduring test runs.
[0.14.1] - 2026-06-28
Fixed
- Resolved Sparkle update error by introducing a physical
Info.plisttemplate to correctly merge custom Sparkle keys (SUFeedURL,SUPublicEDKey) during the Xcode build process.
[0.14.0] - 2026-06-28
Added
- Privacy Policy: Created a premium, responsive
releases/privacy.htmlpolicy document detailing NotchDock's local-first architecture and third-party data handlers. - Settings: Added a direct link to the hosted Privacy Policy (
https://notchdock.app/privacy.html) on the About screen. - Testing: Updated the
testSettingsLinksunit test to assert the new Privacy Policy URL inSettingsLinks. - Settings: Disclaimer footnote in the About section stating third-party data is public, provided "as-is", and not affiliated with ESPN or Yahoo Finance.
- Settings: Free Public Beta badge and monetization explanation text on the About page.
- Testing: UI test to verify the disclaimer, beta badge, and beta description text displays on the About settings page.
- Sports Module: Premium Game Stats Popup loading experience with stable layout heights, pulsing skeleton loader screens, and staggered progressive fade-in/slide-up animations on data load completion.
Changed
- Sports Module: Added horizontal padding to the stats popup views (statistics, key performers, match events, and skeleton loaders) to keep the contents aligned and visually balanced within the wider popover window.
Fixed
- Sports Module: Resolved an extraneous closing brace compiler error at the top level of the module file.
[0.13.10] - 2026-06-27
Added
- Automated Apple Developer ID code signing, DMG notarization, and verification integration in
release.sh. - Sparkle 2 auto-update framework support and automated update feed (
appcast.xml) generation.
Changed
- Segregated debug and release build sandbox containers using a
.debugbundle identifier suffix for development. - Restructured and renamed
package.shtorelease.shand consolidated release workflow documentation.
[0.13.6] - 2026-06-24
Added
- Sports Module Improvements:
- Pinned Sports live score display with a score-triggered 5-second automatic compact panel expansion.
- Interactive Game Stats popup displaying possession, shots, passing accuracy, and match incidents.
- Automatic dismissal logic for the temporary NotchPanel expansion with hover detection override (canceling collapse on hover).
- Scoreboard fetch resilience with support for date-specific endpoints, result deduplication, and fallback handling when APIs fail.
- Throttling and cooldown policies for sports scoreboard and statistics API requests to handle rate limits.
- Music Module Improvements:
- Dynamic check for music automation permission with clean status indicators.
- Automatic compact view hide timeout after 2 minutes of paused music playback.
- Settings & Diagnostics:
- Dynamic contact support, issue reporting, and user guide links in the Settings sidebar.
- Robust diagnostic logging and export system for troubleshooting Calendar, Reminders, and system state.
- Layout & Rendering Stability:
StableHostingViewandCachedAsyncImagecomponents to completely prevent recursive Auto Layout constraint crashes caused by dynamic image loading.
Changed
- Centralized panel transition and rotation logic into
AppStatewith standardized 15-second rotation intervals.
Fixed
- Sports module scoreboard alignment and column symmetry (linescores, team logos, abbreviations, records).
- Hover reactivation bug preventing the panel from expanding unexpectedly near closed/hidden bounds.
Refactored
- Seeded deterministic mock game stats and incidents to ensure stable, reliable automated tests.
Release v0.14.7
Changelog
All notable changes to this project will be documented in this file.
[0.14.6] - 2026-06-30
Added
- Sports Module: Penalty shootout support for soccer matches, including bracketed shootout scores displayed next to regulation scores in both the expanded card view and the match stats popup.
- Sports Module: Custom robust decoders for
ESPNLinescoreandESPNCompetitorto safely parse shootout goals represented as Double, Int, or String in the JSON responses. - Sports Module: Status detail fallback parser
parseShootoutFromStatusDetailinmakeGameto extract shootout scores from the status string when native linescores are absent.
Changed
- Sports Module: Decoupled shootout scores into dedicated
homeShootoutScore/awayShootoutScoreproperties to ensure period linescores grids and match stats tables remain clean of shootout elements.
Fixed
- Updater: Enabled Sparkle's sandboxed updater installer launcher service (
SUEnableInstallerLauncherService = YES/INFOPLIST_KEY_SUEnableInstallerLauncherService) to resolve updater launch failure abort errors during updates in the macOS App Sandbox. - Resolved missing application icon in built app by extracting PNG files from
AppIcon.icnsand adding them to the asset catalogAssets.xcassets/AppIcon.appiconset. - Updated
.gitignoreto prevent PNG files inside.xcassetsdirectories from being ignored by Git. - Testing & State Synchronization: Fixed state reset bug where assigning
isExpanded = falseoractiveExtensionIDto their current values in observers redundantly clearedselectedGameForStatsby introducing transition check guards (oldValue && !isExpandedandoldValue != activeExtensionID). - Testing: Guarded the hover-out collapse block in
IslandView.swiftto prevent spurious initial hover events from triggering collapse timers when views first render. - Testing: Silenced real ESPN API data tasks during tests by adding
isTestingchecks insidefetchScores(),fetchPastAndUpcomingGames(), andfetchGameStats(for:)inSportsModule.swift, preventing background network requests from leaking and corrupting mock test states in subsequent tests.
[0.14.5] - 2026-06-30
Added
- Integrated codesigning of the final packaged DMG (
NotchDock.dmg) using the Developer ID Application certificate.
Changed
- Post-processed Sparkle update feed (
appcast.xml) enclosure URLs to point directly to GitHub Release assets instead of the local website domain.
[0.14.4] - 2026-06-29
Changed
- Roadmap: Removed redundant "Planned" badges/texts from the Apps Roadmap settings view.
- Testing: Added UI test
testAppsRoadmapViewto verify the Apps Roadmap page loads and the "Planned" badges do not exist.
Fixed
- Fixed Xcode build warning by removing
Info.plistfrom target membership exceptions list in the Folder Sync configurations, preventing it from being copied as a raw bundle resource. - Testing: Resolved unit test host background pollution by introducing dynamic framework-based test runner detection to disable background fetching and polling timers in
CalendarViewModel,SportsViewModel,StocksViewModel, andAppStateat startup. - Testing: Fixed a timing bug in
testNewCalendarNotchviewLogicDetailed()by setting the test event start date to 20 minutes ago and extending its duration to 3 hours, aligning it with the expected key, duration, and phase assertions. - Testing: Synchronized Combine updates in unit tests by introducing run loop spinning (
spinRunLoop()) to allow asynchronous notifications to deliver before assertions are evaluated. - Testing: Fixed test isolation issues in
testStocksViewModelLogic()by resetting the view model's pinned tickers and index. - Testing: Implemented a global
resetSharedStates()setup & teardown cleanup innotchdockTests.swiftthat runs before and after each test case, resetting all shared singletons (AppState.shared,SportsViewModel.shared,StocksViewModel.shared,TimerViewModel.shared) and flushing Combine main loop dispatches, guaranteeing complete test-to-test execution isolation. - Testing: Fixed
testNotchLogMaxLimit()false positive substring match on 'Log line 1' by checking for exact line suffix match instead of simple substring containment. - Testing: Restored original
switchIntervalvalues properly during test setup and teardown insidetestSingleAppUpdatesLoopingAndSwitching()to avoid local developer config leaks. - Stocks Module: Corrected a state update race condition in
clampPinnedIndexby triggering it synchronously insidepinnedTickers.didSetrather than asynchronously via a Combine subscription, preventingwillSettiming races. - Sports Module: Corrected a date grouping sort order assertion in
testSportsDateGrouping(). - AppState: Wrapped
selectedGameForStatsstate resets inAppStateinsideif !isTestingguards to prevent asynchronous layout updates in the running host application from resetting the view model's stats selection tonilduring test runs.
[0.14.1] - 2026-06-28
Fixed
- Resolved Sparkle update error by introducing a physical
Info.plisttemplate to correctly merge custom Sparkle keys (SUFeedURL,SUPublicEDKey) during the Xcode build process.
[0.14.0] - 2026-06-28
Added
- Privacy Policy: Created a premium, responsive
releases/privacy.htmlpolicy document detailing NotchDock's local-first architecture and third-party data handlers. - Settings: Added a direct link to the hosted Privacy Policy (
https://notchdock.app/privacy.html) on the About screen. - Testing: Updated the
testSettingsLinksunit test to assert the new Privacy Policy URL inSettingsLinks. - Settings: Disclaimer footnote in the About section stating third-party data is public, provided "as-is", and not affiliated with ESPN or Yahoo Finance.
- Settings: Free Public Beta badge and monetization explanation text on the About page.
- Testing: UI test to verify the disclaimer, beta badge, and beta description text displays on the About settings page.
- Sports Module: Premium Game Stats Popup loading experience with stable layout heights, pulsing skeleton loader screens, and staggered progressive fade-in/slide-up animations on data load completion.
Changed
- Sports Module: Added horizontal padding to the stats popup views (statistics, key performers, match events, and skeleton loaders) to keep the contents aligned and visually balanced within the wider popover window.
Fixed
- Sports Module: Resolved an extraneous closing brace compiler error at the top level of the module file.
[0.13.10] - 2026-06-27
Added
- Automated Apple Developer ID code signing, DMG notarization, and verification integration in
release.sh. - Sparkle 2 auto-update framework support and automated update feed (
appcast.xml) generation.
Changed
- Segregated debug and release build sandbox containers using a
.debugbundle identifier suffix for development. - Restructured and renamed
package.shtorelease.shand consolidated release workflow documentation.
[0.13.6] - 2026-06-24
Added
- Sports Module Improvements:
- Pinned Sports live score display with a score-triggered 5-second automatic compact panel expansion.
- Interactive Game Stats popup displaying possession, shots, passing accuracy, and match incidents.
- Automatic dismissal logic for the temporary NotchPanel expansion with hover detection override (canceling collapse on hover).
- Scoreboard fetch resilience with support for date-specific endpoints, result deduplication, and fallback handling when APIs fail.
- Throttling and cooldown policies for sports scoreboard and statistics API requests to handle rate limits.
- Music Module Improvements:
- Dynamic check for music automation permission with clean status indicators.
- Automatic compact view hide timeout after 2 minutes of paused music playback.
- Settings & Diagnostics:
- Dynamic contact support, issue reporting, and user guide links in the Settings sidebar.
- Robust diagnostic logging and export system for troubleshooting Calendar, Reminders, and system state.
- Layout & Rendering Stability:
StableHostingViewandCachedAsyncImagecomponents to completely prevent recursive Auto Layout constraint crashes caused by dynamic image loading.
Changed
- Centralized panel transition and rotation logic into
AppStatewith standardized 15-second rotation intervals.
Fixed
- Sports module scoreboard alignment and column symmetry (linescores, team logos, abbreviations, records).
- Hover reactivation bug preventing the panel from expanding unexpectedly near closed/hidden bounds.
Refactored
- Seeded deterministic mock game stats and incidents to ensure stable, reliable automated tests.
Release v0.14.6
Changelog
All notable changes to this project will be documented in this file.
[0.14.6] - 2026-06-30
Added
- Sports Module: Penalty shootout support for soccer matches, including bracketed shootout scores displayed next to regulation scores in both the expanded card view and the match stats popup.
- Sports Module: Custom robust decoders for
ESPNLinescoreandESPNCompetitorto safely parse shootout goals represented as Double, Int, or String in the JSON responses. - Sports Module: Status detail fallback parser
parseShootoutFromStatusDetailinmakeGameto extract shootout scores from the status string when native linescores are absent.
Changed
- Sports Module: Decoupled shootout scores into dedicated
homeShootoutScore/awayShootoutScoreproperties to ensure period linescores grids and match stats tables remain clean of shootout elements.
Fixed
- Resolved missing application icon in built app by extracting PNG files from
AppIcon.icnsand adding them to the asset catalogAssets.xcassets/AppIcon.appiconset. - Updated
.gitignoreto prevent PNG files inside.xcassetsdirectories from being ignored by Git. - Testing & State Synchronization: Fixed state reset bug where assigning
isExpanded = falseoractiveExtensionIDto their current values in observers redundantly clearedselectedGameForStatsby introducing transition check guards (oldValue && !isExpandedandoldValue != activeExtensionID). - Testing: Guarded the hover-out collapse block in
IslandView.swiftto prevent spurious initial hover events from triggering collapse timers when views first render. - Testing: Silenced real ESPN API data tasks during tests by adding
isTestingchecks insidefetchScores(),fetchPastAndUpcomingGames(), andfetchGameStats(for:)inSportsModule.swift, preventing background network requests from leaking and corrupting mock test states in subsequent tests.
[0.14.5] - 2026-06-30
Added
- Integrated codesigning of the final packaged DMG (
NotchDock.dmg) using the Developer ID Application certificate.
Changed
- Post-processed Sparkle update feed (
appcast.xml) enclosure URLs to point directly to GitHub Release assets instead of the local website domain.
[0.14.4] - 2026-06-29
Changed
- Roadmap: Removed redundant "Planned" badges/texts from the Apps Roadmap settings view.
- Testing: Added UI test
testAppsRoadmapViewto verify the Apps Roadmap page loads and the "Planned" badges do not exist.
Fixed
- Fixed Xcode build warning by removing
Info.plistfrom target membership exceptions list in the Folder Sync configurations, preventing it from being copied as a raw bundle resource. - Testing: Resolved unit test host background pollution by introducing dynamic framework-based test runner detection to disable background fetching and polling timers in
CalendarViewModel,SportsViewModel,StocksViewModel, andAppStateat startup. - Testing: Fixed a timing bug in
testNewCalendarNotchviewLogicDetailed()by setting the test event start date to 20 minutes ago and extending its duration to 3 hours, aligning it with the expected key, duration, and phase assertions. - Testing: Synchronized Combine updates in unit tests by introducing run loop spinning (
spinRunLoop()) to allow asynchronous notifications to deliver before assertions are evaluated. - Testing: Fixed test isolation issues in
testStocksViewModelLogic()by resetting the view model's pinned tickers and index. - Testing: Implemented a global
resetSharedStates()setup & teardown cleanup innotchdockTests.swiftthat runs before and after each test case, resetting all shared singletons (AppState.shared,SportsViewModel.shared,StocksViewModel.shared,TimerViewModel.shared) and flushing Combine main loop dispatches, guaranteeing complete test-to-test execution isolation. - Testing: Fixed
testNotchLogMaxLimit()false positive substring match on 'Log line 1' by checking for exact line suffix match instead of simple substring containment. - Testing: Restored original
switchIntervalvalues properly during test setup and teardown insidetestSingleAppUpdatesLoopingAndSwitching()to avoid local developer config leaks. - Stocks Module: Corrected a state update race condition in
clampPinnedIndexby triggering it synchronously insidepinnedTickers.didSetrather than asynchronously via a Combine subscription, preventingwillSettiming races. - Sports Module: Corrected a date grouping sort order assertion in
testSportsDateGrouping(). - AppState: Wrapped
selectedGameForStatsstate resets inAppStateinsideif !isTestingguards to prevent asynchronous layout updates in the running host application from resetting the view model's stats selection tonilduring test runs.
[0.14.1] - 2026-06-28
Fixed
- Resolved Sparkle update error by introducing a physical
Info.plisttemplate to correctly merge custom Sparkle keys (SUFeedURL,SUPublicEDKey) during the Xcode build process.
[0.14.0] - 2026-06-28
Added
- Privacy Policy: Created a premium, responsive
releases/privacy.htmlpolicy document detailing NotchDock's local-first architecture and third-party data handlers. - Settings: Added a direct link to the hosted Privacy Policy (
https://notchdock.app/privacy.html) on the About screen. - Testing: Updated the
testSettingsLinksunit test to assert the new Privacy Policy URL inSettingsLinks. - Settings: Disclaimer footnote in the About section stating third-party data is public, provided "as-is", and not affiliated with ESPN or Yahoo Finance.
- Settings: Free Public Beta badge and monetization explanation text on the About page.
- Testing: UI test to verify the disclaimer, beta badge, and beta description text displays on the About settings page.
- Sports Module: Premium Game Stats Popup loading experience with stable layout heights, pulsing skeleton loader screens, and staggered progressive fade-in/slide-up animations on data load completion.
Changed
- Sports Module: Added horizontal padding to the stats popup views (statistics, key performers, match events, and skeleton loaders) to keep the contents aligned and visually balanced within the wider popover window.
Fixed
- Sports Module: Resolved an extraneous closing brace compiler error at the top level of the module file.
[0.13.10] - 2026-06-27
Added
- Automated Apple Developer ID code signing, DMG notarization, and verification integration in
release.sh. - Sparkle 2 auto-update framework support and automated update feed (
appcast.xml) generation.
Changed
- Segregated debug and release build sandbox containers using a
.debugbundle identifier suffix for development. - Restructured and renamed
package.shtorelease.shand consolidated release workflow documentation.
[0.13.6] - 2026-06-24
Added
- Sports Module Improvements:
- Pinned Sports live score display with a score-triggered 5-second automatic compact panel expansion.
- Interactive Game Stats popup displaying possession, shots, passing accuracy, and match incidents.
- Automatic dismissal logic for the temporary NotchPanel expansion with hover detection override (canceling collapse on hover).
- Scoreboard fetch resilience with support for date-specific endpoints, result deduplication, and fallback handling when APIs fail.
- Throttling and cooldown policies for sports scoreboard and statistics API requests to handle rate limits.
- Music Module Improvements:
- Dynamic check for music automation permission with clean status indicators.
- Automatic compact view hide timeout after 2 minutes of paused music playback.
- Settings & Diagnostics:
- Dynamic contact support, issue reporting, and user guide links in the Settings sidebar.
- Robust diagnostic logging and export system for troubleshooting Calendar, Reminders, and system state.
- Layout & Rendering Stability:
StableHostingViewandCachedAsyncImagecomponents to completely prevent recursive Auto Layout constraint crashes caused by dynamic image loading.
Changed
- Centralized panel transition and rotation logic into
AppStatewith standardized 15-second rotation intervals.
Fixed
- Sports module scoreboard alignment and column symmetry (linescores, team logos, abbreviations, records).
- Hover reactivation bug preventing the panel from expanding unexpectedly near closed/hidden bounds.
Refactored
- Seeded deterministic mock game stats and incidents to ensure stable, reliable automated tests.