diff --git a/src/features/authFiles/uiState.ts b/src/features/authFiles/uiState.ts index 542d66e..5631fae 100644 --- a/src/features/authFiles/uiState.ts +++ b/src/features/authFiles/uiState.ts @@ -15,6 +15,7 @@ export type AuthFilesUiState = { }; const AUTH_FILES_UI_STATE_KEY = 'authFilesPage.uiState'; +const AUTH_FILES_COMPACT_MODE_KEY = 'authFilesPage.compactMode'; const AUTH_FILES_SORT_MODE_SET = new Set(AUTH_FILES_SORT_MODES); export const isAuthFilesSortMode = (value: unknown): value is AuthFilesSortMode => @@ -40,3 +41,23 @@ export const writeAuthFilesUiState = (state: AuthFilesUiState) => { // ignore } }; + +export const readPersistedAuthFilesCompactMode = (): boolean | null => { + if (typeof window === 'undefined') return null; + try { + const raw = window.localStorage.getItem(AUTH_FILES_COMPACT_MODE_KEY); + if (raw === null) return null; + return JSON.parse(raw) === true; + } catch { + return null; + } +}; + +export const writePersistedAuthFilesCompactMode = (compactMode: boolean) => { + if (typeof window === 'undefined') return; + try { + window.localStorage.setItem(AUTH_FILES_COMPACT_MODE_KEY, JSON.stringify(compactMode)); + } catch { + // ignore + } +}; diff --git a/src/pages/AuthFilesPage.tsx b/src/pages/AuthFilesPage.tsx index cbc61f3..225de57 100644 --- a/src/pages/AuthFilesPage.tsx +++ b/src/pages/AuthFilesPage.tsx @@ -53,7 +53,9 @@ import { useAuthFilesStatusBarCache } from '@/features/authFiles/hooks/useAuthFi import { isAuthFilesSortMode, readAuthFilesUiState, + readPersistedAuthFilesCompactMode, writeAuthFilesUiState, + writePersistedAuthFilesCompactMode, type AuthFilesSortMode, } from '@/features/authFiles/uiState'; import { useAuthStore, useNotificationStore, useThemeStore } from '@/stores'; @@ -88,6 +90,7 @@ export function AuthFilesPage() { const [viewMode, setViewMode] = useState<'diagram' | 'list'>('list'); const [sortMode, setSortMode] = useState('default'); const [batchActionBarVisible, setBatchActionBarVisible] = useState(false); + const [uiStateHydrated, setUiStateHydrated] = useState(false); const floatingBatchActionsRef = useRef(null); const batchActionAnimationRef = useRef(null); const previousSelectionCountRef = useRef(0); @@ -176,46 +179,58 @@ export function AuthFilesPage() { const pageSize = compactMode ? pageSizeByMode.compact : pageSizeByMode.regular; useEffect(() => { - const persisted = readAuthFilesUiState(); - if (!persisted) return; + const persistedCompactMode = readPersistedAuthFilesCompactMode(); + if (typeof persistedCompactMode === 'boolean') { + setCompactMode(persistedCompactMode); + } - if (typeof persisted.filter === 'string' && persisted.filter.trim()) { - setFilter(persisted.filter); - } - if (typeof persisted.problemOnly === 'boolean') { - setProblemOnly(persisted.problemOnly); - } - if (typeof persisted.compactMode === 'boolean') { - setCompactMode(persisted.compactMode); - } - if (typeof persisted.search === 'string') { - setSearch(persisted.search); - } - if (typeof persisted.page === 'number' && Number.isFinite(persisted.page)) { - setPage(Math.max(1, Math.round(persisted.page))); - } - const legacyPageSize = - typeof persisted.pageSize === 'number' && Number.isFinite(persisted.pageSize) - ? clampCardPageSize(persisted.pageSize) - : null; - const regularPageSize = - typeof persisted.regularPageSize === 'number' && Number.isFinite(persisted.regularPageSize) - ? clampCardPageSize(persisted.regularPageSize) - : legacyPageSize ?? DEFAULT_REGULAR_PAGE_SIZE; - const compactPageSize = - typeof persisted.compactPageSize === 'number' && Number.isFinite(persisted.compactPageSize) - ? clampCardPageSize(persisted.compactPageSize) - : legacyPageSize ?? DEFAULT_COMPACT_PAGE_SIZE; - setPageSizeByMode({ - regular: regularPageSize, - compact: compactPageSize, - }); - if (isAuthFilesSortMode(persisted.sortMode)) { - setSortMode(persisted.sortMode); + const persisted = readAuthFilesUiState(); + if (persisted) { + if (typeof persisted.filter === 'string' && persisted.filter.trim()) { + setFilter(persisted.filter); + } + if (typeof persisted.problemOnly === 'boolean') { + setProblemOnly(persisted.problemOnly); + } + if ( + typeof persistedCompactMode !== 'boolean' && + typeof persisted.compactMode === 'boolean' + ) { + setCompactMode(persisted.compactMode); + } + if (typeof persisted.search === 'string') { + setSearch(persisted.search); + } + if (typeof persisted.page === 'number' && Number.isFinite(persisted.page)) { + setPage(Math.max(1, Math.round(persisted.page))); + } + const legacyPageSize = + typeof persisted.pageSize === 'number' && Number.isFinite(persisted.pageSize) + ? clampCardPageSize(persisted.pageSize) + : null; + const regularPageSize = + typeof persisted.regularPageSize === 'number' && Number.isFinite(persisted.regularPageSize) + ? clampCardPageSize(persisted.regularPageSize) + : legacyPageSize ?? DEFAULT_REGULAR_PAGE_SIZE; + const compactPageSize = + typeof persisted.compactPageSize === 'number' && Number.isFinite(persisted.compactPageSize) + ? clampCardPageSize(persisted.compactPageSize) + : legacyPageSize ?? DEFAULT_COMPACT_PAGE_SIZE; + setPageSizeByMode({ + regular: regularPageSize, + compact: compactPageSize, + }); + if (isAuthFilesSortMode(persisted.sortMode)) { + setSortMode(persisted.sortMode); + } } + + setUiStateHydrated(true); }, []); useEffect(() => { + if (!uiStateHydrated) return; + writeAuthFilesUiState({ filter, problemOnly, @@ -227,7 +242,18 @@ export function AuthFilesPage() { compactPageSize: pageSizeByMode.compact, sortMode, }); - }, [filter, problemOnly, compactMode, search, page, pageSize, pageSizeByMode, sortMode]); + writePersistedAuthFilesCompactMode(compactMode); + }, [ + compactMode, + filter, + page, + pageSize, + pageSizeByMode, + problemOnly, + search, + sortMode, + uiStateHydrated, + ]); useEffect(() => { setPageSizeInput(String(pageSize));