增加AI页面在其它页面的展示

This commit is contained in:
allen2fuc
2026-05-08 18:15:52 +08:00
parent 9817ecca33
commit 68f06344dc
9 changed files with 334 additions and 15 deletions
+78
View File
@@ -0,0 +1,78 @@
import {
createContext,
useCallback,
useContext,
useMemo,
useState,
type Dispatch,
type ReactNode,
type SetStateAction,
} from "react";
const SPLIT_STORAGE_KEY = "luxsin-ai-split-pct";
const SPLIT_MIN = 28;
const SPLIT_MAX = 72;
function clampPct(n: number) {
return Math.min(SPLIT_MAX, Math.max(SPLIT_MIN, Math.round(n)));
}
function loadSplitPct(): number {
if (typeof window === "undefined") return 50;
try {
const v = sessionStorage.getItem(SPLIT_STORAGE_KEY);
if (v) {
const n = parseInt(v, 10);
if (!Number.isNaN(n)) return clampPct(n);
}
} catch {
/* ignore */
}
return 50;
}
type AIDrawerContextValue = {
/** Desktop split panel visible (only used when lg+ and route !== /ai) */
open: boolean;
setOpen: Dispatch<SetStateAction<boolean>>;
toggle: () => void;
/** Width share of the AI column (percent), used when split view is shown */
splitPercent: number;
setSplitPercent: (pct: number) => void;
};
const AIDrawerContext = createContext<AIDrawerContextValue | null>(null);
export function AIDrawerProvider({ children }: { children: ReactNode }) {
const [open, setOpen] = useState(false);
const [splitPercent, setSplitPercentState] = useState(loadSplitPct);
const toggle = useCallback(() => setOpen((o) => !o), []);
const setSplitPercent = useCallback((pct: number) => {
const next = clampPct(pct);
setSplitPercentState(next);
try {
sessionStorage.setItem(SPLIT_STORAGE_KEY, String(next));
} catch {
/* ignore */
}
}, []);
const value = useMemo(
() => ({ open, setOpen, toggle, splitPercent, setSplitPercent }),
[open, splitPercent, setSplitPercent, toggle],
);
return (
<AIDrawerContext.Provider value={value}>{children}</AIDrawerContext.Provider>
);
}
export function useAIDrawer() {
const ctx = useContext(AIDrawerContext);
if (!ctx) {
throw new Error("useAIDrawer must be used within AIDrawerProvider");
}
return ctx;
}