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 {
|
||||
@ObservedObject var state: AppState
|
||||
@State private var lastClickedID: UUID?
|
||||
@State private var previewNote: NoteInfo?
|
||||
@FocusState private var sidebarFocused: Bool
|
||||
|
||||
private let dateFormatter: DateFormatter = {
|
||||
let f = DateFormatter()
|
||||
|
|
@ -49,9 +51,6 @@ struct SidebarView: View {
|
|||
dateFormatter: dateFormatter
|
||||
)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture(count: 2) {
|
||||
state.openNote(note.id)
|
||||
}
|
||||
.onTapGesture(count: 1) {
|
||||
handleClick(note: note, index: index)
|
||||
}
|
||||
|
|
@ -68,11 +67,29 @@ struct SidebarView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.focusable()
|
||||
.focused($sidebarFocused)
|
||||
.onDeleteCommand {
|
||||
guard !state.selectedNoteIDs.isEmpty else { return }
|
||||
state.deleteNotes(state.selectedNoteIDs)
|
||||
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))
|
||||
|
|
@ -80,6 +97,7 @@ struct SidebarView: View {
|
|||
}
|
||||
|
||||
private func handleClick(note: NoteInfo, index: Int) {
|
||||
sidebarFocused = true
|
||||
let flags = NSEvent.modifierFlags
|
||||
if flags.contains(.command) {
|
||||
state.selectNote(note.id, extend: true)
|
||||
|
|
@ -95,11 +113,44 @@ struct SidebarView: View {
|
|||
}
|
||||
} else {
|
||||
state.selectNote(note.id)
|
||||
state.openNote(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 {
|
||||
let note: NoteInfo
|
||||
let isSelected: Bool
|
||||
|
|
|
|||
Loading…
Reference in New Issue