ChWebsiteApp/CHDataManagement/Main/StorageStatusView.swift
2025-02-23 20:34:02 +01:00

122 lines
3.8 KiB
Swift

import SwiftUI
struct StorageStatusView: View {
@EnvironmentObject
private var content: Content
@Binding
var isPresented: Bool
var title: String {
switch content.saveState {
case .storageNotInitialized:
"No Database Loaded"
case .savingPausedDueToLoadErrors:
"Database corrupted"
case .isSaved:
"Database is healthy"
case .needsSave:
"Database will be saved soon"
case .failedToSave:
"Database errors"
case .isSaving:
"Database is being saved"
}
}
var subtitle: String {
switch content.saveState {
case .storageNotInitialized:
"To start editing the content of a website, create a new database or load an existing one. Open a folder with an existing database, or choose an empty folder to create a new project."
case .savingPausedDueToLoadErrors:
"The errors loading the database are listed below. Saving has been disabled to prevent data corruption. Enable saving to save the partially loaded data."
case .isSaved:
"All data is saved to disk"
case .needsSave:
"Wait for a few seconds until the remaining changes are saved."
case .failedToSave:
"The errors while saving the database are listed below."
case .isSaving:
"Changes are being written to disk"
}
}
var buttonText: String {
switch content.saveState {
case .storageNotInitialized:
"Choose folder"
case .savingPausedDueToLoadErrors:
"Save partial data"
case .isSaved, .isSaving, .needsSave:
"Save database"
case .failedToSave:
"Attempt save again"
}
}
var body: some View {
VStack {
Text(title)
.font(.title)
.padding()
Text(subtitle)
.multilineTextAlignment(.center)
List(content.storageErrors) { error in
VStack {
Text(error.message)
Text(error.date.formatted())
.font(.footnote)
}
}
.frame(minHeight: 300)
Button(buttonText, action: saveButtonPressed)
.padding()
.disabled(content.saveState == .isSaving)
Button("Dismiss", action: { isPresented = false })
.padding()
}
.padding()
}
func saveButtonPressed() {
switch content.saveState {
case .storageNotInitialized:
selectContentPath()
case .savingPausedDueToLoadErrors:
content.resumeSavingAfterLoadingErrors()
case .isSaved, .needsSave, .failedToSave:
content.saveUnconditionally()
case .isSaving:
break
}
}
private func selectContentPath() {
let panel = NSOpenPanel()
// Sets up so user can only select a single directory
panel.canChooseFiles = false
panel.canChooseDirectories = true
panel.allowsMultipleSelection = false
panel.showsHiddenFiles = false
panel.title = "Select the database folder"
let response = panel.runModal()
guard response == .OK else {
content.storageErrors.append(.init(message: "Failed to select a folder: \(response)"))
return
}
guard let url = panel.url else {
content.storageErrors.append(.init(message: "No url found for selected content folder"))
return
}
guard content.storage.save(contentPath: url) else {
content.storageErrors.append(.init(message: "Failed to set content path"))
return
}
content.loadFromDisk { }
}
}