Combine initial and storage view

This commit is contained in:
Christoph Hagen
2025-02-23 20:34:02 +01:00
parent cdcbe21c0d
commit cf17b513d0
5 changed files with 132 additions and 63 deletions

View File

@ -33,7 +33,7 @@ struct MainView: App {
private var showInitialSetupSheet = false
@State
private var showStorageErrorSheet = false
private var showStorageStatusSheet = false
@State
private var showSettingsSheet = false
@ -176,7 +176,7 @@ struct MainView: App {
}
}
ToolbarItem {
Button(action: saveButtonPressed) {
Button(action: { showStorageStatusSheet = true }) {
Image(systemSymbol: content.saveState.symbol)
.foregroundStyle(content.saveState.color)
}
@ -199,8 +199,8 @@ struct MainView: App {
.environmentObject(content)
.environmentObject(selection)
}
.sheet(isPresented: $showStorageErrorSheet) {
StorageErrorView(isPresented: $showStorageErrorSheet)
.sheet(isPresented: $showStorageStatusSheet) {
StorageStatusView(isPresented: $showStorageStatusSheet)
.environmentObject(content)
}
.sheet(isPresented: $showSettingsSheet) {
@ -230,28 +230,15 @@ struct MainView: App {
}
}
private func saveButtonPressed() {
switch content.saveState {
case .storageNotInitialized:
showInitialSheet()
case .isSaved, .needsSave:
content.saveUnconditionally()
case .isSaving:
break
case .failedToSave, .savingPausedDueToLoadErrors:
showStorageErrorSheet = true
}
}
private func loadContent() {
guard content.storage.contentScope != nil else {
showInitialSheet()
showStorageStatusSheet = true
return
}
content.loadFromDisk {
prepareAfterLoad()
if !content.storageErrors.isEmpty {
self.showStorageErrorSheet = true
self.showStorageStatusSheet = true
}
}
}
@ -270,11 +257,5 @@ struct MainView: App {
selection.file = content.files.first
}
}
private func showInitialSheet() {
DispatchQueue.main.async {
showInitialSetupSheet = true
}
}
}

View File

@ -1,33 +0,0 @@
import SwiftUI
struct StorageErrorView: View {
@EnvironmentObject
private var content: Content
@Binding
var isPresented: Bool
var body: some View {
VStack {
Text("Failed to load database")
.font(.headline)
List(content.storageErrors) { error in
VStack {
Text(error.message)
Text(error.date.formatted())
.font(.footnote)
}
}
.frame(minHeight: 300)
if content.saveState == .savingPausedDueToLoadErrors {
Button("Allow saving", action: { content.resumeSavingAfterLoadingErrors() })
.padding()
Text("Saving has been disabled to prevent data corruption due to loading errors. Enable saving to save the partially loaded data.")
}
Button("Dismiss", action: { isPresented = false })
.padding()
}
.padding()
}
}

View File

@ -0,0 +1,121 @@
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 { }
}
}