diff --git a/src/ui/Mobile/Apps/Terminal/Terminal.tsx b/src/ui/Mobile/Apps/Terminal/Terminal.tsx index 5b3d1435..e4415681 100644 --- a/src/ui/Mobile/Apps/Terminal/Terminal.tsx +++ b/src/ui/Mobile/Apps/Terminal/Terminal.tsx @@ -405,7 +405,7 @@ style.innerHTML = ` font-feature-settings: "liga" 1, "calt" 1; } -.xterm .xterm-screen .xterm-char[data-char-code^="\\uE"] { +.xterm .xterm-screen .xterm-char[data-char-code^="\uE000"] { font-family: 'JetBrains Mono Nerd Font', 'MesloLGS NF', 'FiraCode Nerd Font' !important; } `; diff --git a/src/ui/Mobile/Apps/Terminal/TerminalKeyboard.tsx b/src/ui/Mobile/Apps/Terminal/TerminalKeyboard.tsx index ca295c52..68c40217 100644 --- a/src/ui/Mobile/Apps/Terminal/TerminalKeyboard.tsx +++ b/src/ui/Mobile/Apps/Terminal/TerminalKeyboard.tsx @@ -9,59 +9,137 @@ interface TerminalKeyboardProps { export function TerminalKeyboard({onSendInput}: TerminalKeyboardProps) { const [layoutName, setLayoutName] = useState("default"); + const [isCtrl, setIsCtrl] = useState(false); + const [isAlt, setIsAlt] = useState(false); - const onKeyPress = (button: string) => { + const onKeyPress = async (button: string) => { if (button === "{shift}") { setLayoutName("shift"); return; } - if (button === "{unshift}") { setLayoutName("default"); return; } - if (button === "{more}") { - setLayoutName("more") + setLayoutName("more"); return; } - if (button === "{less}") { setLayoutName("default"); return; } - if (button === "{hide}") { setLayoutName("hide"); return; } - if (button === "{unhide}") { setLayoutName("default"); return; } - onSendInput(button); + if (button === "{ctrl}") { + setIsCtrl(prev => !prev); + return; + } + if (button === "{alt}") { + setIsAlt(prev => !prev); + return; + } + + if (button === "{paste}") { + if (navigator.clipboard?.readText) { + try { + const text = await navigator.clipboard.readText(); + if (text) { + onSendInput(text); + } + } catch (err) { + + } + } + return; + } + + let input = button; + + const specialKeyMap: { [key: string]: string } = { + "{esc}": "\x1b", "{enter}": "\r", "{tab}": "\t", "{backspace}": "\x7f", + "{arrowUp}": "\x1b[A", "{arrowDown}": "\x1b[B", "{arrowRight}": "\x1b[C", "{arrowLeft}": "\x1b[D", + "{home}": "\x1b[H", "{end}": "\x1b[F", "{pgUp}": "\x1b[5~", "{pgDn}": "\x1b[6~", + "F1": "\x1bOP", "F2": "\x1bOQ", "F3": "\x1bOR", "F4": "\x1bOS", + "F5": "\x1b[15~", "F6": "\x1b[17~", "F7": "\x1b[18~", "F8": "\x1b[19~", + "F9": "\x1b[20~", "F10": "\x1b[21~", "F11": "\x1b[23~", "F12": "\x1b[24~", + "{space}": " " + }; + + if (specialKeyMap[input]) { + input = specialKeyMap[input]; + } + + if (isCtrl) { + if (input.length === 1) { + const charCode = input.toUpperCase().charCodeAt(0); + if (charCode >= 64 && charCode <= 95) { + input = String.fromCharCode(charCode - 64); + } + } + } + + if (isAlt) { + input = `\x1b${input}`; + } + + onSendInput(input); }; + const buttonTheme = [ + { + class: "hg-space-big", + buttons: "{space}", + }, + { + class: "hg-space-medium", + buttons: "{enter} {backspace}", + }, + { + class: "hg-space-small", + buttons: "{hide} {less} {more}", + } + ]; + + if (isCtrl) { + buttonTheme.push({class: "key-active", buttons: "{ctrl}"}); + } + if (isAlt) { + buttonTheme.push({class: "key-active", buttons: "{alt}"}); + } + return (