1
0
forked from firka/firka

Add auto-refresh and duplicate-call guard

Watch app: add Combine import, scenePhase tracking, a periodic timer and a 10-minute freshness threshold to auto-refresh data when the app becomes active or data becomes stale. Move refresh logic into onChange/onReceive handlers and add shouldAutoRefresh to avoid unnecessary refreshes; removed an immediate proactive token refresh in ContentView. DataStore.refreshAll now early-returns if a refresh is already in progress and logs the skip to prevent duplicate concurrent refreshes.
This commit is contained in:
Horváth Gergely
2026-02-09 18:23:55 +01:00
committed by 4831c0
parent dbf0d18e5c
commit a071cafacd
2 changed files with 38 additions and 2 deletions

View File

@@ -1,10 +1,16 @@
import SwiftUI
import WatchConnectivity
internal import Combine
struct ContentView: View {
var dataStore = DataStore.shared
@State private var selectedTab = 0
@State private var isRequestingToken = false
@Environment(\.scenePhase) private var scenePhase
private let staleCheckTimer = Timer.publish(every: 30, on: .main, in: .common).autoconnect()
private let autoRefreshThreshold: TimeInterval = 10 * 60
var body: some View {
Group {
@@ -41,8 +47,6 @@ struct ContentView: View {
dataStore.checkTokenState()
dataStore.loadFromCache()
if dataStore.hasToken {
await dataStore.refreshTokenProactively()
await dataStore.refreshAll()
if (dataStore.error == "token_expired" || dataStore.error == "no_token") && !dataStore.recoveryAttempted {
@@ -55,6 +59,33 @@ struct ContentView: View {
requestToken()
}
}
.onChange(of: scenePhase) { oldPhase, newPhase in
if newPhase == .active && oldPhase != .active {
if shouldAutoRefresh {
print("[Watch] App came to foreground, data is stale (>10 min), refreshing...")
Task {
await dataStore.refreshAll()
}
} else {
print("[Watch] App came to foreground, data is fresh (<10 min), skipping refresh")
}
}
}
.onReceive(staleCheckTimer) { _ in
if scenePhase == .active && shouldAutoRefresh && !dataStore.isLoading {
print("[Watch] Data became stale (>10 min), auto-refreshing...")
Task {
await dataStore.refreshAll()
}
}
}
}
private var shouldAutoRefresh: Bool {
guard dataStore.hasToken else { return false }
guard let lastUpdated = dataStore.lastUpdated else { return true }
let elapsed = Date().timeIntervalSince(lastUpdated)
return elapsed >= autoRefreshThreshold
}
private func requestToken() {

View File

@@ -292,6 +292,11 @@ class DataStore {
// MARK: - Data Refresh
func refreshAll() async {
guard !isLoading else {
print("[Watch] DataStore.refreshAll() already in progress, skipping duplicate call")
return
}
print("[Watch] DataStore.refreshAll() called")
isLoading = true
error = nil