Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
319bad27a1
commit
938b2bc033
@ -9,6 +9,7 @@ struct RootView: View {
|
|||||||
@State private var selectedTab: RootTab
|
@State private var selectedTab: RootTab
|
||||||
@State private var analyticsPrewarmTask: Task<Void, Never>?
|
@State private var analyticsPrewarmTask: Task<Void, Never>?
|
||||||
@State private var isForegroundRefreshing = false
|
@State private var isForegroundRefreshing = false
|
||||||
|
@State private var isResumingFromBackground = true
|
||||||
private let foregroundRefreshMinimumSeconds: TimeInterval = 0.15
|
private let foregroundRefreshMinimumSeconds: TimeInterval = 0.15
|
||||||
private let debugForegroundRefreshMinimumSeconds: TimeInterval = 0.8
|
private let debugForegroundRefreshMinimumSeconds: TimeInterval = 0.8
|
||||||
private let debugForegroundRefreshKey = "debugForegroundRefreshNextForeground"
|
private let debugForegroundRefreshKey = "debugForegroundRefreshNextForeground"
|
||||||
@ -38,6 +39,10 @@ struct RootView: View {
|
|||||||
self.settingsStore = settingsStore
|
self.settingsStore = settingsStore
|
||||||
self.categoryStore = categoryStore
|
self.categoryStore = categoryStore
|
||||||
self._selectedTab = State(initialValue: initialTab)
|
self._selectedTab = State(initialValue: initialTab)
|
||||||
|
|
||||||
|
// Update time-of-day immediately before any views render.
|
||||||
|
// This ensures correct rituals are shown when app resumes from background.
|
||||||
|
store.updateCurrentTimeOfDay()
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@ -46,6 +51,7 @@ struct RootView: View {
|
|||||||
Tab(String(localized: "Today"), systemImage: "sun.max.fill", value: RootTab.today) {
|
Tab(String(localized: "Today"), systemImage: "sun.max.fill", value: RootTab.today) {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
TodayView(store: store, categoryStore: categoryStore)
|
TodayView(store: store, categoryStore: categoryStore)
|
||||||
|
.id(store.currentTimeOfDay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,10 +89,17 @@ struct RootView: View {
|
|||||||
}
|
}
|
||||||
.transition(.opacity)
|
.transition(.opacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Brief overlay when resuming to hide stale snapshot
|
||||||
|
if isResumingFromBackground {
|
||||||
|
AppSurface.primary
|
||||||
|
.ignoresSafeArea()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.tint(AppAccent.primary)
|
.tint(AppAccent.primary)
|
||||||
.background(AppSurface.primary.ignoresSafeArea())
|
.background(AppSurface.primary.ignoresSafeArea())
|
||||||
.animation(.easeInOut(duration: 0.12), value: isForegroundRefreshing)
|
.animation(.easeInOut(duration: 0.12), value: isForegroundRefreshing)
|
||||||
|
.animation(.easeIn(duration: 0.05), value: isResumingFromBackground)
|
||||||
.onChange(of: scenePhase) { _, newPhase in
|
.onChange(of: scenePhase) { _, newPhase in
|
||||||
if newPhase == .active {
|
if newPhase == .active {
|
||||||
store.reminderScheduler.clearBadge()
|
store.reminderScheduler.clearBadge()
|
||||||
@ -95,6 +108,12 @@ struct RootView: View {
|
|||||||
// This ensures the correct rituals are shown without a visible transition.
|
// This ensures the correct rituals are shown without a visible transition.
|
||||||
store.updateCurrentTimeOfDay()
|
store.updateCurrentTimeOfDay()
|
||||||
|
|
||||||
|
// Hide resume overlay after a tiny delay to allow view to update
|
||||||
|
Task { @MainActor in
|
||||||
|
try? await Task.sleep(for: .milliseconds(50))
|
||||||
|
isResumingFromBackground = false
|
||||||
|
}
|
||||||
|
|
||||||
let useDebugOverlay = UserDefaults.standard.bool(forKey: debugForegroundRefreshKey)
|
let useDebugOverlay = UserDefaults.standard.bool(forKey: debugForegroundRefreshKey)
|
||||||
if useDebugOverlay {
|
if useDebugOverlay {
|
||||||
UserDefaults.standard.set(false, forKey: debugForegroundRefreshKey)
|
UserDefaults.standard.set(false, forKey: debugForegroundRefreshKey)
|
||||||
@ -106,6 +125,9 @@ struct RootView: View {
|
|||||||
showOverlay: useDebugOverlay,
|
showOverlay: useDebugOverlay,
|
||||||
minimumSeconds: useDebugOverlay ? debugForegroundRefreshMinimumSeconds : foregroundRefreshMinimumSeconds
|
minimumSeconds: useDebugOverlay ? debugForegroundRefreshMinimumSeconds : foregroundRefreshMinimumSeconds
|
||||||
)
|
)
|
||||||
|
} else if newPhase == .background {
|
||||||
|
// Prepare for next resume
|
||||||
|
isResumingFromBackground = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: selectedTab) { _, _ in
|
.onChange(of: selectedTab) { _, _ in
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user