[iOS & Android] iOS 1.2.4 & Android 1.7.3

This commit is contained in:
2025-10-06 11:54:36 -06:00
parent acf487db93
commit c10fa48bf5
10 changed files with 245 additions and 54 deletions

View File

@@ -378,7 +378,6 @@ class SyncService: ObservableObject {
print("Renamed local image: \(filename) -> \(consistentFilename)")
// Update problem's image path in memory for consistency
// Note: This would require updating the problem in the data manager
} catch {
print("Failed to rename local image, using original: \(error)")
}
@@ -397,12 +396,24 @@ class SyncService: ObservableObject {
private func createBackupFromDataManager(_ dataManager: ClimbingDataManager) -> ClimbDataBackup
{
// Filter out active sessions and their attempts from sync
let completedSessions = dataManager.sessions.filter { $0.status != .active }
let activeSessionIds = Set(
dataManager.sessions.filter { $0.status == .active }.map { $0.id })
let completedAttempts = dataManager.attempts.filter {
!activeSessionIds.contains($0.sessionId)
}
print(
"iOS SYNC: Excluding \(dataManager.sessions.count - completedSessions.count) active sessions and \(dataManager.attempts.count - completedAttempts.count) active session attempts from sync"
)
return ClimbDataBackup(
exportedAt: DataStateManager.shared.getLastModified(),
gyms: dataManager.gyms.map { BackupGym(from: $0) },
problems: dataManager.problems.map { BackupProblem(from: $0) },
sessions: dataManager.sessions.map { BackupClimbSession(from: $0) },
attempts: dataManager.attempts.map { BackupAttempt(from: $0) }
sessions: completedSessions.map { BackupClimbSession(from: $0) },
attempts: completedAttempts.map { BackupAttempt(from: $0) }
)
}
@@ -412,6 +423,17 @@ class SyncService: ObservableObject {
) throws {
do {
// Store active sessions and their attempts before import
let activeSessions = dataManager.sessions.filter { $0.status == .active }
let activeSessionIds = Set(activeSessions.map { $0.id })
let activeAttempts = dataManager.attempts.filter {
activeSessionIds.contains($0.sessionId)
}
print(
"iOS IMPORT: Preserving \(activeSessions.count) active sessions and \(activeAttempts.count) active attempts during import"
)
// Update problem image paths to point to downloaded images
let updatedBackup: ClimbDataBackup
if !imagePathMapping.isEmpty {
@@ -456,6 +478,24 @@ class SyncService: ObservableObject {
// Use existing import method which properly handles data restoration
try dataManager.importData(from: zipData, showSuccessMessage: false)
// Restore active sessions and their attempts after import
for session in activeSessions {
print("iOS IMPORT: Restoring active session: \(session.id)")
dataManager.sessions.append(session)
if session.id == dataManager.activeSession?.id {
dataManager.activeSession = session
}
}
for attempt in activeAttempts {
dataManager.attempts.append(attempt)
}
// Save restored data
dataManager.saveSessions()
dataManager.saveAttempts()
dataManager.saveActiveSession()
// Update local data state to match imported data timestamp
DataStateManager.shared.setLastModified(backup.exportedAt)
print("Data state synchronized to imported timestamp: \(backup.exportedAt)")

View File

@@ -158,7 +158,7 @@ class ClimbingDataManager: ObservableObject {
}
}
private func saveSessions() {
internal func saveSessions() {
if let data = try? encoder.encode(sessions) {
userDefaults.set(data, forKey: Keys.sessions)
// Share with widget - convert to widget format
@@ -176,7 +176,7 @@ class ClimbingDataManager: ObservableObject {
}
}
private func saveAttempts() {
internal func saveAttempts() {
if let data = try? encoder.encode(attempts) {
userDefaults.set(data, forKey: Keys.attempts)
// Share with widget - convert to widget format
@@ -197,7 +197,7 @@ class ClimbingDataManager: ObservableObject {
}
}
private func saveActiveSession() {
internal func saveActiveSession() {
if let activeSession = activeSession,
let data = try? encoder.encode(activeSession)
{
@@ -326,9 +326,6 @@ class ClimbingDataManager: ObservableObject {
saveSessions()
DataStateManager.shared.updateDataState()
successMessage = "Session started successfully"
clearMessageAfterDelay()
// MARK: - Start Live Activity for new session
if let gym = gym(withId: gymId) {
Task {
@@ -336,9 +333,6 @@ class ClimbingDataManager: ObservableObject {
for: newSession, gymName: gym.name)
}
}
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
func endSession(_ sessionId: UUID) {
@@ -356,8 +350,6 @@ class ClimbingDataManager: ObservableObject {
saveActiveSession()
saveSessions()
DataStateManager.shared.updateDataState()
successMessage = "Session completed successfully"
clearMessageAfterDelay()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
@@ -380,14 +372,14 @@ class ClimbingDataManager: ObservableObject {
saveSessions()
DataStateManager.shared.updateDataState()
successMessage = "Session updated successfully"
clearMessageAfterDelay()
// Update Live Activity when session is updated
updateLiveActivityForActiveSession()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
// Only trigger sync if session is completed
if session.status != .active {
syncService.triggerAutoSync(dataManager: self)
}
}
}
@@ -406,8 +398,6 @@ class ClimbingDataManager: ObservableObject {
sessions.removeAll { $0.id == session.id }
saveSessions()
DataStateManager.shared.updateDataState()
successMessage = "Session deleted successfully"
clearMessageAfterDelay()
// Update Live Activity when session is deleted
updateLiveActivityForActiveSession()
@@ -435,12 +425,6 @@ class ClimbingDataManager: ObservableObject {
saveAttempts()
DataStateManager.shared.updateDataState()
successMessage = "Attempt logged successfully"
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
clearMessageAfterDelay()
// Update Live Activity when new attempt is added
updateLiveActivityForActiveSession()
}
@@ -450,14 +434,9 @@ class ClimbingDataManager: ObservableObject {
attempts[index] = attempt
saveAttempts()
DataStateManager.shared.updateDataState()
successMessage = "Attempt updated successfully"
clearMessageAfterDelay()
// Update Live Activity when attempt is updated
updateLiveActivityForActiveSession()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
}
@@ -465,14 +444,9 @@ class ClimbingDataManager: ObservableObject {
attempts.removeAll { $0.id == attempt.id }
saveAttempts()
DataStateManager.shared.updateDataState()
successMessage = "Attempt deleted successfully"
clearMessageAfterDelay()
// Update Live Activity when attempt is deleted
updateLiveActivityForActiveSession()
// Trigger auto-sync if enabled
syncService.triggerAutoSync(dataManager: self)
}
func attempts(forSession sessionId: UUID) -> [Attempt] {

View File

@@ -131,7 +131,6 @@ final class LiveActivityManager {
)
await currentActivity.update(.init(state: updatedContentState, staleDate: nil))
print("Live Activity updated successfully")
}
/// Call this when a ClimbSession ends to end the Live Activity