340770861e
Each view now uses themeManager.current.background and secondaryBackground explicitly, matching the pattern in SetupView. preferredColorScheme alone only toggles system dark/light — specific hex colors require explicit background modifiers.
89 lines
3.0 KiB
Swift
89 lines
3.0 KiB
Swift
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
|
|
}
|
|
}
|