fix: scroller to work on mobile
and some other bug fix
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
"@base-ui/react": "^1.4.0",
|
||||
"@fontsource-variable/inter": "^5.2.8",
|
||||
"@tailwindcss/vite": "^4.2.2",
|
||||
"@xterm/addon-clipboard": "^0.2.0",
|
||||
"@xterm/addon-fit": "^0.11.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
|
||||
Generated
+21
@@ -16,6 +16,9 @@ importers:
|
||||
"@tailwindcss/vite":
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2([email protected](@types/[email protected])([email protected]))
|
||||
"@xterm/addon-clipboard":
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0
|
||||
"@xterm/addon-fit":
|
||||
specifier: ^0.11.0
|
||||
version: 0.11.0
|
||||
@@ -1248,6 +1251,12 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||
|
||||
"@xterm/[email protected]":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-Dl31BCtBhLaUEECUbEiVcCLvLBbaeGYdT7NofB8OJkGTD3MWgBsaLjXvfGAD4tQNHhm6mbKyYkR7XD8kiZsdNg==,
|
||||
}
|
||||
|
||||
"@xterm/[email protected]":
|
||||
resolution:
|
||||
{
|
||||
@@ -2286,6 +2295,12 @@ packages:
|
||||
integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==,
|
||||
}
|
||||
|
||||
[email protected]:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-5xVjhUZlHHeuO2W7w2rDFj/Kl1xLX+HjZxdOQwCsUOifl6UaoH1o1wsbsTMz+r0aeC7gCijvru02j6TfKZWzKg==,
|
||||
}
|
||||
|
||||
[email protected]:
|
||||
resolution:
|
||||
{
|
||||
@@ -4221,6 +4236,10 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
"@xterm/[email protected]":
|
||||
dependencies:
|
||||
js-base64: 3.8.1
|
||||
|
||||
"@xterm/[email protected]": {}
|
||||
|
||||
"@xterm/[email protected]": {}
|
||||
@@ -4767,6 +4786,8 @@ snapshots:
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { ClipboardAddon } from "@xterm/addon-clipboard";
|
||||
import { FitAddon } from "@xterm/addon-fit";
|
||||
import { Terminal as XTerm } from "@xterm/xterm";
|
||||
import { Eraser, PlugZap, RotateCcw, Square, Terminal } from "lucide-react";
|
||||
@@ -165,65 +166,51 @@ export function TerminalPage({
|
||||
fontFamily: '"SFMono-Regular", Consolas, "Liberation Mono", monospace',
|
||||
fontSize: 14,
|
||||
lineHeight: 1.1,
|
||||
// xterm uses this width for its internal scrollbar as well as the
|
||||
// overview ruler. Reserve a larger touch target on coarse pointers.
|
||||
overviewRuler: {
|
||||
width: window.matchMedia("(pointer: coarse)").matches ? 22 : 16,
|
||||
},
|
||||
scrollback: 5000,
|
||||
theme: {
|
||||
background: "#0b1117",
|
||||
foreground: "#e5e7eb",
|
||||
cursor: "#6ee7a8",
|
||||
scrollbarSliderBackground: "#52617099",
|
||||
scrollbarSliderHoverBackground: "#6b7c8dcc",
|
||||
scrollbarSliderActiveBackground: "#8294a6",
|
||||
},
|
||||
});
|
||||
const fit = new FitAddon();
|
||||
terminal.loadAddon(new ClipboardAddon());
|
||||
terminal.loadAddon(fit);
|
||||
terminal.open(hostRef.current);
|
||||
terminal.attachCustomKeyEventHandler((event) => {
|
||||
if (event.type !== "keydown") return true;
|
||||
const copiesTerminalSelection =
|
||||
event.type === "keydown" &&
|
||||
event.ctrlKey &&
|
||||
event.shiftKey &&
|
||||
event.code === "KeyC";
|
||||
if (!copiesTerminalSelection) return true;
|
||||
|
||||
const copy =
|
||||
(event.ctrlKey && event.shiftKey && event.code === "KeyC") ||
|
||||
(event.metaKey && event.code === "KeyC") ||
|
||||
(event.ctrlKey && event.code === "Insert");
|
||||
if (copy) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (terminal.hasSelection()) {
|
||||
if (!navigator.clipboard) {
|
||||
toast.error("Clipboard access requires HTTPS or localhost");
|
||||
} else {
|
||||
void navigator.clipboard
|
||||
.writeText(terminal.getSelection())
|
||||
.catch((error) =>
|
||||
toast.error("Clipboard access was denied", {
|
||||
description: String(error),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const paste =
|
||||
(event.ctrlKey && event.shiftKey && event.code === "KeyV") ||
|
||||
(event.metaKey && event.code === "KeyV") ||
|
||||
(event.shiftKey && event.code === "Insert");
|
||||
if (paste) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
// Chromium reserves Ctrl+Shift+C for DevTools. Other clipboard shortcuts
|
||||
// fall through to xterm's native copy/paste event handlers.
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (terminal.hasSelection()) {
|
||||
if (!navigator.clipboard) {
|
||||
toast.error("Clipboard access requires HTTPS or localhost");
|
||||
return false;
|
||||
} else {
|
||||
void navigator.clipboard
|
||||
.writeText(terminal.getSelection())
|
||||
.catch((error) =>
|
||||
toast.error("Clipboard access was denied", {
|
||||
description: String(error),
|
||||
}),
|
||||
);
|
||||
}
|
||||
void navigator.clipboard
|
||||
.readText()
|
||||
.then((text) => terminal.paste(text))
|
||||
.catch((error) =>
|
||||
toast.error("Clipboard access was denied", {
|
||||
description: String(error),
|
||||
}),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
fit.fit();
|
||||
terminalRef.current = terminal;
|
||||
@@ -351,7 +338,9 @@ export function TerminalPage({
|
||||
} finally {
|
||||
setSession(null);
|
||||
setConnection("idle");
|
||||
terminalRef.current?.clear();
|
||||
// xterm.clear() deliberately preserves the active cursor line. Closing
|
||||
// a session should discard its complete screen and terminal modes.
|
||||
terminalRef.current?.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -465,11 +465,13 @@
|
||||
fitted canvas, so keep it on the same surface as the terminal theme. */
|
||||
background-color: #0b1117;
|
||||
overscroll-behavior: contain;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.terminal-surface .xterm-viewport::-webkit-scrollbar {
|
||||
display: none;
|
||||
.terminal-surface .xterm-scrollable-element > .scrollbar,
|
||||
.terminal-surface .xterm-scrollable-element > .scrollbar > .slider {
|
||||
/* Without this, mobile browsers claim a thumb drag as page panning before
|
||||
xterm's pointer-capture scrollbar can process it. */
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
|
||||
Reference in New Issue
Block a user