From 25d7eb906ce546306c13309e2522430b5642255c Mon Sep 17 00:00:00 2001 From: Oleksandr Riasnyi Date: Fri, 7 Aug 2026 22:33:54 +0300 Subject: [PATCH] Fix timer countdown and island pill position - Timer/media/weather objectWillChange now always forwarded (not gated by isOpen), so the Dynamic Island updates in real time - Pill shifted further right with padding to clear notch corner --- Sources/VoidBar/Model/NotchViewModel.swift | 18 +++++++++++++++--- Sources/VoidBar/UI/DynamicIslandView.swift | 5 ++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Sources/VoidBar/Model/NotchViewModel.swift b/Sources/VoidBar/Model/NotchViewModel.swift index 62b2de9..ec3b916 100644 --- a/Sources/VoidBar/Model/NotchViewModel.swift +++ b/Sources/VoidBar/Model/NotchViewModel.swift @@ -135,14 +135,26 @@ final class NotchViewModel: ObservableObject { // first letter typed is also the last one that lands. Their panes // observe them directly, and the header counter refreshes anyway, // because the list is only ever re-read on the way into the tab. + // Stores that power the Dynamic Island must always forward their + // changes — the island is visible when the panel is *closed*. for child in [ media.objectWillChange, + timer.objectWillChange, + weather.objectWillChange + ] { + child + .sink { [weak self] _ in + self?.objectWillChange.send() + } + .store(in: &cancellables) + } + + // The remaining stores only matter when the panel is open. + for child in [ shelf.objectWillChange, clipboard.objectWillChange, calendar.objectWillChange, - timer.objectWillChange, - monitor.objectWillChange, - weather.objectWillChange + monitor.objectWillChange ] { child .sink { [weak self] _ in diff --git a/Sources/VoidBar/UI/DynamicIslandView.swift b/Sources/VoidBar/UI/DynamicIslandView.swift index c2f44ea..013ed06 100644 --- a/Sources/VoidBar/UI/DynamicIslandView.swift +++ b/Sources/VoidBar/UI/DynamicIslandView.swift @@ -22,7 +22,10 @@ struct DynamicIslandView: View { )) } } - .frame(width: notchWidth + 120, height: notchHeight) + // Extra width so the pill can sit fully outside the notch area. + // The 6pt trailing padding keeps it clear of the notch's rounded corner. + .padding(.trailing, 6) + .frame(width: notchWidth + 140, height: notchHeight) .animation(.spring(response: 0.35, dampingFraction: 0.8), value: pillKind) }