122 lines
4.2 KiB
TypeScript
122 lines
4.2 KiB
TypeScript
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,
|
|
};
|
|
};
|