From 2d0ed0f69c29d3dabf1f0a9f4f38bd1ac2d6c04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E8=8B=B1=E4=B8=9C?= Date: Wed, 21 Jan 2026 21:51:15 +0800 Subject: [PATCH] refactor(ui): update the UI of the code file --- .../code/blob/[version]/[...path]/index.tsx | 114 ++++++++++++++---- 1 file changed, 90 insertions(+), 24 deletions(-) diff --git a/moon/apps/web/pages/[org]/code/blob/[version]/[...path]/index.tsx b/moon/apps/web/pages/[org]/code/blob/[version]/[...path]/index.tsx index 8cfc67d21..a59d6b90c 100644 --- a/moon/apps/web/pages/[org]/code/blob/[version]/[...path]/index.tsx +++ b/moon/apps/web/pages/[org]/code/blob/[version]/[...path]/index.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useCallback, useEffect, useRef, useState } from 'react' import { Theme } from '@radix-ui/themes' import { useParams } from 'next/navigation' @@ -10,25 +10,10 @@ import { AppLayout } from '@/components/Layout/AppLayout' import AuthAppProviders from '@/components/Providers/AuthAppProviders' import { useGetBlob } from '@/hooks/useGetBlob' -const codeStyle = { - borderRadius: 8, - width: '80%', - background: '#fff', - display: 'flex', - flexDirection: 'column' as const, - overflow: 'hidden', - paddingRight: '8px' -} - -const treeStyle = { - borderRadius: 8, - width: '20%', - minWidth: '300px', - flexShrink: 0, - background: '#fff', - overflow: 'auto', - paddingRight: '8px' -} +const MIN_LEFT_WIDTH = 250 +const MAX_LEFT_WIDTH_PERCENT = 0.4 // Reduced from 0.5 to 0.4 to ensure right side has enough space +const DEFAULT_LEFT_WIDTH_PERCENT = 0.2 +const MIN_RIGHT_WIDTH = 500 // Add minimum width constraint for right side function BlobPage() { const params = useParams() @@ -40,17 +25,98 @@ function BlobPage() { const { data: blobData, isLoading: isCodeLoading } = useGetBlob({ path: new_path, refs }) const fileContent = blobData?.data ?? '' + // Resizable panel state + const containerRef = useRef(null) + const [leftWidth, setLeftWidth] = useState(null) + const [isDragging, setIsDragging] = useState(false) + + // Initialize left width based on container width + useEffect(() => { + if (containerRef.current && leftWidth === null) { + setLeftWidth(containerRef.current.offsetWidth * DEFAULT_LEFT_WIDTH_PERCENT) + } + }, [leftWidth]) + + const handleMouseDown = useCallback((e: React.MouseEvent) => { + e.preventDefault() + setIsDragging(true) + }, []) + + const handleMouseMove = useCallback( + (e: MouseEvent) => { + if (!isDragging || !containerRef.current) return + + const containerRect = containerRef.current.getBoundingClientRect() + const newLeftWidth = e.clientX - containerRect.left + const maxWidth = containerRect.width * MAX_LEFT_WIDTH_PERCENT + + // Ensure right side has at least MIN_RIGHT_WIDTH width + const maxAllowedLeftWidth = Math.min(maxWidth, containerRect.width - MIN_RIGHT_WIDTH) + + setLeftWidth(Math.max(MIN_LEFT_WIDTH, Math.min(newLeftWidth, maxAllowedLeftWidth))) + }, + [isDragging] + ) + + const handleMouseUp = useCallback(() => { + setIsDragging(false) + }, []) + + useEffect(() => { + if (isDragging) { + document.addEventListener('mousemove', handleMouseMove) + document.addEventListener('mouseup', handleMouseUp) + document.body.style.cursor = 'col-resize' + document.body.style.userSelect = 'none' + } + + return () => { + document.removeEventListener('mousemove', handleMouseMove) + document.removeEventListener('mouseup', handleMouseUp) + document.body.style.cursor = '' + document.body.style.userSelect = '' + } + }, [isDragging, handleMouseMove, handleMouseUp]) + return (
- {/* tree */} -
-
+ {/* File tree */} +
+
-
+ {/* Resizer handle */} +
+ +