From 8fa99209c389e8902988fa074d66dde86eb3d813 Mon Sep 17 00:00:00 2001 From: OG T Date: Sun, 29 Mar 2026 01:47:05 +0800 Subject: [PATCH] =?UTF-8?q?fix(web):=20OmniTerminal=20Escape=20=E9=97=9C?= =?UTF-8?q?=E9=96=89=20+=20=E9=9F=BF=E6=87=89=E5=BC=8F=E5=BA=95=E9=83=A8?= =?UTF-8?q?=E6=8A=BD=E5=B1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 19.R - 修復 UX 問題: - 新增 Escape 鍵關閉 Terminal (之前僅有 CMD+J) - Mobile: 全螢幕改為 70vh 底部抽屜 - 新增半透明 backdrop,點擊可關閉 - 響應式: Mobile/Tablet/Desktop 三級適配 修復問題: Terminal 開啟後無法關閉 Co-Authored-By: Claude Opus 4.5 --- .../src/components/terminal/OmniTerminal.tsx | 61 ++++++++++++------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/apps/web/src/components/terminal/OmniTerminal.tsx b/apps/web/src/components/terminal/OmniTerminal.tsx index cf53bf8d9..943626a15 100644 --- a/apps/web/src/components/terminal/OmniTerminal.tsx +++ b/apps/web/src/components/terminal/OmniTerminal.tsx @@ -22,6 +22,7 @@ */ import React, { useEffect, useRef, useState } from 'react' +import { useTranslations } from 'next-intl' import { useTerminalStore, useIsConnected, @@ -34,6 +35,7 @@ import { Z_INDEX } from '@/lib/constants/z-index' import { SHORTCUTS, matchShortcut } from '@/lib/constants/shortcuts' export const OmniTerminal = () => { + const t = useTranslations('omniTerminal') // Use optimized selectors for better re-render performance const isOpen = useIsTerminalOpen() const messages = useTerminalMessages() @@ -44,16 +46,24 @@ export const OmniTerminal = () => { const inputRef = useRef(null) const scrollRef = useRef(null) - // CMD+J 快捷鍵 (Phase 19 - 避免 CMD+K 瀏覽器衝突) + // 快捷鍵處理 (Phase 19 - 完整鍵盤支援) useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { - // CMD+J: Toggle Terminal + // CMD+J: Toggle Terminal (全局) if (matchShortcut(e, SHORTCUTS.TOGGLE_TERMINAL)) { e.preventDefault() toggleTerminal() return } - // '/': Quick open (非輸入框時) + + // Escape: 關閉 Terminal (當 Terminal 開啟時) + if (e.key === 'Escape' && isOpen) { + e.preventDefault() + toggleTerminal() + return + } + + // '/': Quick open (非輸入框時,Terminal 關閉時) if (e.key === '/' && !isOpen && document.activeElement?.tagName !== 'INPUT') { e.preventDefault() openTerminal() @@ -162,26 +172,30 @@ export const OmniTerminal = () => { } return ( -
- {/* Responsive container: - - Mobile: Full screen - - Tablet: 90% width - - Desktop: max-w-4xl centered */} + <> + {/* Backdrop overlay for mobile - 點擊可關閉 */} + ) }