diff --git a/client/src/App.tsx b/client/src/App.tsx index 76579da..95695c7 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -16,7 +16,6 @@ import IOPage from "./pages/IOPage"; import VUPage from "./pages/VUPage"; import SelectPage, { consumeSelectReturnScroll } from "./pages/SelectPage"; import CommunityPage from "./pages/CommunityPage"; -import ChangelogPage from "./pages/ChangelogPage"; import { AIDrawerProvider } from "./contexts/AIDrawerContext"; import { NavConfigProvider, useNavConfig } from "./contexts/NavConfigContext"; import DesktopAIShell from "./components/DesktopAIShell"; @@ -25,6 +24,8 @@ import { appShellColumnClass, appShellOuterClass } from "./lib/appShell"; const EQPage = lazy(() => import("./pages/EQPage")); const EffectsPage = lazy(() => import("./pages/EffectsPage")); const AIPage = lazy(() => import("./pages/AIPage")); +// ChangelogPage 依赖 streamdown(shiki/mermaid/katex 重链),懒加载避免打入主入口 chunk +const ChangelogPage = lazy(() => import("./pages/ChangelogPage")); function LazyRoute({ children }: { children: React.ReactNode }) { return }>{children}; @@ -54,6 +55,14 @@ function EffectsPageRoute() { ); } +function ChangelogPageRoute() { + return ( + + + + ); +} + /** * Restores the calling page's scroll position when returning from /select. * The select page is short, so the browser clamps window scroll to 0 while on @@ -106,7 +115,7 @@ function AppRouter() { - + diff --git a/client/src/pages/eq/components/FreqChart.tsx b/client/src/pages/eq/components/FreqChart.tsx index b10f5b1..98f5b13 100644 --- a/client/src/pages/eq/components/FreqChart.tsx +++ b/client/src/pages/eq/components/FreqChart.tsx @@ -1,4 +1,5 @@ import { useState, useEffect, useRef, useMemo } from "react"; +import { ChevronDown, ZoomIn } from "lucide-react"; import { toast } from "sonner"; import { useStrokeDrawAnimation } from "@/lib/useStrokeDrawAnimation"; import { @@ -113,6 +114,22 @@ export function FreqChart({ } }; + const [isYRangeMenuOpen, setIsYRangeMenuOpen] = useState(false); + const yRangeMenuRef = useRef(null); + + // 点击菜单外部收起下拉 + useEffect(() => { + if (!isYRangeMenuOpen) return; + const onPointerDown = (event: PointerEvent) => { + const target = event.target as Node; + if (!(yRangeMenuRef.current?.contains(target) ?? false)) { + setIsYRangeMenuOpen(false); + } + }; + document.addEventListener("pointerdown", onPointerDown); + return () => document.removeEventListener("pointerdown", onPointerDown); + }, [isYRangeMenuOpen]); + useEffect(() => { const node = chartContainerRef.current; if (!node) return; @@ -317,27 +334,6 @@ export function FreqChart({ Equalized - {/* Y 轴刻度范围切换 */} -
- {Y_RANGE_OPTIONS.map((r) => ( - - ))} -
{/* A/B + DIFF controls */} @@ -399,9 +395,43 @@ export function FreqChart({ {/* SVG chart */}
+ {/* Y 轴刻度范围:Y 轴顶端单按钮,点击展开下拉选项 */} +
+ + {isYRangeMenuOpen && ( +
+ {Y_RANGE_OPTIONS.map((r) => ( + + ))} +
+ )} +
{/* dB grid */} - {gainLabels.map((g) => ( + {gainLabels.map((g, gi) => ( - - {formatGainLabel(g)} - + {/* 顶格标签位置被 Y 轴范围按钮占用,避免文字重叠 */} + {gi > 0 && ( + + {formatGainLabel(g)} + + )} ))} {/* Freq grid */}