iOS 2.7.3 - Removed Music Integration & Refactoring
This commit is contained in:
@@ -244,7 +244,7 @@ struct AddEditProblemView: View {
|
||||
|
||||
let tempImagePaths = imagePaths.filter { !$0.isEmpty && !imagePaths.contains($0) }
|
||||
for imagePath in tempImagePaths {
|
||||
ImageManager.shared.deleteImage(atPath: imagePath)
|
||||
_ = ImageManager.shared.deleteImage(atPath: imagePath)
|
||||
}
|
||||
|
||||
let newImagePaths = imagePaths.filter { !$0.isEmpty }
|
||||
|
||||
@@ -682,8 +682,8 @@ struct ExportDataView: View {
|
||||
|
||||
private func cleanupTempFile() {
|
||||
if let fileURL = tempFileURL {
|
||||
let logTag = Self.logTag // Capture before entering async closure
|
||||
// Clean up after a delay to ensure sharing is complete
|
||||
let logTag = Self.logTag
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
|
||||
try? FileManager.default.removeItem(at: fileURL)
|
||||
AppLogger.debug(
|
||||
@@ -752,80 +752,84 @@ struct SyncSection: View {
|
||||
}
|
||||
.foregroundColor(.primary)
|
||||
|
||||
if syncService.isConfigured {
|
||||
|
||||
// Sync Now - only show if connected
|
||||
// Sync Now - show with proper opacity when not available
|
||||
Button(action: {
|
||||
if syncService.isConnected {
|
||||
Button(action: {
|
||||
performSync()
|
||||
}) {
|
||||
HStack {
|
||||
if syncService.isSyncing {
|
||||
ProgressView()
|
||||
.scaleEffect(0.8)
|
||||
Text("Syncing...")
|
||||
.foregroundColor(.secondary)
|
||||
} else {
|
||||
Image(systemName: "arrow.triangle.2.circlepath")
|
||||
.foregroundColor(.green)
|
||||
Text("Sync Now")
|
||||
Spacer()
|
||||
if let lastSync = syncService.lastSyncTime {
|
||||
Text(
|
||||
RelativeDateTimeFormatter().localizedString(
|
||||
for: lastSync, relativeTo: Date())
|
||||
)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.disabled(syncService.isSyncing)
|
||||
.foregroundColor(.primary)
|
||||
performSync()
|
||||
}
|
||||
|
||||
// Auto-sync configuration - always visible for testing
|
||||
}) {
|
||||
HStack {
|
||||
VStack(alignment: .leading) {
|
||||
Text("Auto-sync")
|
||||
Text("Sync automatically on app launch and data changes")
|
||||
if syncService.isSyncing {
|
||||
ProgressView()
|
||||
.scaleEffect(0.8)
|
||||
Text("Syncing...")
|
||||
.foregroundColor(.secondary)
|
||||
} else {
|
||||
Image(systemName: "arrow.triangle.2.circlepath")
|
||||
.foregroundColor(syncService.isConnected ? .green : .secondary)
|
||||
Text("Sync Now")
|
||||
.foregroundColor(syncService.isConnected ? .primary : .secondary)
|
||||
Spacer()
|
||||
if let lastSync = syncService.lastSyncTime {
|
||||
Text(
|
||||
RelativeDateTimeFormatter().localizedString(
|
||||
for: lastSync, relativeTo: Date())
|
||||
)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
Toggle(
|
||||
"",
|
||||
isOn: Binding(
|
||||
get: { syncService.isAutoSyncEnabled },
|
||||
set: { syncService.isAutoSyncEnabled = $0 }
|
||||
)
|
||||
)
|
||||
.disabled(!syncService.isConnected)
|
||||
}
|
||||
.foregroundColor(.primary)
|
||||
|
||||
// Disconnect option - only show if connected
|
||||
if syncService.isConnected {
|
||||
Button(action: {
|
||||
showingDisconnectAlert = true
|
||||
}) {
|
||||
HStack {
|
||||
Image(systemName: "power")
|
||||
.foregroundColor(.orange)
|
||||
Text("Disconnect")
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.foregroundColor(.primary)
|
||||
}
|
||||
}
|
||||
.disabled(!syncService.isConnected || syncService.isSyncing)
|
||||
.opacity(syncService.isConfigured ? 1.0 : 0.6)
|
||||
|
||||
if let error = syncService.syncError {
|
||||
// Auto-sync configuration
|
||||
HStack {
|
||||
VStack(alignment: .leading) {
|
||||
Text("Auto-sync")
|
||||
Text("Sync automatically on app launch and data changes")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
Toggle(
|
||||
"",
|
||||
isOn: Binding(
|
||||
get: { syncService.isAutoSyncEnabled },
|
||||
set: { syncService.isAutoSyncEnabled = $0 }
|
||||
)
|
||||
)
|
||||
.disabled(!syncService.isConnected)
|
||||
}
|
||||
.opacity(syncService.isConfigured ? 1.0 : 0.6)
|
||||
|
||||
// Disconnect option
|
||||
Button(action: {
|
||||
if syncService.isConnected {
|
||||
showingDisconnectAlert = true
|
||||
}
|
||||
}) {
|
||||
HStack {
|
||||
Image(systemName: "power")
|
||||
.foregroundColor(syncService.isConnected ? .orange : .secondary)
|
||||
Text("Disconnect")
|
||||
.foregroundColor(syncService.isConnected ? .primary : .secondary)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.disabled(!syncService.isConnected)
|
||||
.opacity(syncService.isConfigured ? 1.0 : 0.6)
|
||||
|
||||
// Error message
|
||||
if let error = syncService.syncError {
|
||||
HStack {
|
||||
Text(error)
|
||||
.font(.caption)
|
||||
.foregroundColor(.red)
|
||||
.padding(.leading, 24)
|
||||
Spacer()
|
||||
}
|
||||
.padding(.leading, 24)
|
||||
}
|
||||
}
|
||||
.alert("Disconnect from Server", isPresented: $showingDisconnectAlert) {
|
||||
@@ -1215,34 +1219,32 @@ struct HealthKitSection: View {
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
} else {
|
||||
Toggle(
|
||||
isOn: Binding(
|
||||
get: { healthKitService.isEnabled },
|
||||
set: { newValue in
|
||||
if newValue && !healthKitService.isAuthorized {
|
||||
isRequestingAuthorization = true
|
||||
Task {
|
||||
do {
|
||||
try await healthKitService.requestAuthorization()
|
||||
await MainActor.run {
|
||||
healthKitService.setEnabled(true)
|
||||
isRequestingAuthorization = false
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
showingAuthorizationError = true
|
||||
isRequestingAuthorization = false
|
||||
}
|
||||
Toggle(isOn: Binding(
|
||||
get: { healthKitService.isEnabled },
|
||||
set: { newValue in
|
||||
if newValue && !healthKitService.isAuthorized {
|
||||
isRequestingAuthorization = true
|
||||
Task {
|
||||
do {
|
||||
try await healthKitService.requestAuthorization()
|
||||
await MainActor.run {
|
||||
healthKitService.setEnabled(true)
|
||||
isRequestingAuthorization = false
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
showingAuthorizationError = true
|
||||
isRequestingAuthorization = false
|
||||
}
|
||||
}
|
||||
} else if newValue {
|
||||
healthKitService.setEnabled(true)
|
||||
} else {
|
||||
healthKitService.setEnabled(false)
|
||||
}
|
||||
} else if newValue {
|
||||
healthKitService.setEnabled(true)
|
||||
} else {
|
||||
healthKitService.setEnabled(false)
|
||||
}
|
||||
)
|
||||
) {
|
||||
}
|
||||
)) {
|
||||
HStack {
|
||||
Image(systemName: "heart.fill")
|
||||
.foregroundColor(.red)
|
||||
@@ -1250,14 +1252,15 @@ struct HealthKitSection: View {
|
||||
}
|
||||
}
|
||||
.disabled(isRequestingAuthorization)
|
||||
|
||||
|
||||
if healthKitService.isEnabled {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(
|
||||
"Climbing sessions will be recorded as workouts in Apple Health"
|
||||
)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Climbing sessions will be recorded as workouts in Apple Health")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user