From 6d2f0cb95c41219f721ba5b2585f58e881d0c8cd Mon Sep 17 00:00:00 2001 From: dengqichen Date: Sat, 6 Dec 2025 23:47:20 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99ssh=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E9=80=9A=E7=94=A8=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Terminal/TerminalSplitDivider.tsx | 32 +++------------ .../src/components/Terminal/index.module.less | 41 +++++++++++++++++++ .../src/components/Terminal/useSplitView.ts | 35 +++++++++++++--- 3 files changed, 76 insertions(+), 32 deletions(-) diff --git a/frontend/src/components/Terminal/TerminalSplitDivider.tsx b/frontend/src/components/Terminal/TerminalSplitDivider.tsx index 44a28a1f..1a529913 100644 --- a/frontend/src/components/Terminal/TerminalSplitDivider.tsx +++ b/frontend/src/components/Terminal/TerminalSplitDivider.tsx @@ -4,6 +4,7 @@ */ import React, { useRef, useState, useEffect } from 'react'; import type { LayoutOrientation } from './types'; +import styles from './index.module.less'; interface TerminalSplitDividerProps { orientation: LayoutOrientation; @@ -56,6 +57,7 @@ export const TerminalSplitDivider: React.FC = ({ orie ? (orientation === 'horizontal' ? container.clientWidth : container.clientHeight) : undefined; + console.log(`[TerminalSplitDivider] onResize, orientation: ${orientation}, delta: ${delta}, containerSize: ${containerSize}`); onResize(delta, containerSize); lastMousePosRef.current = currentMousePos; }; @@ -79,6 +81,7 @@ export const TerminalSplitDivider: React.FC = ({ orie const handleMouseDown = (e: React.MouseEvent) => { e.preventDefault(); + console.log(`[TerminalSplitDivider] mouseDown, orientation: ${orientation}`); const initialPos = orientation === 'horizontal' ? e.clientX : e.clientY; startPosRef.current = initialPos; lastMousePosRef.current = initialPos; @@ -88,33 +91,8 @@ export const TerminalSplitDivider: React.FC = ({ orie return (
- {/* 中心可见线 */} -
- - {/* 拖动热区 - 增加可拖动区域 */} -
-
+ /> ); }; diff --git a/frontend/src/components/Terminal/index.module.less b/frontend/src/components/Terminal/index.module.less index ec5da153..5dd0d44a 100644 --- a/frontend/src/components/Terminal/index.module.less +++ b/frontend/src/components/Terminal/index.module.less @@ -22,6 +22,21 @@ border-bottom: 1px solid #374151; } +/* 搜索栏样式 */ +.searchBar { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + background: #f9fafb; + border-bottom: 1px solid #e5e7eb; +} + +:global(.dark) .searchBar { + background: #1f2937; + border-bottom: 1px solid #374151; +} + .left { display: flex; align-items: center; @@ -204,3 +219,29 @@ width: 150px; } } + +/* 分隔线样式 */ +.divider { + flex-shrink: 0; + z-index: 10; + background-color: #9ca3af; + transition: all 150ms; + + &:hover { + background-color: rgb(59 130 246 / 1); + } + + &.dragging { + background-color: rgb(59 130 246 / 1); + } + + &.horizontal { + width: 4px; + cursor: col-resize; + } + + &.vertical { + height: 4px; + cursor: row-resize; + } +} diff --git a/frontend/src/components/Terminal/useSplitView.ts b/frontend/src/components/Terminal/useSplitView.ts index 72079bcb..0b3d7a7b 100644 --- a/frontend/src/components/Terminal/useSplitView.ts +++ b/frontend/src/components/Terminal/useSplitView.ts @@ -6,6 +6,22 @@ import { useState, useCallback } from 'react'; import type { EditorGroup, TerminalTab, SplitDirection, SplitLayout, SplitNode, SplitContainer, LayoutOrientation } from './types'; import { TerminalInstanceManager } from './core/TerminalInstanceManager'; +/** + * 根据容器尺寸和方向计算最小尺寸(像素) + * @param containerSize 容器尺寸(px) + * @param orientation 分割方向 + * @returns 最小尺寸(px) + */ +const getMinSize = (containerSize: number, orientation: LayoutOrientation): number => { + if (orientation === 'horizontal') { + // 左右分屏:最小宽度520px + return 520; + } else { + // 上下分屏:根据容器高度计算,最小200px,最多占40% + return Math.max(200, Math.min(containerSize * 0.4, 300)); + } +}; + interface UseSplitViewOptions { initialTab: TerminalTab; onWindowClose?: () => void; // 最后一个Tab关闭时的回调 @@ -370,12 +386,19 @@ export const useSplitView = ({ initialTab, onWindowClose }: UseSplitViewOptions) // 调整分屏大小 const resizeGroups = useCallback((nodeId: string, delta: number, containerSize?: number) => { + console.log(`[useSplitView.resizeGroups] nodeId: ${nodeId}, delta: ${delta}, containerSize: ${containerSize}`); setLayout(prev => { const result = findParent(prev.root, nodeId); - if (!result || !result.parent) return prev; + if (!result || !result.parent) { + console.log(`[useSplitView.resizeGroups] findParent failed`); + return prev; + } const { parent, index } = result; - if (index >= parent.children.length - 1) return prev; + if (index >= parent.children.length - 1) { + console.log(`[useSplitView.resizeGroups] index check failed: ${index} >= ${parent.children.length - 1}`); + return prev; + } const current = parent.children[index]; const next = parent.children[index + 1]; @@ -385,12 +408,14 @@ export const useSplitView = ({ initialTab, onWindowClose }: UseSplitViewOptions) // delta是像素值,需要转换为百分比:(delta / containerSize) * totalSize const deltaPercent = containerSize ? (delta / containerSize) * totalSize : delta; - // 计算最小尺寸百分比:520px / 容器尺寸 * 100 - // 如果没有容器尺寸,使用默认20%作为兜底 - const minSizePercent = containerSize ? Math.min(50, (520 / containerSize) * 100) : 20; + // 计算最小尺寸百分比:使用totalSize的20%作为最小值 + // 这样每个分屏至少占两个分屏总和的20%(例如:总100%时,最小20%) + const minSizePercent = totalSize * 0.2; const newCurrentSize = Math.max(minSizePercent, Math.min(totalSize - minSizePercent, current.size + deltaPercent)); const newNextSize = totalSize - newCurrentSize; + + console.log(`[useSplitView.resizeGroups] current.size: ${current.size}, deltaPercent: ${deltaPercent}, newCurrentSize: ${newCurrentSize}, newNextSize: ${newNextSize}`); const newChildren = parent.children.map((child, i) => { if (i === index) return { ...child, size: newCurrentSize };