Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
79ec9a57f3
commit
881ac5ad4c
@ -173,13 +173,6 @@ final class RitualStore: RitualStoreProviding {
|
|||||||
refresh()
|
refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Forces a refresh path intended for external sync probes (for example,
|
|
||||||
/// runtimes where remote change callbacks may be delayed while foregrounded).
|
|
||||||
func refreshFromExternalSyncProbe() {
|
|
||||||
modelContext = ModelContext(modelContainer)
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ritualProgress(for ritual: Ritual) -> Double {
|
func ritualProgress(for ritual: Ritual) -> Double {
|
||||||
let habits = ritual.habits
|
let habits = ritual.habits
|
||||||
guard !habits.isEmpty else { return 0 }
|
guard !habits.isEmpty else { return 0 }
|
||||||
|
|||||||
@ -11,7 +11,6 @@ struct RootView: View {
|
|||||||
@State private var analyticsPrewarmTask: Task<Void, Never>?
|
@State private var analyticsPrewarmTask: Task<Void, Never>?
|
||||||
@State private var cloudKitFallbackRefreshTask: Task<Void, Never>?
|
@State private var cloudKitFallbackRefreshTask: Task<Void, Never>?
|
||||||
@State private var aggressiveCloudKitRefreshTasks: [Task<Void, Never>] = []
|
@State private var aggressiveCloudKitRefreshTasks: [Task<Void, Never>] = []
|
||||||
@State private var macSyncSafetyNetTask: Task<Void, Never>?
|
|
||||||
@State private var isForegroundRefreshing = false
|
@State private var isForegroundRefreshing = false
|
||||||
@State private var isResumingFromBackground = false
|
@State private var isResumingFromBackground = false
|
||||||
private let foregroundRefreshMinimumSeconds: TimeInterval = 0.15
|
private let foregroundRefreshMinimumSeconds: TimeInterval = 0.15
|
||||||
@ -137,14 +136,12 @@ struct RootView: View {
|
|||||||
)
|
)
|
||||||
scheduleAggressiveCloudKitRefreshes()
|
scheduleAggressiveCloudKitRefreshes()
|
||||||
scheduleCloudKitFallbackRefresh()
|
scheduleCloudKitFallbackRefresh()
|
||||||
startMacSyncSafetyNetIfNeeded()
|
|
||||||
} else if newPhase == .background {
|
} else if newPhase == .background {
|
||||||
// Prepare for next resume
|
// Prepare for next resume
|
||||||
isResumingFromBackground = true
|
isResumingFromBackground = true
|
||||||
cloudKitFallbackRefreshTask?.cancel()
|
cloudKitFallbackRefreshTask?.cancel()
|
||||||
aggressiveCloudKitRefreshTasks.forEach { $0.cancel() }
|
aggressiveCloudKitRefreshTasks.forEach { $0.cancel() }
|
||||||
aggressiveCloudKitRefreshTasks.removeAll()
|
aggressiveCloudKitRefreshTasks.removeAll()
|
||||||
macSyncSafetyNetTask?.cancel()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: selectedTab) { _, _ in
|
.onChange(of: selectedTab) { _, _ in
|
||||||
@ -159,12 +156,7 @@ struct RootView: View {
|
|||||||
.onOpenURL { url in
|
.onOpenURL { url in
|
||||||
handleURL(url)
|
handleURL(url)
|
||||||
}
|
}
|
||||||
.onAppear {
|
|
||||||
startMacSyncSafetyNetIfNeeded()
|
|
||||||
}
|
|
||||||
.onDisappear {
|
.onDisappear {
|
||||||
macSyncSafetyNetTask?.cancel()
|
|
||||||
macSyncSafetyNetTask = nil
|
|
||||||
aggressiveCloudKitRefreshTasks.forEach { $0.cancel() }
|
aggressiveCloudKitRefreshTasks.forEach { $0.cancel() }
|
||||||
aggressiveCloudKitRefreshTasks.removeAll()
|
aggressiveCloudKitRefreshTasks.removeAll()
|
||||||
}
|
}
|
||||||
@ -250,23 +242,6 @@ struct RootView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// iOS-on-Mac can miss immediate remote push delivery while foregrounded.
|
|
||||||
/// Keep a lightweight active-phase polling safety net for CloudKit merges.
|
|
||||||
private func startMacSyncSafetyNetIfNeeded() {
|
|
||||||
let isMacRuntime = ProcessInfo.processInfo.isiOSAppOnMac || UIDevice.current.userInterfaceIdiom == .mac
|
|
||||||
guard isMacRuntime else { return }
|
|
||||||
guard scenePhase == .active else { return }
|
|
||||||
guard macSyncSafetyNetTask == nil else { return }
|
|
||||||
|
|
||||||
macSyncSafetyNetTask = Task { @MainActor in
|
|
||||||
while !Task.isCancelled {
|
|
||||||
try? await Task.sleep(for: .seconds(3))
|
|
||||||
guard !Task.isCancelled else { return }
|
|
||||||
guard scenePhase == .active else { continue }
|
|
||||||
store.refreshFromExternalSyncProbe()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user