mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-01 18:28:38 +00:00
refactor(palette-ops): flatten Handle wrapper into ref-based registry
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { createContext, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
|
||||
import { createContext, useContext, useEffect, useMemo, useRef } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export type PaletteOps = {
|
||||
@@ -7,64 +7,47 @@ export type PaletteOps = {
|
||||
refreshProjects: () => Promise<void> | void;
|
||||
};
|
||||
|
||||
type Handle = {
|
||||
handlersRef: React.MutableRefObject<Partial<PaletteOps>>;
|
||||
call: PaletteOps;
|
||||
type Registry = React.MutableRefObject<Partial<PaletteOps>>;
|
||||
|
||||
const PaletteOpsContext = createContext<Registry | null>(null);
|
||||
|
||||
const defaultOps: PaletteOps = {
|
||||
openFile: () => undefined,
|
||||
openSettings: () => undefined,
|
||||
refreshProjects: () => undefined,
|
||||
};
|
||||
|
||||
const PaletteOpsContext = createContext<Handle | null>(null);
|
||||
|
||||
const noop = () => undefined;
|
||||
|
||||
export function PaletteOpsProvider({ children }: { children: ReactNode }) {
|
||||
const handlersRef = useRef<Partial<PaletteOps>>({});
|
||||
|
||||
const call = useMemo<PaletteOps>(
|
||||
() => ({
|
||||
openFile: (path) => handlersRef.current.openFile?.(path),
|
||||
openSettings: (tab) => handlersRef.current.openSettings?.(tab),
|
||||
refreshProjects: () => handlersRef.current.refreshProjects?.() ?? undefined,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
const value = useMemo<Handle>(() => ({ handlersRef, call }), [call]);
|
||||
|
||||
return <PaletteOpsContext.Provider value={value}>{children}</PaletteOpsContext.Provider>;
|
||||
const ref = useRef<Partial<PaletteOps>>({});
|
||||
return <PaletteOpsContext.Provider value={ref}>{children}</PaletteOpsContext.Provider>;
|
||||
}
|
||||
|
||||
export function usePaletteOps(): PaletteOps {
|
||||
const handle = useContext(PaletteOpsContext);
|
||||
if (!handle) {
|
||||
return { openFile: noop, openSettings: noop, refreshProjects: noop };
|
||||
}
|
||||
return handle.call;
|
||||
const ref = useContext(PaletteOpsContext);
|
||||
return useMemo<PaletteOps>(
|
||||
() => ({
|
||||
openFile: (path) => (ref?.current.openFile ?? defaultOps.openFile)(path),
|
||||
openSettings: (tab) => (ref?.current.openSettings ?? defaultOps.openSettings)(tab),
|
||||
refreshProjects: () => (ref?.current.refreshProjects ?? defaultOps.refreshProjects)(),
|
||||
}),
|
||||
[ref],
|
||||
);
|
||||
}
|
||||
|
||||
export function usePaletteOpsRegister(partial: Partial<PaletteOps>) {
|
||||
const handle = useContext(PaletteOpsContext);
|
||||
const openFile = partial.openFile;
|
||||
const openSettings = partial.openSettings;
|
||||
const refreshProjects = partial.refreshProjects;
|
||||
const ref = useContext(PaletteOpsContext);
|
||||
const { openFile, openSettings, refreshProjects } = partial;
|
||||
|
||||
const installer = useCallback(() => {
|
||||
if (!handle) return undefined;
|
||||
const prev = { ...handle.handlersRef.current };
|
||||
if (openFile) handle.handlersRef.current.openFile = openFile;
|
||||
if (openSettings) handle.handlersRef.current.openSettings = openSettings;
|
||||
if (refreshProjects) handle.handlersRef.current.refreshProjects = refreshProjects;
|
||||
useEffect(() => {
|
||||
if (!ref) return undefined;
|
||||
const prev = { ...ref.current };
|
||||
if (openFile) ref.current.openFile = openFile;
|
||||
if (openSettings) ref.current.openSettings = openSettings;
|
||||
if (refreshProjects) ref.current.refreshProjects = refreshProjects;
|
||||
return () => {
|
||||
if (openFile && handle.handlersRef.current.openFile === openFile) {
|
||||
handle.handlersRef.current.openFile = prev.openFile;
|
||||
}
|
||||
if (openSettings && handle.handlersRef.current.openSettings === openSettings) {
|
||||
handle.handlersRef.current.openSettings = prev.openSettings;
|
||||
}
|
||||
if (refreshProjects && handle.handlersRef.current.refreshProjects === refreshProjects) {
|
||||
handle.handlersRef.current.refreshProjects = prev.refreshProjects;
|
||||
}
|
||||
if (openFile && ref.current.openFile === openFile) ref.current.openFile = prev.openFile;
|
||||
if (openSettings && ref.current.openSettings === openSettings) ref.current.openSettings = prev.openSettings;
|
||||
if (refreshProjects && ref.current.refreshProjects === refreshProjects) ref.current.refreshProjects = prev.refreshProjects;
|
||||
};
|
||||
}, [handle, openFile, openSettings, refreshProjects]);
|
||||
|
||||
useEffect(() => installer(), [installer]);
|
||||
}, [ref, openFile, openSettings, refreshProjects]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user