import { useCallback, useEffect, useRef, useState } from 'react'; import { DEFAULT_SORT_DIRECTION, DEFAULT_SORT_FIELD, SORT_FIELD_VALUES, } from './appLayoutUtils'; const VIEW_MODE_STORAGE_KEY = 'papercrate_view_mode'; const SORT_FIELD_STORAGE_KEY = 'papercrate_sort_field'; const SORT_DIRECTION_STORAGE_KEY = 'papercrate_sort_direction'; const INCLUDE_DESCENDANTS_STORAGE_KEY = 'papercrate_include_descendants'; const readSessionStorage = (key: string): string | null => { try { return window.sessionStorage.getItem(key); } catch (error) { console.warn(`[session-storage] failed to read ${key}`, error); return null; } }; const writeSessionStorage = (key: string, value: string): void => { try { window.sessionStorage.setItem(key, value); } catch (error) { console.warn(`[session-storage] failed to persist ${key}`, error); } }; export const useDocumentsPreferences = () => { const [documentsViewMode, setDocumentsViewModeState] = useState<'list' | 'grid' | 'desk'>(() => { const stored = readSessionStorage(VIEW_MODE_STORAGE_KEY); if (stored === 'grid' || stored === 'desk') { return stored; } return 'list'; }); const lastNonDeskViewRef = useRef<'list' | 'grid'>((documentsViewMode === 'desk' ? 'list' : documentsViewMode) as 'list' | 'grid'); const setDocumentsViewMode = useCallback((mode: string) => { const next = mode === 'grid' ? 'grid' : mode === 'desk' ? 'desk' : 'list'; setDocumentsViewModeState((previous) => { if (next !== previous) { writeSessionStorage(VIEW_MODE_STORAGE_KEY, next); } return next; }); }, []); const handleDeskExit = useCallback(() => { const fallback = lastNonDeskViewRef.current && lastNonDeskViewRef.current !== 'desk' ? lastNonDeskViewRef.current : 'list'; setDocumentsViewMode(fallback); }, [setDocumentsViewMode]); const [documentsSortField, setDocumentsSortField] = useState(() => { const stored = readSessionStorage(SORT_FIELD_STORAGE_KEY); return SORT_FIELD_VALUES.includes(stored) ? stored : DEFAULT_SORT_FIELD; }); const documentsSortFieldRef = useRef(documentsSortField); useEffect(() => { documentsSortFieldRef.current = documentsSortField; writeSessionStorage(SORT_FIELD_STORAGE_KEY, documentsSortField); }, [documentsSortField]); const [documentsSortDirection, setDocumentsSortDirection] = useState(() => { const stored = readSessionStorage(SORT_DIRECTION_STORAGE_KEY); return stored === 'desc' || stored === 'asc' ? stored : DEFAULT_SORT_DIRECTION; }); const documentsSortDirectionRef = useRef(documentsSortDirection); useEffect(() => { documentsSortDirectionRef.current = documentsSortDirection; writeSessionStorage(SORT_DIRECTION_STORAGE_KEY, documentsSortDirection); }, [documentsSortDirection]); const handleDocumentsSortFieldChange = useCallback((field: string) => { const nextField = SORT_FIELD_VALUES.includes(field) ? field : DEFAULT_SORT_FIELD; setDocumentsSortField((previous) => (previous === nextField ? previous : nextField)); }, []); const handleDocumentsSortDirectionToggle = useCallback(() => { setDocumentsSortDirection((previous) => (previous === 'asc' ? 'desc' : 'asc')); }, []); const [searchIncludeDescendants, setSearchIncludeDescendants] = useState(() => { const stored = readSessionStorage(INCLUDE_DESCENDANTS_STORAGE_KEY); if (stored === 'true') return true; if (stored === 'false') return false; return true; }); useEffect(() => { writeSessionStorage( INCLUDE_DESCENDANTS_STORAGE_KEY, searchIncludeDescendants ? 'true' : 'false', ); }, [searchIncludeDescendants]); const toggleSearchIncludeDescendants = useCallback(() => { setSearchIncludeDescendants((previous) => !previous); }, []); const sortRefreshReadyRef = useRef(false); return { documentsViewMode, handleDocumentsViewModeChange: setDocumentsViewMode, handleDeskExit, documentsSortField, documentsSortDirection, documentsSortFieldRef, documentsSortDirectionRef, handleDocumentsSortFieldChange, handleDocumentsSortDirectionToggle, searchIncludeDescendants, setSearchIncludeDescendants, toggleSearchIncludeDescendants, sortRefreshReadyRef, }; };