Import/export fixes, icon, and graphing
This commit is contained in:
@@ -8,31 +8,53 @@
|
||||
import SwiftUI
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
enum SheetType {
|
||||
case export(Data)
|
||||
case importData
|
||||
}
|
||||
|
||||
struct SettingsView: View {
|
||||
@EnvironmentObject var dataManager: ClimbingDataManager
|
||||
@State private var showingResetAlert = false
|
||||
@State private var showingExportSheet = false
|
||||
@State private var showingImportSheet = false
|
||||
@State private var exportData: Data?
|
||||
@State private var activeSheet: SheetType?
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
List {
|
||||
DataManagementSection()
|
||||
List {
|
||||
DataManagementSection(
|
||||
activeSheet: $activeSheet
|
||||
)
|
||||
|
||||
AppInfoSection()
|
||||
AppInfoSection()
|
||||
}
|
||||
.navigationTitle("Settings")
|
||||
.sheet(
|
||||
item: Binding<SheetType?>(
|
||||
get: { activeSheet },
|
||||
set: { activeSheet = $0 }
|
||||
)
|
||||
) { sheetType in
|
||||
switch sheetType {
|
||||
case .export(let data):
|
||||
ExportDataView(data: data)
|
||||
case .importData:
|
||||
ImportDataView()
|
||||
}
|
||||
.navigationTitle("Settings")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SheetType: Identifiable {
|
||||
var id: String {
|
||||
switch self {
|
||||
case .export: return "export"
|
||||
case .importData: return "import"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DataManagementSection: View {
|
||||
@EnvironmentObject var dataManager: ClimbingDataManager
|
||||
@Binding var activeSheet: SheetType?
|
||||
@State private var showingResetAlert = false
|
||||
@State private var showingExportSheet = false
|
||||
@State private var showingImportSheet = false
|
||||
@State private var exportData: Data?
|
||||
@State private var isExporting = false
|
||||
|
||||
var body: some View {
|
||||
@@ -60,7 +82,7 @@ struct DataManagementSection: View {
|
||||
|
||||
// Import Data
|
||||
Button(action: {
|
||||
showingImportSheet = true
|
||||
activeSheet = .importData
|
||||
}) {
|
||||
HStack {
|
||||
Image(systemName: "square.and.arrow.down")
|
||||
@@ -94,38 +116,15 @@ struct DataManagementSection: View {
|
||||
"Are you sure you want to reset all data? This will permanently delete:\n\n• All gyms and their information\n• All problems and their images\n• All climbing sessions\n• All attempts and progress data\n\nThis action cannot be undone. Consider exporting your data first."
|
||||
)
|
||||
}
|
||||
.sheet(isPresented: $showingExportSheet) {
|
||||
if let data = exportData {
|
||||
ExportDataView(data: data)
|
||||
} else {
|
||||
Text("No export data available")
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showingImportSheet) {
|
||||
ImportDataView()
|
||||
}
|
||||
}
|
||||
|
||||
private func exportDataAsync() {
|
||||
isExporting = true
|
||||
|
||||
Task {
|
||||
let data = await withCheckedContinuation { continuation in
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
let result = dataManager.exportData()
|
||||
continuation.resume(returning: result)
|
||||
}
|
||||
}
|
||||
|
||||
await MainActor.run {
|
||||
isExporting = false
|
||||
if let data = data {
|
||||
exportData = data
|
||||
showingExportSheet = true
|
||||
} else {
|
||||
// Error message should already be set by dataManager
|
||||
exportData = nil
|
||||
}
|
||||
let data = await MainActor.run { dataManager.exportData() }
|
||||
isExporting = false
|
||||
if let data = data {
|
||||
activeSheet = .export(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,8 +142,9 @@ struct AppInfoSection: View {
|
||||
var body: some View {
|
||||
Section("App Information") {
|
||||
HStack {
|
||||
Image(systemName: "mountain.2.fill")
|
||||
.foregroundColor(.blue)
|
||||
Image("MountainsIcon")
|
||||
.resizable()
|
||||
.frame(width: 24, height: 24)
|
||||
VStack(alignment: .leading) {
|
||||
Text("OpenClimb")
|
||||
.font(.headline)
|
||||
@@ -163,15 +163,6 @@ struct AppInfoSection: View {
|
||||
Text("\(appVersion) (\(buildNumber))")
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
HStack {
|
||||
Image(systemName: "person.fill")
|
||||
.foregroundColor(.blue)
|
||||
Text("Developer")
|
||||
Spacer()
|
||||
Text("OpenClimb Team")
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,7 +194,7 @@ struct ExportDataView: View {
|
||||
item: fileURL,
|
||||
preview: SharePreview(
|
||||
"OpenClimb Data Export",
|
||||
image: Image(systemName: "mountain.2.fill"))
|
||||
image: Image("MountainsIcon"))
|
||||
) {
|
||||
Label("Share Data", systemImage: "square.and.arrow.up")
|
||||
.font(.headline)
|
||||
@@ -324,13 +315,6 @@ struct ImportDataView: View {
|
||||
Text("Import climbing data from a previously exported ZIP file.")
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
Text(
|
||||
"Fully compatible with Android exports - identical ZIP format with images."
|
||||
)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.blue)
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
Text("⚠️ Warning: This will replace all current data!")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.red)
|
||||
@@ -423,7 +407,10 @@ struct ImportDataView: View {
|
||||
|
||||
await MainActor.run {
|
||||
isImporting = false
|
||||
dismiss()
|
||||
// Auto-close after successful import
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
|
||||
Reference in New Issue
Block a user