Swiftly/src/SidebarView.swift

84 lines
2.6 KiB
Swift

import SwiftUI
struct SidebarView: View {
@ObservedObject var state: AppState
private let dateFormatter: DateFormatter = {
let f = DateFormatter()
f.dateStyle = .short
f.timeStyle = .short
return f
}()
var body: some View {
VStack(spacing: 0) {
HStack {
Text("Notes")
.font(.headline)
.foregroundColor(Color(ns: Theme.current.text))
Spacer()
Button(action: { state.newNote() }) {
Image(systemName: "plus")
.foregroundColor(Color(ns: Theme.current.text))
}
.buttonStyle(.plain)
.help("New Note")
}
.padding(.horizontal, 12)
.padding(.vertical, 8)
Divider()
if state.noteList.isEmpty {
VStack {
Spacer()
Text("No notes yet")
.foregroundColor(Color(ns: Theme.current.overlay1))
.font(.system(size: 13))
Spacer()
}
} else {
List(state.noteList) { note in
NoteRow(
note: note,
isSelected: note.id == state.currentNoteID,
dateFormatter: dateFormatter
)
.contentShape(Rectangle())
.onTapGesture { state.loadNote(note.id) }
.contextMenu {
Button("Delete") { state.deleteNote(note.id) }
}
.listRowBackground(
note.id == state.currentNoteID
? Color(ns: Theme.current.surface1)
: Color.clear
)
}
.listStyle(.plain)
}
}
.background(Color(ns: Theme.current.mantle))
.onAppear { state.refreshNoteList() }
}
}
struct NoteRow: View {
let note: NoteInfo
let isSelected: Bool
let dateFormatter: DateFormatter
var body: some View {
VStack(alignment: .leading, spacing: 2) {
Text(note.title)
.font(.system(size: 13, weight: isSelected ? .semibold : .regular))
.foregroundColor(Color(ns: Theme.current.text))
.lineLimit(1)
Text(dateFormatter.string(from: note.lastModified))
.font(.system(size: 11))
.foregroundColor(Color(ns: Theme.current.subtext0))
}
.padding(.vertical, 2)
}
}