import SwiftUI import SFSafeSymbols #warning("Fix podcast") #warning("Allow selection of pages as navigation bar items") #warning("Add link to other language") #warning("Transfer images of posts to other language") #warning("Show tag selection view for pages") #warning("Button to replace files") #warning("Replace links to files inside pages when id changes") #warning("Calculate file sizes") #warning("Specify image aspect ratio to prevent page jumps") @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(selected: $selectedPost) case .pages: SelectedContentView(selected: $selectedPage) case .tags: SelectedContentView(selected: $selectedTag) case .files: SelectedContentView(selected: $selectedFile) case .generation: GenerationContentView(selected: $selectedSection) } } @ViewBuilder var detail: some View { switch selectedTab { case .posts: SelectedDetailView(selected: $selectedPost) case .pages: SelectedDetailView(selected: $selectedPage) case .tags: SelectedDetailView(selected: $selectedTag) case .files: SelectedDetailView(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)") } } }