- 将ChangelogPage修改为懒加载,减少主入口chunk体积 - 在频率图表中添加Y轴刻度范围按钮,支持点击展开下拉菜单选择范围 - 实现点击菜单外部自动收起功能,提升用户体验 - 调整Y轴刻度标签显示,避免与按钮重叠 - 移除原有的刻度范围切换静态按钮,改用动态菜单方式展示 - 更新相关样式,提升界面一致性和美观性
This commit is contained in:
+11
-2
@@ -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 <Suspense fallback={<PageLoader />}>{children}</Suspense>;
|
||||
@@ -54,6 +55,14 @@ function EffectsPageRoute() {
|
||||
);
|
||||
}
|
||||
|
||||
function ChangelogPageRoute() {
|
||||
return (
|
||||
<LazyRoute>
|
||||
<ChangelogPage />
|
||||
</LazyRoute>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
<Route path="/select" component={SelectPage} />
|
||||
<Route path="/ai" component={AIPageRoute} />
|
||||
<Route path="/community" component={CommunityPage} />
|
||||
<Route path="/changelog" component={ChangelogPage} />
|
||||
<Route path="/changelog" component={ChangelogPageRoute} />
|
||||
<Route path="/404" component={NotFound} />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
|
||||
@@ -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<HTMLDivElement | null>(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
|
||||
</span>
|
||||
</button>
|
||||
{/* Y 轴刻度范围切换 */}
|
||||
<div
|
||||
className="ml-auto flex shrink-0 items-center overflow-hidden rounded-[8px]"
|
||||
style={{ background: "rgba(44,44,46,0.7)", border: "1px solid rgba(255,255,255,0.08)" }}
|
||||
>
|
||||
{Y_RANGE_OPTIONS.map((r) => (
|
||||
<button
|
||||
key={r}
|
||||
type="button"
|
||||
className="px-2 py-1 text-[10px] transition-all duration-150"
|
||||
style={
|
||||
yDbMax === r
|
||||
? { background: "#00FFF6", color: "#000", fontWeight: 600 }
|
||||
: { color: "rgba(255,255,255,0.4)" }
|
||||
}
|
||||
onClick={() => handleYRangeChange(r)}
|
||||
>
|
||||
±{r}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* A/B + DIFF controls */}
|
||||
@@ -399,9 +395,43 @@ export function FreqChart({
|
||||
{/* SVG chart */}
|
||||
<div
|
||||
ref={chartContainerRef}
|
||||
className="rounded-[10px] overflow-hidden"
|
||||
className="relative rounded-[10px] overflow-hidden"
|
||||
style={{ background: "rgba(10,12,10,0.7)" }}
|
||||
>
|
||||
{/* Y 轴刻度范围:Y 轴顶端单按钮,点击展开下拉选项 */}
|
||||
<div ref={yRangeMenuRef} className="absolute left-1 top-1 z-20">
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-1 rounded-[8px] px-2 py-1 text-[12px] font-semibold text-[#00FFF6] active:opacity-80 transition-opacity"
|
||||
style={{ background: "rgba(44,44,46,0.85)", border: "1px solid rgba(255,255,255,0.12)" }}
|
||||
onClick={() => setIsYRangeMenuOpen(v => !v)}
|
||||
>
|
||||
<ZoomIn size={12} />
|
||||
{yDbMax}
|
||||
<ChevronDown size={12} className={`transition-transform ${isYRangeMenuOpen ? "rotate-180" : ""}`} />
|
||||
</button>
|
||||
{isYRangeMenuOpen && (
|
||||
<div
|
||||
className="absolute left-0 top-full mt-1 w-[64px] overflow-hidden rounded-[8px]"
|
||||
style={{ background: "rgba(10,12,16,0.98)", border: "1px solid rgba(0,255,246,0.35)", boxShadow: "0 8px 20px rgba(0,0,0,0.45)" }}
|
||||
>
|
||||
{Y_RANGE_OPTIONS.map((r) => (
|
||||
<button
|
||||
key={r}
|
||||
type="button"
|
||||
className={`w-full px-2 py-1.5 text-left text-[11px] transition-colors ${yDbMax === r ? "text-black font-semibold" : "text-white/90 hover:bg-white/10"}`}
|
||||
style={yDbMax === r ? { background: "#00FFF6" } : undefined}
|
||||
onClick={() => {
|
||||
handleYRangeChange(r);
|
||||
setIsYRangeMenuOpen(false);
|
||||
}}
|
||||
>
|
||||
{r}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<svg
|
||||
ref={svgRef}
|
||||
viewBox={`0 0 ${W} ${H}`}
|
||||
@@ -419,13 +449,16 @@ export function FreqChart({
|
||||
</clipPath>
|
||||
</defs>
|
||||
{/* dB grid */}
|
||||
{gainLabels.map((g) => (
|
||||
{gainLabels.map((g, gi) => (
|
||||
<g key={`gain-${g}`}>
|
||||
<line x1="0" y1={gainToY(g)} x2={W} y2={gainToY(g)}
|
||||
stroke="rgba(255,255,255,0.05)" strokeWidth="1" />
|
||||
{/* 顶格标签位置被 Y 轴范围按钮占用,避免文字重叠 */}
|
||||
{gi > 0 && (
|
||||
<text x="3" y={gainToY(g) - 2} fontSize="7" fill="rgba(255,255,255,0.2)">
|
||||
{formatGainLabel(g)}
|
||||
</text>
|
||||
)}
|
||||
</g>
|
||||
))}
|
||||
{/* Freq grid */}
|
||||
|
||||
Reference in New Issue
Block a user