[iOS & Android] iOS 1.2.5 & Android 1.7.4 [Sync] Sync 1.1.0
All checks were successful
OpenClimb Docker Deploy / build-and-push (push) Successful in 2m25s

This commit is contained in:
2025-10-06 17:38:19 -06:00
parent c10fa48bf5
commit a19ff8ef66
12 changed files with 583 additions and 83 deletions

View File

@@ -41,6 +41,7 @@ class ClimbingDataManager: ObservableObject {
static let sessions = "openclimb_sessions"
static let attempts = "openclimb_attempts"
static let activeSession = "openclimb_active_session"
static let deletedItems = "openclimb_deleted_items"
}
// Widget data models
@@ -137,7 +138,7 @@ class ClimbingDataManager: ObservableObject {
}
}
private func saveGyms() {
internal func saveGyms() {
if let data = try? encoder.encode(gyms) {
userDefaults.set(data, forKey: Keys.gyms)
// Share with widget - convert to widget format
@@ -150,7 +151,7 @@ class ClimbingDataManager: ObservableObject {
}
}
private func saveProblems() {
internal func saveProblems() {
if let data = try? encoder.encode(problems) {
userDefaults.set(data, forKey: Keys.problems)
// Share with widget
@@ -246,6 +247,7 @@ class ClimbingDataManager: ObservableObject {
// Delete the gym
gyms.removeAll { $0.id == gym.id }
trackDeletion(itemId: gym.id.uuidString, itemType: "gym")
saveGyms()
DataStateManager.shared.updateDataState()
successMessage = "Gym deleted successfully"
@@ -293,6 +295,7 @@ class ClimbingDataManager: ObservableObject {
// Delete the problem
problems.removeAll { $0.id == problem.id }
trackDeletion(itemId: problem.id.uuidString, itemType: "problem")
saveProblems()
DataStateManager.shared.updateDataState()
@@ -396,6 +399,7 @@ class ClimbingDataManager: ObservableObject {
// Delete the session
sessions.removeAll { $0.id == session.id }
trackDeletion(itemId: session.id.uuidString, itemType: "session")
saveSessions()
DataStateManager.shared.updateDataState()
@@ -442,17 +446,50 @@ class ClimbingDataManager: ObservableObject {
func deleteAttempt(_ attempt: Attempt) {
attempts.removeAll { $0.id == attempt.id }
trackDeletion(itemId: attempt.id.uuidString, itemType: "attempt")
saveAttempts()
DataStateManager.shared.updateDataState()
// Update Live Activity when attempt is deleted
updateLiveActivityForActiveSession()
// Note: Attempts for active sessions are not synced until session is completed
}
func attempts(forSession sessionId: UUID) -> [Attempt] {
return attempts.filter { $0.sessionId == sessionId }.sorted { $0.timestamp < $1.timestamp }
}
// MARK: - Deletion Tracking
private func trackDeletion(itemId: String, itemType: String) {
let deletion = DeletedItem(
id: itemId,
type: itemType,
deletedAt: ISO8601DateFormatter().string(from: Date())
)
var currentDeletions = getDeletedItems()
currentDeletions.append(deletion)
if let data = try? encoder.encode(currentDeletions) {
userDefaults.set(data, forKey: Keys.deletedItems)
}
}
func getDeletedItems() -> [DeletedItem] {
guard let data = userDefaults.data(forKey: Keys.deletedItems),
let deletions = try? decoder.decode([DeletedItem].self, from: data)
else {
return []
}
return deletions
}
func clearDeletedItems() {
userDefaults.removeObject(forKey: Keys.deletedItems)
}
func attempts(forProblem problemId: UUID) -> [Attempt] {
return attempts.filter { $0.problemId == problemId }.sorted { $0.timestamp > $1.timestamp }
}