fix mobile terminal drawer sizing (#799)
This commit is contained in:
@@ -86,9 +86,10 @@ function handleClose() {
|
||||
.drawer-panel {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: -900px;
|
||||
width: 900px;
|
||||
height: 100vh;
|
||||
right: min(-1180px, -88vw);
|
||||
width: min(1180px, 88vw);
|
||||
height: calc(100 * var(--vh));
|
||||
max-height: calc(100 * var(--vh));
|
||||
background: $bg-card;
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
|
||||
display: flex;
|
||||
@@ -180,5 +181,3 @@ function handleClose() {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@@ -103,6 +103,9 @@ let activeFitAddon: FitAddon | null = null;
|
||||
let resizeObserver: ResizeObserver | null = null;
|
||||
let reconnectAttempts = 0;
|
||||
const MAX_RECONNECT_ATTEMPTS = 3;
|
||||
let touchScrollLastY: number | null = null;
|
||||
let touchScrollRemainder = 0;
|
||||
const TOUCH_SCROLL_LINE_PX = 18;
|
||||
|
||||
// ─── Computed ──────────────────────────────────────────────────
|
||||
|
||||
@@ -356,6 +359,35 @@ function sendResize() {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
function handleTerminalTouchStart(event: TouchEvent) {
|
||||
if (event.touches.length !== 1) {
|
||||
touchScrollLastY = null;
|
||||
touchScrollRemainder = 0;
|
||||
return;
|
||||
}
|
||||
touchScrollLastY = event.touches[0].clientY;
|
||||
touchScrollRemainder = 0;
|
||||
}
|
||||
|
||||
function handleTerminalTouchMove(event: TouchEvent) {
|
||||
if (!activeTerm || event.touches.length !== 1 || touchScrollLastY === null) return;
|
||||
const nextY = event.touches[0].clientY;
|
||||
touchScrollRemainder += touchScrollLastY - nextY;
|
||||
touchScrollLastY = nextY;
|
||||
|
||||
const lines = Math.trunc(touchScrollRemainder / TOUCH_SCROLL_LINE_PX);
|
||||
if (lines === 0) return;
|
||||
|
||||
activeTerm.scrollLines(lines);
|
||||
touchScrollRemainder -= lines * TOUCH_SCROLL_LINE_PX;
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
function handleTerminalTouchEnd() {
|
||||
touchScrollLastY = null;
|
||||
touchScrollRemainder = 0;
|
||||
}
|
||||
|
||||
// ─── Theme ───────────────────────────────────────────────────────
|
||||
|
||||
function applyTheme(themeName: string) {
|
||||
@@ -517,7 +549,15 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</header>
|
||||
<div class="terminal-container">
|
||||
<div ref="terminalRef" class="terminal-xterm" :style="{ backgroundColor: terminalBg }" />
|
||||
<div
|
||||
ref="terminalRef"
|
||||
class="terminal-xterm"
|
||||
:style="{ backgroundColor: terminalBg }"
|
||||
@touchstart="handleTerminalTouchStart"
|
||||
@touchmove="handleTerminalTouchMove"
|
||||
@touchend="handleTerminalTouchEnd"
|
||||
@touchcancel="handleTerminalTouchEnd"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -798,4 +838,35 @@ onUnmounted(() => {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $breakpoint-mobile) {
|
||||
.terminal-panel-drawer {
|
||||
height: calc(100 * var(--vh));
|
||||
max-height: calc(100 * var(--vh));
|
||||
}
|
||||
|
||||
.terminal-main {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.terminal-container {
|
||||
margin-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
|
||||
}
|
||||
|
||||
.terminal-xterm {
|
||||
:deep(.xterm-viewport),
|
||||
:deep(.xterm-scrollable-element) {
|
||||
touch-action: pan-y;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior: contain;
|
||||
scrollbar-width: thin !important;
|
||||
}
|
||||
|
||||
:deep(.xterm-viewport::-webkit-scrollbar),
|
||||
:deep(.xterm-scrollable-element::-webkit-scrollbar) {
|
||||
display: block !important;
|
||||
width: 6px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -245,6 +245,9 @@ let activeTerm: Terminal | null = null;
|
||||
let activeFitAddon: FitAddon | null = null;
|
||||
let resizeObserver: ResizeObserver | null = null;
|
||||
let mobileQuery: MediaQueryList | null = null;
|
||||
let touchScrollLastY: number | null = null;
|
||||
let touchScrollRemainder = 0;
|
||||
const TOUCH_SCROLL_LINE_PX = 18;
|
||||
|
||||
// ─── Computed ──────────────────────────────────────────────────
|
||||
|
||||
@@ -495,6 +498,35 @@ function sendResize() {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
function handleTerminalTouchStart(event: TouchEvent) {
|
||||
if (event.touches.length !== 1) {
|
||||
touchScrollLastY = null;
|
||||
touchScrollRemainder = 0;
|
||||
return;
|
||||
}
|
||||
touchScrollLastY = event.touches[0].clientY;
|
||||
touchScrollRemainder = 0;
|
||||
}
|
||||
|
||||
function handleTerminalTouchMove(event: TouchEvent) {
|
||||
if (!activeTerm || event.touches.length !== 1 || touchScrollLastY === null) return;
|
||||
const nextY = event.touches[0].clientY;
|
||||
touchScrollRemainder += touchScrollLastY - nextY;
|
||||
touchScrollLastY = nextY;
|
||||
|
||||
const lines = Math.trunc(touchScrollRemainder / TOUCH_SCROLL_LINE_PX);
|
||||
if (lines === 0) return;
|
||||
|
||||
activeTerm.scrollLines(lines);
|
||||
touchScrollRemainder -= lines * TOUCH_SCROLL_LINE_PX;
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
function handleTerminalTouchEnd() {
|
||||
touchScrollLastY = null;
|
||||
touchScrollRemainder = 0;
|
||||
}
|
||||
|
||||
// ─── Theme ───────────────────────────────────────────────────────
|
||||
|
||||
function applyTheme(themeName: string) {
|
||||
@@ -689,7 +721,15 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</header>
|
||||
<div class="terminal-container">
|
||||
<div ref="terminalRef" class="terminal-xterm" :style="{ backgroundColor: terminalBg }" />
|
||||
<div
|
||||
ref="terminalRef"
|
||||
class="terminal-xterm"
|
||||
:style="{ backgroundColor: terminalBg }"
|
||||
@touchstart="handleTerminalTouchStart"
|
||||
@touchmove="handleTerminalTouchMove"
|
||||
@touchend="handleTerminalTouchEnd"
|
||||
@touchcancel="handleTerminalTouchEnd"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -980,6 +1020,19 @@ onUnmounted(() => {
|
||||
// ─── Mobile ─────────────────────────────────────────────────────
|
||||
|
||||
@media (max-width: $breakpoint-mobile) {
|
||||
.terminal-panel {
|
||||
height: calc(100 * var(--vh));
|
||||
max-height: calc(100 * var(--vh));
|
||||
}
|
||||
|
||||
.terminal-main {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.terminal-container {
|
||||
margin-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
|
||||
}
|
||||
|
||||
.session-close-btn {
|
||||
display: flex;
|
||||
}
|
||||
@@ -1011,6 +1064,20 @@ onUnmounted(() => {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
:deep(.xterm-viewport),
|
||||
:deep(.xterm-scrollable-element) {
|
||||
touch-action: pan-y;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior: contain;
|
||||
scrollbar-width: thin !important;
|
||||
}
|
||||
|
||||
:deep(.xterm-viewport::-webkit-scrollbar),
|
||||
:deep(.xterm-scrollable-element::-webkit-scrollbar) {
|
||||
display: block !important;
|
||||
width: 6px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user