2024-12-10 15:21:28 +01:00

187 lines
5.7 KiB
Swift

import SwiftUI
import SFSafeSymbols
#warning("Allow selection of pages as navigation bar items")
#warning("Transfer images of posts to other language")
#warning("Show tag selection view for pages")
@main
struct MainView: App {
private let sidebarWidth: CGFloat = 250
private let detailWidth: CGFloat = 300
@StateObject
private var content: Content = .init()
@State
private var language: ContentLanguage = .english
@State
private var selectedTab: MainViewTab = .posts
@State
private var selectedPost: Post?
@State
private var selectedPage: Page?
@State
private var selectedTag: Tag?
@State
private var selectedImage: ImageResource?
@State
private var selectedFile: FileResource?
@State
private var selectedSection: SettingsSection = .folders
@State
private var showAddSheet = false
@ViewBuilder
var sidebar: some View {
switch selectedTab {
case .posts:
PostListView(selectedPost: $selectedPost)
case .pages:
PageListView(selectedPage: $selectedPage)
case .tags:
TagListView(selectedTag: $selectedTag)
case .files:
FileListView(selectedFile: $selectedFile)
case .generation:
SettingsListView(selectedSection: $selectedSection)
}
}
@ViewBuilder
var viewContent: some View {
switch selectedTab {
case .posts:
SelectedContentView<PostContentView>(selected: $selectedPost)
case .pages:
SelectedContentView<PageContentView>(selected: $selectedPage)
case .tags:
SelectedContentView<TagContentView>(selected: $selectedTag)
case .files:
SelectedContentView<FileContentView>(selected: $selectedFile)
case .generation:
GenerationContentView()
}
}
@ViewBuilder
var detail: some View {
switch selectedTab {
case .posts:
SelectedDetailView<PostDetailView>(selected: $selectedPost)
case .pages:
SelectedDetailView<PageDetailView>(selected: $selectedPage)
case .tags:
SelectedDetailView<TagDetailView>(selected: $selectedTag)
case .files:
SelectedDetailView<FileDetailView>(selected: $selectedFile)
case .generation:
GenerationDetailView(section: selectedSection)
}
}
@ViewBuilder
var addItemSheet: some View {
switch selectedTab {
case .posts:
AddPostView(selected: $selectedPost)
case .pages:
AddPageView(selected: $selectedPage)
case .tags:
AddTagView(selected: $selectedTag)
case .files:
AddFileView(selectedImage: $selectedImage, selectedFile: $selectedFile)
case .generation:
Text("Not implemented")
}
}
var body: some Scene {
WindowGroup {
NavigationSplitView {
sidebar
.toolbar {
ToolbarItem(placement: .navigation) {
Picker("", selection: $selectedTab) {
Text("Posts").tag(MainViewTab.posts)
Text("Pages").tag(MainViewTab.pages)
Text("Tags").tag(MainViewTab.tags)
Text("Files").tag(MainViewTab.files)
Text("Generation").tag(MainViewTab.generation)
}.pickerStyle(.segmented)
}
}
.navigationSplitViewColumnWidth(min: sidebarWidth, ideal: sidebarWidth, max: sidebarWidth)
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: { showAddSheet = true }) {
Label("Add", systemSymbol: .plus)
}
.disabled(!selectedTab.canAddItems)
}
}
} content: {
viewContent
} detail: {
detail
.navigationSplitViewColumnWidth(min: detailWidth, ideal: detailWidth, max: detailWidth)
}
.toolbar {
ToolbarItem(placement: .primaryAction) {
Picker("", selection: $language) {
Text("English")
.tag(ContentLanguage.english)
Text("German")
.tag(ContentLanguage.german)
}.pickerStyle(.segmented)
}
ToolbarItem(placement: .primaryAction) {
Button(action: save) {
Text("Save")
}
}
}
.navigationTitle("")
.environment(\.language, language)
.environmentObject(content)
.onAppear(perform: loadContent)
.onReceive(Timer.publish(every: 60.0, on: .main, in: .common).autoconnect()) { _ in
save()
}
.sheet(isPresented: $showAddSheet) {
addItemSheet
.environment(\.language, language)
.environmentObject(content)
}
}
}
private func save() {
// Save all changed files
do {
try content.saveToDisk()
} catch {
print("Failed to save content: \(error.localizedDescription)")
}
}
private func loadContent() {
do {
try content.loadFromDisk()
} catch {
print("Failed to load content: \(error.localizedDescription)")
}
}
}