sidebar: single-click opens note, delete key works, space previews

This commit is contained in:
jess 2026-04-06 15:33:51 -07:00
parent bb3cc40b51
commit 12a6cc2a52
1 changed files with 54 additions and 3 deletions

View File

@ -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