108 lines
4.9 KiB
Swift
108 lines
4.9 KiB
Swift
import SwiftUI
|
|
import TermindDomain
|
|
|
|
private struct MobileSceneFocusedValueKey: FocusedValueKey {
|
|
typealias Value = MobileSceneModel
|
|
}
|
|
|
|
extension FocusedValues {
|
|
var mobileScene: MobileSceneModel? {
|
|
get { self[MobileSceneFocusedValueKey.self] }
|
|
set { self[MobileSceneFocusedValueKey.self] = newValue }
|
|
}
|
|
}
|
|
|
|
nonisolated enum MobileShortcut {
|
|
static let settings = KeyboardShortcut(",", modifiers: .command)
|
|
static let connect = KeyboardShortcut("t", modifiers: .command)
|
|
static let newChat = KeyboardShortcut("t", modifiers: [.command, .option])
|
|
static let newHost = KeyboardShortcut("n", modifiers: [.command, .shift])
|
|
static let generateCommand = KeyboardShortcut("i", modifiers: .command)
|
|
static let find = KeyboardShortcut("f", modifiers: .command)
|
|
static let findNext = KeyboardShortcut("g", modifiers: .command)
|
|
static let findPrevious = KeyboardShortcut("g", modifiers: [.command, .shift])
|
|
static let closeWorkspace = KeyboardShortcut("w", modifiers: .command)
|
|
static let nextWorkspace = KeyboardShortcut("]", modifiers: [.command, .shift])
|
|
static let previousWorkspace = KeyboardShortcut("[", modifiers: [.command, .shift])
|
|
static let send = KeyboardShortcut(.return, modifiers: .command)
|
|
static let stop = KeyboardShortcut(".", modifiers: .command)
|
|
static let formDefault = KeyboardShortcut(.return, modifiers: [])
|
|
static let formCancel = KeyboardShortcut(.escape, modifiers: [])
|
|
|
|
static func workspace(_ index: Int) -> KeyboardShortcut {
|
|
KeyboardShortcut(KeyEquivalent(Character("\(index)")), modifiers: .command)
|
|
}
|
|
}
|
|
|
|
/// Scene commands mirror the macOS key map while targeting only the frontmost
|
|
/// iOS/iPadOS scene through `FocusedValues.mobileScene`.
|
|
struct MobileCommands: Commands {
|
|
@FocusedValue(\.mobileScene) private var scene
|
|
|
|
var body: some Commands {
|
|
CommandGroup(replacing: .appSettings) {
|
|
Button("Settings", systemImage: "gearshape") { scene?.openSettings() }
|
|
.keyboardShortcut(MobileShortcut.settings)
|
|
.disabled(scene == nil)
|
|
}
|
|
|
|
CommandGroup(replacing: .newItem) {
|
|
Button("Connect", systemImage: "network") { scene?.openConnectionPicker() }
|
|
.keyboardShortcut(MobileShortcut.connect)
|
|
.disabled(scene == nil)
|
|
Button("New Chat", systemImage: "plus.bubble") { scene?.openNewConversation() }
|
|
.keyboardShortcut(MobileShortcut.newChat)
|
|
.disabled(scene == nil)
|
|
Button("New Host", systemImage: "server.rack") { scene?.openNewHost() }
|
|
.keyboardShortcut(MobileShortcut.newHost)
|
|
.disabled(scene == nil)
|
|
}
|
|
|
|
CommandGroup(after: .pasteboard) {
|
|
Button("Generate Command", systemImage: "sparkles") { scene?.generateTerminalCommand() }
|
|
.keyboardShortcut(MobileShortcut.generateCommand)
|
|
.disabled(scene?.canUseTerminalCommands != true)
|
|
|
|
Divider()
|
|
|
|
Button("Find", systemImage: "magnifyingglass") { scene?.presentTerminalFind() }
|
|
.keyboardShortcut(MobileShortcut.find)
|
|
.disabled(scene?.canUseTerminalCommands != true)
|
|
Button("Find Next in Terminal") { scene?.navigateTerminalFind(.previous) }
|
|
.keyboardShortcut(MobileShortcut.findNext)
|
|
.disabled(scene?.canUseTerminalCommands != true)
|
|
Button("Find Previous in Terminal") { scene?.navigateTerminalFind(.next) }
|
|
.keyboardShortcut(MobileShortcut.findPrevious)
|
|
.disabled(scene?.canUseTerminalCommands != true)
|
|
}
|
|
|
|
CommandGroup(replacing: .saveItem) {
|
|
Button("Close Workspace", systemImage: "xmark") { scene?.closeActiveWorkspace() }
|
|
.keyboardShortcut(MobileShortcut.closeWorkspace)
|
|
.disabled(scene?.canCloseWorkspace != true)
|
|
}
|
|
|
|
CommandMenu("Workspaces") {
|
|
Button("Next Workspace", systemImage: "chevron.forward") { scene?.selectNextWorkspace() }
|
|
.keyboardShortcut(MobileShortcut.nextWorkspace)
|
|
.disabled(scene?.hasWorkspaces != true)
|
|
Button("Previous Workspace", systemImage: "chevron.backward") { scene?.selectPreviousWorkspace() }
|
|
.keyboardShortcut(MobileShortcut.previousWorkspace)
|
|
.disabled(scene?.hasWorkspaces != true)
|
|
|
|
Divider()
|
|
|
|
ForEach(1...8, id: \.self) { index in
|
|
Button("Workspace \(index)", systemImage: "terminal") {
|
|
scene?.selectWorkspace(at: index - 1)
|
|
}
|
|
.keyboardShortcut(MobileShortcut.workspace(index))
|
|
.disabled((scene?.workspaceCount ?? 0) < index)
|
|
}
|
|
Button("Last Workspace", systemImage: "terminal") { scene?.selectLastWorkspace() }
|
|
.keyboardShortcut(MobileShortcut.workspace(9))
|
|
.disabled(scene?.hasWorkspaces != true)
|
|
}
|
|
}
|
|
}
|