移动端滚动按钮复用滚轮逻辑
This commit is contained in:
1 parent
f51d33af83
commit
26d236fd8c
3 files changed
+45
-12
No files matched your search
@@ -13,7 +13,7 @@ type MobileTab = "terminal" | "files" | "system";
|
||||
|
||||
export function TerminalMobile({ state, onBack }: TerminalMobileProps) {
|
||||
const [activeTab, setActiveTab] = React.useState<MobileTab>("terminal");
|
||||
const { syncTerminalSize, terminalInstance } = state;
|
||||
const { syncTerminalSize, terminalInstance, scrollTerminal } = state;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (activeTab !== "terminal") {
|
||||
@@ -27,15 +27,6 @@ export function TerminalMobile({ state, onBack }: TerminalMobileProps) {
|
||||
term.focus();
|
||||
}, [activeTab, syncTerminalSize, terminalInstance]);
|
||||
|
||||
const handleScroll = React.useCallback((direction: "up" | "down") => {
|
||||
const term = terminalInstance.current;
|
||||
if (!term) {
|
||||
return;
|
||||
}
|
||||
const lines = direction === "up" ? -8 : 8;
|
||||
term.scrollLines(lines);
|
||||
}, [terminalInstance]);
|
||||
|
||||
const actions = [
|
||||
{
|
||||
key: "language",
|
||||
@@ -151,7 +142,7 @@ export function TerminalMobile({ state, onBack }: TerminalMobileProps) {
|
||||
<div className="absolute right-4 bottom-4 flex flex-col gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleScroll("up")}
|
||||
onClick={() => scrollTerminal("up")}
|
||||
className={`h-10 w-10 rounded-full border text-base ${
|
||||
state.isDark
|
||||
? "border-slate-700 bg-slate-900/90 text-slate-200"
|
||||
@@ -163,7 +154,7 @@ export function TerminalMobile({ state, onBack }: TerminalMobileProps) {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleScroll("down")}
|
||||
onClick={() => scrollTerminal("down")}
|
||||
className={`h-10 w-10 rounded-full border text-base ${
|
||||
state.isDark
|
||||
? "border-slate-700 bg-slate-900/90 text-slate-200"
|
||||
|
||||
@@ -156,6 +156,7 @@ export function useTerminalSession(sessionId?: string) {
|
||||
autoReconnect: socketState.autoReconnect,
|
||||
setAutoReconnect: socketState.setAutoReconnect,
|
||||
syncTerminalSize: socketState.syncTerminalSize,
|
||||
scrollTerminal: socketState.scrollTerminal,
|
||||
handleReconnect: socketState.handleReconnect,
|
||||
handleCancelReconnect: socketState.handleCancelReconnect,
|
||||
sessionInfo: sessionInfoState.sessionInfo,
|
||||
|
||||
@@ -247,6 +247,46 @@ export function useTerminalSocket({
|
||||
const connectSocketRef = React.useRef(connectSocket);
|
||||
const sendInputRef = React.useRef(sendInput);
|
||||
const syncTerminalSizeRef = React.useRef(syncTerminalSize);
|
||||
const scrollTerminal = React.useCallback((direction: "up" | "down") => {
|
||||
const term = terminalInstance.current;
|
||||
const container = terminalRef.current;
|
||||
if (!term || !container) {
|
||||
return;
|
||||
}
|
||||
if (term.modes.mouseTrackingMode !== "none") {
|
||||
return;
|
||||
}
|
||||
const lineDelta = direction === "up" ? -8 : 8;
|
||||
const sendTmuxWheelPage = (delta: number) => {
|
||||
if (delta === 0) {
|
||||
return;
|
||||
}
|
||||
const sequence = delta < 0 ? "\x1b[5~" : "\x1b[6~";
|
||||
sendInput(sequence);
|
||||
};
|
||||
const activeBuffer = term.buffer.active;
|
||||
const hasLocalScrollback = activeBuffer.type === "normal" && activeBuffer.baseY > 0;
|
||||
if (!hasLocalScrollback) {
|
||||
sendTmuxWheelPage(lineDelta);
|
||||
return;
|
||||
}
|
||||
const viewport = container.querySelector<HTMLElement>(".xterm-viewport");
|
||||
if (viewport) {
|
||||
const maxScrollTop = Math.max(0, viewport.scrollHeight - viewport.clientHeight);
|
||||
const isAtTop = viewport.scrollTop <= 0;
|
||||
const isAtBottom = viewport.scrollTop >= maxScrollTop;
|
||||
const isEnhancedSession = enhancedSessionRef.current;
|
||||
if (isEnhancedSession && lineDelta < 0 && isAtTop) {
|
||||
sendTmuxWheelPage(lineDelta);
|
||||
return;
|
||||
}
|
||||
if (isEnhancedSession && lineDelta > 0 && isAtBottom) {
|
||||
sendTmuxWheelPage(lineDelta);
|
||||
return;
|
||||
}
|
||||
}
|
||||
term.scrollLines(lineDelta);
|
||||
}, [sendInput, enhancedSessionRef]);
|
||||
|
||||
React.useEffect(() => {
|
||||
connectSocketRef.current = connectSocket;
|
||||
@@ -461,6 +501,7 @@ export function useTerminalSocket({
|
||||
autoReconnect,
|
||||
setAutoReconnect,
|
||||
syncTerminalSize,
|
||||
scrollTerminal,
|
||||
handleReconnect,
|
||||
handleCancelReconnect,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user