pass through a wrapper component

This commit is contained in:
Nate Kelley 2025-07-11 14:46:10 -06:00
parent de959ea090
commit 90a11d5fd8
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
4 changed files with 565 additions and 515 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
export const createAutoSaveId = (id: string) => `app-splitter-${id}`;
export const createAutoSaveId = (id: string) => `splitter-${id}`;
// Helper function to convert size values to pixels
export const sizeToPixels = (size: string | number, containerSize: number): number => {

View File

@ -27,7 +27,7 @@ interface Options<T> {
export function useLocalStorageState<T>(
key: string,
options?: Options<T>
): [T | undefined, (value?: SetState<T>) => void] {
): [T | undefined, (value?: SetState<T>) => void, () => T | undefined] {
const {
defaultValue,
serializer = JSON.stringify,
@ -37,22 +37,22 @@ export function useLocalStorageState<T>(
expirationTime = DEFAULT_EXPIRATION_TIME
} = options || {};
const executeBustStorage = useMemoizedFn(() => {
if (!isServer) window.localStorage.removeItem(key);
return typeof defaultValue === 'function' ? (defaultValue as () => T)() : defaultValue;
});
// Get initial value from localStorage or use default
const getInitialValue = useMemoizedFn((): T | undefined => {
const gonnaBustTheStorage = () => {
if (!isServer) window.localStorage.removeItem(key);
return typeof defaultValue === 'function' ? (defaultValue as () => T)() : defaultValue;
};
// If bustStorageOnInit is true, ignore localStorage and use default value
if (bustStorageOnInit === true) {
return gonnaBustTheStorage();
return executeBustStorage();
}
try {
const item = window.localStorage.getItem(key);
if (item === null) {
return gonnaBustTheStorage();
return executeBustStorage();
}
// Parse the stored data which includes value and timestamp
@ -66,7 +66,7 @@ export function useLocalStorageState<T>(
!('timestamp' in storageData)
) {
// If the data doesn't have the expected structure (legacy data), treat as expired
return gonnaBustTheStorage();
return executeBustStorage();
}
// Check if the data has expired
@ -75,24 +75,24 @@ export function useLocalStorageState<T>(
if (timeDifference > expirationTime) {
// Data has expired, remove it and return default value
return gonnaBustTheStorage();
return executeBustStorage();
}
// Data is still valid, deserialize and return the value
const deserializedValue = deserializer(JSON.stringify(storageData.value));
if (typeof bustStorageOnInit === 'function' && bustStorageOnInit(deserializedValue)) {
return gonnaBustTheStorage();
return executeBustStorage();
}
return deserializedValue;
} catch (error) {
onError?.(error);
return gonnaBustTheStorage();
return executeBustStorage();
}
});
const [state, setState] = useState<T | undefined>(getInitialValue);
const [state, setState] = useState<T | undefined>(() => getInitialValue());
// Initialize state from localStorage on mount
useMount(() => {
@ -133,5 +133,5 @@ export function useLocalStorageState<T>(
}
});
return [state, setStoredState];
return [state, setStoredState, executeBustStorage];
}

View File

@ -39,8 +39,14 @@ export const ChatLayout: React.FC<ChatSplitterProps> = ({ children }) => {
const renderLeftPanel = selectedLayout !== 'file-only';
const renderRightPanel = selectedLayout !== 'chat-only';
const secondaryFileView = chatLayoutProps.secondaryView;
const bustStorageOnInit =
selectedLayout === 'chat-only' || selectedLayout === 'file-only' || !!secondaryFileView;
const bustStorageOnInit = (preservedSideValue: number | null) => {
console.log('bustStorageOnInit', autoSaveId, preservedSideValue, {
selectedLayout,
secondaryFileView
});
return selectedLayout === 'chat-only' || selectedLayout === 'file-only' || !!secondaryFileView;
};
useMount(() => {
setMounted(true); //we need to wait for the app splitter to be mounted because this is nested in the app splitter