diff --git a/package.json b/package.json index 15e96c4bd..e0603db4c 100644 --- a/package.json +++ b/package.json @@ -37,9 +37,11 @@ "styled-components-breakpoint": "^3.0.0-preview.20", "swr": "^0.2.3", "uuid": "^3.3.2", - "xterm": "^3.14.4", - "xterm-addon-attach": "^0.1.0", - "xterm-addon-fit": "^0.1.0", + "xterm": "^4.9.0", + "xterm-addon-attach": "^0.6.0", + "xterm-addon-fit": "^0.4.0", + "xterm-addon-search": "^0.7.0", + "xterm-addon-search-bar": "^0.2.0", "yup": "^0.29.1" }, "devDependencies": { diff --git a/resources/scripts/components/server/Console.tsx b/resources/scripts/components/server/Console.tsx index 0c04d95ec..a4df1ccec 100644 --- a/resources/scripts/components/server/Console.tsx +++ b/resources/scripts/components/server/Console.tsx @@ -1,12 +1,14 @@ import React, { useEffect, useMemo, useRef } from 'react'; import { ITerminalOptions, Terminal } from 'xterm'; -import * as TerminalFit from 'xterm/lib/addons/fit/fit'; +import { FitAddon } from 'xterm-addon-fit'; +import { SearchAddon } from 'xterm-addon-search'; +import { SearchBarAddon } from 'xterm-addon-search-bar'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; import { ServerContext } from '@/state/server'; import styled from 'styled-components/macro'; import { usePermissions } from '@/plugins/usePermissions'; import tw from 'twin.macro'; -import 'xterm/dist/xterm.css'; +import 'xterm/css/xterm.css'; import useEventListener from '@/plugins/useEventListener'; import { debounce } from 'debounce'; @@ -29,6 +31,7 @@ const theme = { brightMagenta: '#C792EA', brightCyan: '#89DDFF', brightWhite: '#ffffff', + selection: '#FAF089', }; const terminalProps: ITerminalOptions = { @@ -55,6 +58,9 @@ export default () => { const TERMINAL_PRELUDE = '\u001b[1m\u001b[33mcontainer@pterodactyl~ \u001b[0m'; const ref = useRef(null); const terminal = useMemo(() => new Terminal({ ...terminalProps }), []); + const fitAddon = new FitAddon(); + const searchAddon = new SearchAddon(); + const searchAddonBar = new SearchBarAddon({ searchAddon }); const { connected, instance } = ServerContext.useStoreState(state => state.socket); const [ canSendCommands ] = usePermissions([ 'control.console' ]); @@ -82,26 +88,31 @@ export default () => { useEffect(() => { if (connected && ref.current && !terminal.element) { terminal.open(ref.current); + terminal.loadAddon(fitAddon); + terminal.loadAddon(searchAddon); + terminal.loadAddon(searchAddonBar); + fitAddon.fit(); - // @see https://github.com/xtermjs/xterm.js/issues/2265 - // @see https://github.com/xtermjs/xterm.js/issues/2230 - TerminalFit.fit(terminal); - - // Add support for copying terminal text. + // Add support for capturing keys terminal.attachCustomKeyEventHandler((e: KeyboardEvent) => { - // Ctrl + C + // Ctrl + C ( Copy ) if (e.ctrlKey && (e.key === 'c')) { document.execCommand('copy'); return false; } + if (e.ctrlKey && (e.key === 'f')) { + searchAddonBar.show(); + return false; + } + return true; }); } }, [ terminal, connected ]); const fit = debounce(() => { - TerminalFit.fit(terminal); + fitAddon.fit(); }, 100); useEventListener('resize', () => fit()); diff --git a/yarn.lock b/yarn.lock index 25272d135..113b3370c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1662,6 +1662,14 @@ babel-plugin-syntax-jsx@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" +babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -2260,6 +2268,11 @@ core-js-compat@^3.4.7: browserslist "^4.8.0" semver "^6.3.0" +core-js@^2.4.0: + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== + core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -5797,6 +5810,11 @@ regenerate@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + regenerator-runtime@^0.13.2: version "0.13.2" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" @@ -5967,6 +5985,11 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" +rxjs-compat@^6.5.4: + version "6.6.3" + resolved "https://registry.yarnpkg.com/rxjs-compat/-/rxjs-compat-6.6.3.tgz#141405fcee11f48718d428b99c8f01826f594e5c" + integrity sha512-y+wUqq7bS2dG+7rH2fNMoxsDiJ32RQzFxZQE/JdtpnmEZmwLQrb1tCiItyHxdXJHXjmHnnzFscn3b6PEmORGKw== + safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -7313,17 +7336,33 @@ xtend@^4.0.2: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -xterm-addon-attach@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/xterm-addon-attach/-/xterm-addon-attach-0.1.0.tgz#e0daa8188e9bb830def9ccad015fc62bc07e3abe" +xterm-addon-attach@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/xterm-addon-attach/-/xterm-addon-attach-0.6.0.tgz#220c23addd62ab88c9914e2d4c06f7407e44680e" + integrity sha512-Mo8r3HTjI/EZfczVCwRU6jh438B4WLXxdFO86OB7bx0jGhwh2GdF4ifx/rP+OB+Cb2vmLhhVIZ00/7x3YSP3dg== -xterm-addon-fit@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.1.0.tgz#dd52d8b2ec6ef05faab8285bafd9310063704468" +xterm-addon-fit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.4.0.tgz#06e0c5d0a6aaacfb009ef565efa1c81e93d90193" + integrity sha512-p4BESuV/g2L6pZzFHpeNLLnep9mp/DkF3qrPglMiucSFtD8iJxtMufEoEJbN8LZwB4i+8PFpFvVuFrGOSpW05w== -xterm@^3.14.4: - version "3.14.4" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.14.4.tgz#68a474fd0628e6027e420f6c8b0df136f6281ff8" +xterm-addon-search-bar@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/xterm-addon-search-bar/-/xterm-addon-search-bar-0.2.0.tgz#e03c020a5ed22f1e8d503946b26a14ade508bc91" + integrity sha512-xvXmBA/ShbnzGe5CCy0kqPNNGqjkpuaRgH3Z1iW0V71vCAPRrtJ/v/hMnysZBH7WGUYhlCQr1cJZagW2fBVvSg== + dependencies: + babel-runtime "^6.26.0" + rxjs-compat "^6.5.4" + +xterm-addon-search@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.7.0.tgz#c929d3e5cbb335e82bff72f158ea82936d9cd4ef" + integrity sha512-6060evmJJ+tZcjnx33FXaeEHLpuXEa7l9UzUsYfMlCKbu88AbE+5LJocTKCHYd71cwCwb9pjmv/G1o9Rf9Zbcg== + +xterm@^4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.9.0.tgz#7a4c097a433d565339b5533b468bbc60c6c87969" + integrity sha512-wGfqufmioctKr8VkbRuZbVDfjlXWGZZ1PWHy1yqqpGT3Nm6yaJx8lxDbSEBANtgaiVPTcKSp97sxOy5IlpqYfw== y18n@^4.0.0: version "4.0.0"