sidebar: single-click opens note, delete key works, space previews
This commit is contained in:
parent
bb3cc40b51
commit
12a6cc2a52
|
|
@ -3,6 +3,8 @@ import SwiftUI
|
||||||
struct SidebarView: View {
|
struct SidebarView: View {
|
||||||
@ObservedObject var state: AppState
|
@ObservedObject var state: AppState
|
||||||
@State private var lastClickedID: UUID?
|
@State private var lastClickedID: UUID?
|
||||||
|
@State private var previewNote: NoteInfo?
|
||||||
|
@FocusState private var sidebarFocused: Bool
|
||||||
|
|
||||||
private let dateFormatter: DateFormatter = {
|
private let dateFormatter: DateFormatter = {
|
||||||
let f = DateFormatter()
|
let f = DateFormatter()
|
||||||
|
|
@ -49,9 +51,6 @@ struct SidebarView: View {
|
||||||
dateFormatter: dateFormatter
|
dateFormatter: dateFormatter
|
||||||
)
|
)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.onTapGesture(count: 2) {
|
|
||||||
state.openNote(note.id)
|
|
||||||
}
|
|
||||||
.onTapGesture(count: 1) {
|
.onTapGesture(count: 1) {
|
||||||
handleClick(note: note, index: index)
|
handleClick(note: note, index: index)
|
||||||
}
|
}
|
||||||
|
|
@ -68,11 +67,29 @@ struct SidebarView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.focusable()
|
||||||
|
.focused($sidebarFocused)
|
||||||
.onDeleteCommand {
|
.onDeleteCommand {
|
||||||
guard !state.selectedNoteIDs.isEmpty else { return }
|
guard !state.selectedNoteIDs.isEmpty else { return }
|
||||||
state.deleteNotes(state.selectedNoteIDs)
|
state.deleteNotes(state.selectedNoteIDs)
|
||||||
lastClickedID = nil
|
lastClickedID = nil
|
||||||
}
|
}
|
||||||
|
.onKeyPress(.space) {
|
||||||
|
guard let id = state.selectedNoteIDs.first,
|
||||||
|
state.selectedNoteIDs.count == 1,
|
||||||
|
let note = state.noteList.first(where: { $0.id == id }) else {
|
||||||
|
return .ignored
|
||||||
|
}
|
||||||
|
if previewNote?.id == note.id {
|
||||||
|
previewNote = nil
|
||||||
|
} else {
|
||||||
|
previewNote = note
|
||||||
|
}
|
||||||
|
return .handled
|
||||||
|
}
|
||||||
|
.popover(item: $previewNote, arrowEdge: .trailing) { note in
|
||||||
|
NotePreviewView(note: note, state: state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.background(Color(ns: Theme.current.base))
|
.background(Color(ns: Theme.current.base))
|
||||||
|
|
@ -80,6 +97,7 @@ struct SidebarView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleClick(note: NoteInfo, index: Int) {
|
private func handleClick(note: NoteInfo, index: Int) {
|
||||||
|
sidebarFocused = true
|
||||||
let flags = NSEvent.modifierFlags
|
let flags = NSEvent.modifierFlags
|
||||||
if flags.contains(.command) {
|
if flags.contains(.command) {
|
||||||
state.selectNote(note.id, extend: true)
|
state.selectNote(note.id, extend: true)
|
||||||
|
|
@ -95,11 +113,44 @@ struct SidebarView: View {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state.selectNote(note.id)
|
state.selectNote(note.id)
|
||||||
|
state.openNote(note.id)
|
||||||
lastClickedID = note.id
|
lastClickedID = note.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct NotePreviewView: View {
|
||||||
|
let note: NoteInfo
|
||||||
|
@ObservedObject var state: AppState
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
|
Text(note.title)
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(Color(ns: Theme.current.text))
|
||||||
|
Divider()
|
||||||
|
ScrollView {
|
||||||
|
Text(previewText)
|
||||||
|
.font(.body)
|
||||||
|
.foregroundColor(Color(ns: Theme.current.subtext0))
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.frame(width: 320, height: 240)
|
||||||
|
.background(Color(ns: Theme.current.base))
|
||||||
|
}
|
||||||
|
|
||||||
|
private var previewText: String {
|
||||||
|
let bridge = RustBridge.shared
|
||||||
|
if bridge.cacheLoad(note.id) {
|
||||||
|
let text = bridge.getText(note.id)
|
||||||
|
return String(text.prefix(2000))
|
||||||
|
}
|
||||||
|
return "(unable to load preview)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct NoteRow: View {
|
struct NoteRow: View {
|
||||||
let note: NoteInfo
|
let note: NoteInfo
|
||||||
let isSelected: Bool
|
let isSelected: Bool
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue