增加AI页面在其它页面的展示
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user