96 lines
2.8 KiB
Swift
96 lines
2.8 KiB
Swift
import Foundation
|
|
import SwiftUI
|
|
import UniformTypeIdentifiers
|
|
|
|
@MainActor
|
|
final class ImportFlowViewModel: ObservableObject {
|
|
@Published var template = MoodwellStateOfMindTemplate.template
|
|
@Published var entries: [MoodwellEntry] = []
|
|
@Published var sourceKeys: [String] = []
|
|
@Published var mapping = MoodwellStateOfMindTemplate.defaultMapping
|
|
@Published var moodValenceScale: [Int: Double] = [1: -0.8, 2: -0.25, 3: 0.3, 4: 0.8]
|
|
@Published var dryRunResult: DryRunResult?
|
|
@Published var isImporting = false
|
|
@Published var statusMessage = ""
|
|
@Published var errorMessage: String?
|
|
|
|
let supportedContentTypes: [UTType] = [.json]
|
|
|
|
private let healthKitService = HealthKitService()
|
|
|
|
init() {
|
|
loadBundledSample()
|
|
}
|
|
|
|
func loadBundledSample() {
|
|
guard let url = Bundle.main.url(forResource: "MoodwellData", withExtension: "json") else {
|
|
errorMessage = String(localized: "error.sample.missing")
|
|
return
|
|
}
|
|
loadFile(from: url)
|
|
}
|
|
|
|
func loadFile(from url: URL) {
|
|
do {
|
|
let data = try Data(contentsOf: url)
|
|
let payload = try JSONDecoder().decode(MoodwellPayload.self, from: data)
|
|
entries = payload.mymoods
|
|
if let firstEntry = payload.mymoods.first {
|
|
sourceKeys = Array(firstEntry.sourceDictionary.keys).sorted()
|
|
} else {
|
|
sourceKeys = []
|
|
}
|
|
dryRunResult = nil
|
|
statusMessage = String.localizedStringWithFormat(
|
|
NSLocalizedString("status.loaded", comment: ""),
|
|
entries.count
|
|
)
|
|
errorMessage = nil
|
|
} catch {
|
|
errorMessage = String(localized: "error.load.file") + " \(error.localizedDescription)"
|
|
}
|
|
}
|
|
|
|
func runDryRun() {
|
|
let result = MoodwellStateOfMindTemplate.makeDrafts(entries: entries, mapping: mapping, moodValenceScale: moodValenceScale)
|
|
dryRunResult = result
|
|
if result.errors.isEmpty {
|
|
statusMessage = String.localizedStringWithFormat(
|
|
NSLocalizedString("status.dryrun.success", comment: ""),
|
|
result.drafts.count
|
|
)
|
|
} else {
|
|
statusMessage = String.localizedStringWithFormat(
|
|
NSLocalizedString("status.dryrun.withErrors", comment: ""),
|
|
result.errors.count
|
|
)
|
|
}
|
|
}
|
|
|
|
func commitImport() async {
|
|
guard let dryRunResult else {
|
|
errorMessage = String(localized: "error.dryrun.required")
|
|
return
|
|
}
|
|
guard dryRunResult.errors.isEmpty else {
|
|
errorMessage = String(localized: "error.dryrun.fix")
|
|
return
|
|
}
|
|
|
|
isImporting = true
|
|
defer { isImporting = false }
|
|
|
|
do {
|
|
try await healthKitService.requestWriteAccessForStateOfMind()
|
|
try await healthKitService.save(dryRunResult.drafts)
|
|
statusMessage = String.localizedStringWithFormat(
|
|
NSLocalizedString("status.import.success", comment: ""),
|
|
dryRunResult.drafts.count
|
|
)
|
|
errorMessage = nil
|
|
} catch {
|
|
errorMessage = String(localized: "error.import.failed") + " \(error.localizedDescription)"
|
|
}
|
|
}
|
|
}
|