iOS 1.2.1 - Better auto sync and sync indicator

This commit is contained in:
2025-09-29 13:47:50 -06:00
parent c3f847e1e6
commit b930d5ce96
15 changed files with 185 additions and 220 deletions

View File

@@ -32,6 +32,9 @@ class ClimbingDataManager: ObservableObject {
// Sync service for automatic syncing
let syncService = SyncService()
// Published property to propagate sync state changes
@Published var isSyncing = false
private enum Keys {
static let gyms = "openclimb_gyms"
static let problems = "openclimb_problems"
@@ -67,6 +70,10 @@ class ClimbingDataManager: ObservableObject {
migrateImagePaths()
setupLiveActivityNotifications()
// Keep our published isSyncing in sync with syncService.isSyncing
syncService.$isSyncing
.assign(to: &$isSyncing)
Task {
try? await Task.sleep(nanoseconds: 2_000_000_000)
await performImageMaintenance()
@@ -206,6 +213,9 @@ class ClimbingDataManager: ObservableObject {
DataStateManager.shared.updateDataState()
successMessage = "Gym added successfully"
clearMessageAfterDelay()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
func updateGym(_ gym: Gym) {
@@ -215,6 +225,9 @@ class ClimbingDataManager: ObservableObject {
DataStateManager.shared.updateDataState()
successMessage = "Gym updated successfully"
clearMessageAfterDelay()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
}
@@ -237,6 +250,9 @@ class ClimbingDataManager: ObservableObject {
DataStateManager.shared.updateDataState()
successMessage = "Gym deleted successfully"
clearMessageAfterDelay()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
func gym(withId id: UUID) -> Gym? {
@@ -261,6 +277,9 @@ class ClimbingDataManager: ObservableObject {
DataStateManager.shared.updateDataState()
successMessage = "Problem updated successfully"
clearMessageAfterDelay()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
}
@@ -276,6 +295,9 @@ class ClimbingDataManager: ObservableObject {
problems.removeAll { $0.id == problem.id }
saveProblems()
DataStateManager.shared.updateDataState()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
func problem(withId id: UUID) -> Problem? {
@@ -291,7 +313,7 @@ class ClimbingDataManager: ObservableObject {
}
func startSession(gymId: UUID, notes: String? = nil) {
// End any currently active session
if let currentActive = activeSession {
endSession(currentActive.id)
}
@@ -314,6 +336,9 @@ class ClimbingDataManager: ObservableObject {
for: newSession, gymName: gym.name)
}
}
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
func endSession(_ sessionId: UUID) {
@@ -358,8 +383,11 @@ class ClimbingDataManager: ObservableObject {
successMessage = "Session updated successfully"
clearMessageAfterDelay()
// Update Live Activity when session updates
// Update Live Activity when session is updated
updateLiveActivityForActiveSession()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
}
@@ -368,7 +396,7 @@ class ClimbingDataManager: ObservableObject {
attempts.removeAll { $0.sessionId == session.id }
saveAttempts()
// Remove from active session if it's the current one
// If this is the active session, clear it
if activeSession?.id == session.id {
activeSession = nil
saveActiveSession()
@@ -380,6 +408,12 @@ class ClimbingDataManager: ObservableObject {
DataStateManager.shared.updateDataState()
successMessage = "Session deleted successfully"
clearMessageAfterDelay()
// Update Live Activity when session is deleted
updateLiveActivityForActiveSession()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
func session(withId id: UUID) -> ClimbSession? {
@@ -421,6 +455,9 @@ class ClimbingDataManager: ObservableObject {
// Update Live Activity when attempt is updated
updateLiveActivityForActiveSession()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
}
@@ -433,6 +470,9 @@ class ClimbingDataManager: ObservableObject {
// Update Live Activity when attempt is deleted
updateLiveActivityForActiveSession()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
func attempts(forSession sessionId: UUID) -> [Attempt] {
@@ -476,7 +516,7 @@ class ClimbingDataManager: ObservableObject {
return gym(withId: mostUsedGymId)
}
func resetAllData() {
func resetAllData(showSuccessMessage: Bool = true) {
gyms.removeAll()
problems.removeAll()
sessions.removeAll()
@@ -490,8 +530,11 @@ class ClimbingDataManager: ObservableObject {
userDefaults.removeObject(forKey: Keys.activeSession)
DataStateManager.shared.reset()
successMessage = "All data has been reset"
clearMessageAfterDelay()
if showSuccessMessage {
successMessage = "All data has been reset"
clearMessageAfterDelay()
}
}
func exportData() -> Data? {
@@ -530,7 +573,7 @@ class ClimbingDataManager: ObservableObject {
}
}
func importData(from data: Data) throws {
func importData(from data: Data, showSuccessMessage: Bool = true) throws {
do {
let importResult = try ZipUtils.extractImportZip(data: data)
@@ -566,7 +609,7 @@ class ClimbingDataManager: ObservableObject {
try validateImportData(importData)
resetAllData()
resetAllData(showSuccessMessage: showSuccessMessage)
let updatedProblems = updateProblemImagePaths(
problems: importData.problems,
@@ -586,9 +629,11 @@ class ClimbingDataManager: ObservableObject {
// Update data state to current time since we just imported new data
DataStateManager.shared.updateDataState()
successMessage =
"Data imported successfully with \(importResult.imagePathMapping.count) images"
clearMessageAfterDelay()
if showSuccessMessage {
successMessage =
"Data imported successfully with \(importResult.imagePathMapping.count) images"
clearMessageAfterDelay()
}
} catch {
setError("Import failed: \(error.localizedDescription)")
throw error