import { create } from "zustand" import { persist, createJSONStorage } from "zustand/middleware" type EntryListViewMode = "compact" | "comfortable" | "expanded" type DisplayDensity = "compact" | "default" | "spacious" type FontSize = "small" | "default" | "large" type TimeDisplayFormat = "relative" | "absolute" type ScrollbarStyle = "custom" | "native" | "hidden" type ToolbarPosition = "top" | "bottom" type FocusedPanel = "sidebar" | "entryList" | "detailPanel" type SettingsTab = | "subscriptions" | "folders" | "muted-phrases" | "custom-feeds" | "import-export" | "appearance" | "account" | "billing" | "api" | "danger" interface UserInterfaceState { isSidebarCollapsed: boolean isCommandPaletteOpen: boolean isAddFeedDialogOpen: boolean isSearchOpen: boolean selectedEntryIdentifier: string | null focusedEntryIdentifier: string | null focusedPanel: FocusedPanel focusedSidebarIndex: number entryListViewMode: EntryListViewMode displayDensity: DisplayDensity activeSettingsTab: SettingsTab showFeedFavicons: boolean focusFollowsInteraction: boolean fontSize: FontSize timeDisplayFormat: TimeDisplayFormat showEntryImages: boolean showReadingTime: boolean showFoldersAboveFeeds: boolean showEntryFavicons: boolean scrollbarStyle: ScrollbarStyle autoRefreshTimeline: boolean prioritiseUnreadEntries: boolean toolbarPosition: ToolbarPosition isEntryListAtTop: boolean isShortcutsDialogOpen: boolean expandedFolderIdentifiers: string[] currentFeedIdentifier: string | null currentFolderIdentifier: string | null navigableEntryIdentifiers: string[] resetSidebarLayout: (() => void) | null resetDetailLayout: (() => void) | null setCurrentFeedIdentifier: (identifier: string | null) => void setCurrentFolderIdentifier: (identifier: string | null) => void toggleSidebar: () => void setSidebarCollapsed: (isCollapsed: boolean) => void setCommandPaletteOpen: (isOpen: boolean) => void setAddFeedDialogOpen: (isOpen: boolean) => void setSearchOpen: (isOpen: boolean) => void setSelectedEntryIdentifier: (identifier: string | null) => void setFocusedEntryIdentifier: (identifier: string | null) => void setFocusedPanel: (panel: FocusedPanel) => void setFocusedSidebarIndex: (index: number) => void setEntryListViewMode: (mode: EntryListViewMode) => void setDisplayDensity: (density: DisplayDensity) => void setActiveSettingsTab: (tab: SettingsTab) => void setShowFeedFavicons: (show: boolean) => void setFocusFollowsInteraction: (enabled: boolean) => void setFontSize: (size: FontSize) => void setTimeDisplayFormat: (format: TimeDisplayFormat) => void setShowEntryImages: (show: boolean) => void setShowReadingTime: (show: boolean) => void setShowFoldersAboveFeeds: (show: boolean) => void setShowEntryFavicons: (show: boolean) => void setScrollbarStyle: (style: ScrollbarStyle) => void setAutoRefreshTimeline: (enabled: boolean) => void setPrioritiseUnreadEntries: (enabled: boolean) => void setToolbarPosition: (position: ToolbarPosition) => void setIsEntryListAtTop: (isAtTop: boolean) => void setShortcutsDialogOpen: (isOpen: boolean) => void toggleShortcutsDialog: () => void toggleFolderExpansion: (folderIdentifier: string) => void setNavigableEntryIdentifiers: (identifiers: string[]) => void setResetSidebarLayout: (callback: (() => void) | null) => void setResetDetailLayout: (callback: (() => void) | null) => void } export const useUserInterfaceStore = create()( persist( (set) => ({ isSidebarCollapsed: false, isCommandPaletteOpen: false, isAddFeedDialogOpen: false, isSearchOpen: false, selectedEntryIdentifier: null, focusedEntryIdentifier: null, focusedPanel: "entryList", focusedSidebarIndex: 0, entryListViewMode: "comfortable", displayDensity: "default", activeSettingsTab: "subscriptions", showFeedFavicons: true, focusFollowsInteraction: false, fontSize: "default", timeDisplayFormat: "relative", showEntryImages: true, showReadingTime: true, showFoldersAboveFeeds: false, showEntryFavicons: false, scrollbarStyle: "custom", autoRefreshTimeline: false, prioritiseUnreadEntries: false, toolbarPosition: "top", isEntryListAtTop: true, isShortcutsDialogOpen: false, expandedFolderIdentifiers: [], currentFeedIdentifier: null, currentFolderIdentifier: null, navigableEntryIdentifiers: [], resetSidebarLayout: null, resetDetailLayout: null, setCurrentFeedIdentifier: (identifier) => set({ currentFeedIdentifier: identifier }), setCurrentFolderIdentifier: (identifier) => set({ currentFolderIdentifier: identifier }), toggleSidebar: () => set((state) => ({ isSidebarCollapsed: !state.isSidebarCollapsed })), setSidebarCollapsed: (isCollapsed) => set({ isSidebarCollapsed: isCollapsed }), setCommandPaletteOpen: (isOpen) => set({ isCommandPaletteOpen: isOpen }), setAddFeedDialogOpen: (isOpen) => set({ isAddFeedDialogOpen: isOpen }), setSearchOpen: (isOpen) => set({ isSearchOpen: isOpen }), setSelectedEntryIdentifier: (identifier) => set({ selectedEntryIdentifier: identifier }), setFocusedEntryIdentifier: (identifier) => set({ focusedEntryIdentifier: identifier }), setFocusedPanel: (panel) => set({ focusedPanel: panel }), setFocusedSidebarIndex: (index) => set({ focusedSidebarIndex: index }), setEntryListViewMode: (mode) => set({ entryListViewMode: mode }), setDisplayDensity: (density) => set({ displayDensity: density }), setActiveSettingsTab: (tab) => set({ activeSettingsTab: tab }), setShowFeedFavicons: (show) => set({ showFeedFavicons: show }), setFocusFollowsInteraction: (enabled) => set({ focusFollowsInteraction: enabled }), setFontSize: (size) => set({ fontSize: size }), setTimeDisplayFormat: (format) => set({ timeDisplayFormat: format }), setShowEntryImages: (show) => set({ showEntryImages: show }), setShowReadingTime: (show) => set({ showReadingTime: show }), setShowFoldersAboveFeeds: (show) => set({ showFoldersAboveFeeds: show }), setShowEntryFavicons: (show) => set({ showEntryFavicons: show }), setScrollbarStyle: (style) => set({ scrollbarStyle: style }), setAutoRefreshTimeline: (enabled) => set({ autoRefreshTimeline: enabled }), setPrioritiseUnreadEntries: (enabled) => set({ prioritiseUnreadEntries: enabled }), setToolbarPosition: (position) => set({ toolbarPosition: position }), setIsEntryListAtTop: (isAtTop) => set({ isEntryListAtTop: isAtTop }), setShortcutsDialogOpen: (isOpen) => set({ isShortcutsDialogOpen: isOpen }), toggleShortcutsDialog: () => set((state) => ({ isShortcutsDialogOpen: !state.isShortcutsDialogOpen, })), toggleFolderExpansion: (folderIdentifier) => set((state) => { const current = state.expandedFolderIdentifiers const isExpanded = current.includes(folderIdentifier) return { expandedFolderIdentifiers: isExpanded ? current.filter((id) => id !== folderIdentifier) : [...current, folderIdentifier], } }), setNavigableEntryIdentifiers: (identifiers) => set({ navigableEntryIdentifiers: identifiers }), setResetSidebarLayout: (callback) => set({ resetSidebarLayout: callback }), setResetDetailLayout: (callback) => set({ resetDetailLayout: callback }), }), { name: "asa-news-ui-preferences", storage: createJSONStorage(() => { if (typeof window === "undefined") { return { getItem: () => null, setItem: () => {}, removeItem: () => {}, } } return localStorage }), partialize: (state) => ({ entryListViewMode: state.entryListViewMode, displayDensity: state.displayDensity, showFeedFavicons: state.showFeedFavicons, focusFollowsInteraction: state.focusFollowsInteraction, expandedFolderIdentifiers: state.expandedFolderIdentifiers, fontSize: state.fontSize, timeDisplayFormat: state.timeDisplayFormat, showEntryImages: state.showEntryImages, showReadingTime: state.showReadingTime, showFoldersAboveFeeds: state.showFoldersAboveFeeds, showEntryFavicons: state.showEntryFavicons, scrollbarStyle: state.scrollbarStyle, autoRefreshTimeline: state.autoRefreshTimeline, prioritiseUnreadEntries: state.prioritiseUnreadEntries, toolbarPosition: state.toolbarPosition, }), } ) )