Add paste button to mobile terminal keyboard
This commit is contained in:
1 parent
591be6909e
commit
fe9dc6e20f
4 files changed
+38
-8
No files matched your search
@@ -5,12 +5,17 @@ struct MobileTerminalKeyboard: View {
|
||||
static let barHeight: CGFloat = 44
|
||||
|
||||
@ObservedObject var state: TerminalViewState
|
||||
let paste: () -> Void
|
||||
@State private var control: TerminalPublicStickyActivation = .inactive
|
||||
@State private var alt: TerminalPublicStickyActivation = .inactive
|
||||
@State private var shift = MobileTerminalShiftState()
|
||||
|
||||
init(state: TerminalViewState, initialShift: MobileTerminalShiftState = MobileTerminalShiftState()) {
|
||||
init(
|
||||
state: TerminalViewState, initialShift: MobileTerminalShiftState = MobileTerminalShiftState(),
|
||||
paste: @escaping () -> Void
|
||||
) {
|
||||
self.state = state
|
||||
self.paste = paste
|
||||
_shift = State(initialValue: initialShift)
|
||||
}
|
||||
|
||||
@@ -37,7 +42,11 @@ struct MobileTerminalKeyboard: View {
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
Divider().padding(.vertical, 8)
|
||||
keyboardToggle.padding(.horizontal, 8)
|
||||
HStack(spacing: 0) {
|
||||
pasteButton
|
||||
keyboardToggle
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.font(.system(.callout, design: .monospaced))
|
||||
@@ -62,6 +71,15 @@ struct MobileTerminalKeyboard: View {
|
||||
.accessibilityAddTraits(shift.activation == .inactive ? [] : .isSelected)
|
||||
}
|
||||
|
||||
private var pasteButton: some View {
|
||||
Button(action: paste) {
|
||||
Label("Paste", systemImage: "doc.on.clipboard")
|
||||
.labelStyle(.iconOnly)
|
||||
.frame(width: 44, height: 44)
|
||||
.contentShape(.rect)
|
||||
}
|
||||
}
|
||||
|
||||
private var keyboardToggle: some View {
|
||||
Button {
|
||||
if state.isFocused {
|
||||
|
||||
@@ -45,7 +45,10 @@ struct MobileWorkspaceView: View {
|
||||
workspace.terminal.applyPreferences(value)
|
||||
}
|
||||
.onTapGesture { workspace.terminal.requestFocus() }
|
||||
MobileTerminalKeyboard(state: workspace.terminal)
|
||||
MobileTerminalKeyboard(state: workspace.terminal) {
|
||||
guard let text = UIPasteboard.general.string else { return }
|
||||
workspace.insertTerminalText(text)
|
||||
}
|
||||
}.opacity(showsJourney ? 0 : 1)
|
||||
.allowsHitTesting(!showsJourney).accessibilityHidden(showsJourney)
|
||||
if showsJourney { connectionJourney.background(.background) }
|
||||
|
||||
@@ -15,11 +15,12 @@ import struct TermindDomain.Host
|
||||
struct MobileIconRenderingTests {
|
||||
@Test func terminalKeyboardKeepsItsCompactHeight() {
|
||||
#expect(UIImage(systemName: "play.rectangle") != nil)
|
||||
#expect(UIImage(systemName: "doc.on.clipboard") != nil)
|
||||
#expect(MobileTerminalKeyboard.barHeight == 44)
|
||||
for width in [CGFloat(320), 390, 430] {
|
||||
for dynamicTypeSize in [DynamicTypeSize.large, .accessibility3] {
|
||||
let controller = UIHostingController(
|
||||
rootView: MobileTerminalKeyboard(state: TerminalViewState())
|
||||
rootView: MobileTerminalKeyboard(state: TerminalViewState(), paste: {})
|
||||
.environment(\.dynamicTypeSize, dynamicTypeSize))
|
||||
let size = controller.sizeThatFits(in: CGSize(width: width, height: 800))
|
||||
#expect(abs(size.height - 44) < 0.5)
|
||||
@@ -126,7 +127,7 @@ struct MobileIconRenderingTests {
|
||||
try await capture("terminal-keyboard-\(suffix)", language: language, scheme: scheme) {
|
||||
VStack(spacing: 0) {
|
||||
Spacer()
|
||||
MobileTerminalKeyboard(state: TerminalViewState())
|
||||
MobileTerminalKeyboard(state: TerminalViewState(), paste: {})
|
||||
}
|
||||
.environment(\.locale, locale)
|
||||
}
|
||||
@@ -135,7 +136,8 @@ struct MobileIconRenderingTests {
|
||||
Spacer()
|
||||
MobileTerminalKeyboard(
|
||||
state: TerminalViewState(),
|
||||
initialShift: MobileTerminalShiftState(activation: .locked))
|
||||
initialShift: MobileTerminalShiftState(activation: .locked),
|
||||
paste: {})
|
||||
}
|
||||
.environment(\.locale, locale)
|
||||
}
|
||||
@@ -170,7 +172,7 @@ struct MobileIconRenderingTests {
|
||||
try await capture("terminal-keyboard-large-type", language: language, scheme: .light) {
|
||||
VStack(spacing: 0) {
|
||||
Spacer()
|
||||
MobileTerminalKeyboard(state: TerminalViewState())
|
||||
MobileTerminalKeyboard(state: TerminalViewState(), paste: {})
|
||||
}
|
||||
.environment(\.locale, locale).environment(\.dynamicTypeSize, .accessibility3)
|
||||
}
|
||||
|
||||
@@ -530,13 +530,20 @@ struct ArchitectureBoundaryTests {
|
||||
#expect(historyDivider.lowerBound < nextMatch.lowerBound)
|
||||
#expect(workspace.contains(".dropDestination(for: URL.self)"))
|
||||
#expect(workspace.contains(".toolbar(.hidden, for: .tabBar)"))
|
||||
#expect(workspace.contains("guard let text = UIPasteboard.general.string else { return }"))
|
||||
#expect(workspace.contains("workspace.insertTerminalText(text)"))
|
||||
#expect(root.contains("private func closeWorkspace(_ id: UUID)"))
|
||||
#expect(!workspace.contains("Circle().fill(workspace.connected"))
|
||||
let keyboard = try String(
|
||||
contentsOf: sourceRoot.appending(path: "../TFI/Features/Terminal/MobileTerminalKeyboard.swift"),
|
||||
encoding: .utf8)
|
||||
#expect(keyboard.contains("ScrollView(.horizontal"))
|
||||
#expect(keyboard.contains("keyboardToggle.padding(.horizontal, 8)"))
|
||||
let pasteButton = try #require(keyboard.range(of: "pasteButton"))
|
||||
let keyboardToggle = try #require(keyboard.range(of: "keyboardToggle"))
|
||||
#expect(pasteButton.lowerBound < keyboardToggle.lowerBound)
|
||||
#expect(keyboard.contains("Button(action: paste)"))
|
||||
#expect(keyboard.contains("Label(\"Paste\", systemImage: \"doc.on.clipboard\")"))
|
||||
#expect(keyboard.contains(".padding(.horizontal, 8)"))
|
||||
#expect(keyboard.contains("static let barHeight: CGFloat = 44"))
|
||||
#expect(keyboard.contains(".buttonStyle(.plain)"))
|
||||
#expect(!keyboard.contains(".buttonStyle(.bordered)"))
|
||||
|
||||
Reference in new issue
Block a user