import SwiftUI struct NoteDetailView: View { @EnvironmentObject var client: WebDAVClient let note: DenoteNote @State private var showingEditor = false @State private var isLoadingContent = false @State private var themeManager = ThemeManager.shared private var currentNote: DenoteNote { client.notes.first { $0.id == note.id } ?? note } var body: some View { ScrollView { VStack(alignment: .leading, spacing: 0) { if !currentNote.keywords.isEmpty { keywordsHeader .padding(.horizontal) .padding(.top, 8) .padding(.bottom, 16) } if isLoadingContent { ProgressView("Loading...") .frame(maxWidth: .infinity) .padding(.top, 60) } else if let content = currentNote.content { OrgContentView(content: content) .padding(.horizontal) } else { emptyContentView } } } .background(themeManager.current.background) .navigationTitle(currentNote.displayTitle) .navigationBarTitleDisplayMode(.large) .toolbarBackground(themeManager.current.secondaryBackground, for: .navigationBar) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Edit") { showingEditor = true } .disabled(currentNote.content == nil) } } .sheet(isPresented: $showingEditor) { NoteEditorView(note: currentNote) } .task { await loadContentIfNeeded() } } private var keywordsHeader: some View { HStack(spacing: 6) { ForEach(currentNote.keywords, id: \.self) { kw in Text(kw) .font(.caption) .padding(.horizontal, 8) .padding(.vertical, 3) .background(Color.accentColor.opacity(0.12)) .foregroundStyle(Color.accentColor) .clipShape(Capsule()) } } } private var emptyContentView: some View { VStack(spacing: 12) { Image(systemName: "doc.text") .font(.system(size: 40)) .foregroundStyle(.secondary) Text("Content not available") .foregroundStyle(.secondary) Button("Load") { Task { await loadContentIfNeeded() } } .buttonStyle(.bordered) } .frame(maxWidth: .infinity) .padding(.top, 60) } private func loadContentIfNeeded() async { guard currentNote.content == nil else { return } isLoadingContent = true if let idx = client.notes.firstIndex(where: { $0.id == note.id }) { await client.loadContent(for: idx) } isLoadingContent = false } }