ios: mac catalyst kb shortcuts
This commit is contained in:
@@ -9,5 +9,8 @@ struct SybilApp: App
|
||||
WindowGroup {
|
||||
SplitView()
|
||||
}
|
||||
.commands {
|
||||
SybilCommands()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,29 @@ public struct SplitView: View {
|
||||
@State private var shouldRefreshOnForeground = false
|
||||
@State private var composerFocusRequest = 0
|
||||
|
||||
private var keyboardActions: SybilKeyboardActions? {
|
||||
guard !viewModel.isCheckingSession, viewModel.isAuthenticated else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return SybilKeyboardActions(
|
||||
newChat: {
|
||||
viewModel.startNewChat()
|
||||
composerFocusRequest += 1
|
||||
},
|
||||
newSearch: {
|
||||
viewModel.startNewSearch()
|
||||
composerFocusRequest += 1
|
||||
},
|
||||
previousConversation: {
|
||||
viewModel.selectPreviousSidebarItem()
|
||||
},
|
||||
nextConversation: {
|
||||
viewModel.selectNextSidebarItem()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@MainActor public init() {
|
||||
SybilFontRegistry.registerIfNeeded()
|
||||
SybilTheme.applySystemAppearance()
|
||||
@@ -41,6 +64,7 @@ public struct SplitView: View {
|
||||
}
|
||||
.font(.sybil(.body))
|
||||
.preferredColorScheme(.dark)
|
||||
.focusedSceneValue(\.sybilKeyboardActions, keyboardActions)
|
||||
.task {
|
||||
await viewModel.bootstrap()
|
||||
}
|
||||
@@ -67,3 +91,57 @@ public struct SplitView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct SybilCommands: Commands {
|
||||
@FocusedValue(\.sybilKeyboardActions) private var keyboardActions
|
||||
|
||||
public init() {}
|
||||
|
||||
public var body: some Commands {
|
||||
CommandGroup(replacing: .newItem) {
|
||||
Button("New Chat") {
|
||||
keyboardActions?.newChat()
|
||||
}
|
||||
.keyboardShortcut("n", modifiers: .command)
|
||||
.disabled(keyboardActions == nil)
|
||||
|
||||
Button("New Search") {
|
||||
keyboardActions?.newSearch()
|
||||
}
|
||||
.keyboardShortcut("n", modifiers: [.command, .shift])
|
||||
.disabled(keyboardActions == nil)
|
||||
}
|
||||
|
||||
CommandMenu("Conversation") {
|
||||
Button("Previous Conversation") {
|
||||
keyboardActions?.previousConversation()
|
||||
}
|
||||
.keyboardShortcut("[", modifiers: .command)
|
||||
.disabled(keyboardActions == nil)
|
||||
|
||||
Button("Next Conversation") {
|
||||
keyboardActions?.nextConversation()
|
||||
}
|
||||
.keyboardShortcut("]", modifiers: .command)
|
||||
.disabled(keyboardActions == nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct SybilKeyboardActions {
|
||||
var newChat: () -> Void
|
||||
var newSearch: () -> Void
|
||||
var previousConversation: () -> Void
|
||||
var nextConversation: () -> Void
|
||||
}
|
||||
|
||||
private struct SybilKeyboardActionsKey: FocusedValueKey {
|
||||
typealias Value = SybilKeyboardActions
|
||||
}
|
||||
|
||||
private extension FocusedValues {
|
||||
var sybilKeyboardActions: SybilKeyboardActions? {
|
||||
get { self[SybilKeyboardActionsKey.self] }
|
||||
set { self[SybilKeyboardActionsKey.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,6 +443,34 @@ final class SybilViewModel {
|
||||
}
|
||||
}
|
||||
|
||||
func selectPreviousSidebarItem() {
|
||||
selectAdjacentSidebarItem(offset: -1)
|
||||
}
|
||||
|
||||
func selectNextSidebarItem() {
|
||||
selectAdjacentSidebarItem(offset: 1)
|
||||
}
|
||||
|
||||
private func selectAdjacentSidebarItem(offset: Int) {
|
||||
let items = sidebarItems
|
||||
guard !items.isEmpty else {
|
||||
return
|
||||
}
|
||||
|
||||
let currentIndex = selectedItem.flatMap { selection in
|
||||
items.firstIndex { $0.selection == selection }
|
||||
}
|
||||
let startingIndex = currentIndex ?? (offset < 0 ? items.count : -1)
|
||||
let nextIndex = (startingIndex + offset + items.count) % items.count
|
||||
let nextSelection = items[nextIndex].selection
|
||||
|
||||
guard draftKind != nil || selectedItem != nextSelection else {
|
||||
return
|
||||
}
|
||||
|
||||
select(nextSelection)
|
||||
}
|
||||
|
||||
func deleteItem(_ selection: SidebarSelection) async {
|
||||
guard isAuthenticated else {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user