Spaces:
Sleeping
Sleeping
| const STARRED_KEY = 'docvault_starred'; | |
| const RECENT_KEY = 'docvault_recent'; | |
| class StateManager { | |
| constructor() { | |
| this.currentPath = []; | |
| this.searchQuery = ''; | |
| this.viewMode = localStorage.getItem('view_mode') || 'grid'; // 'grid' | 'list' | |
| this.currentBrowse = 'files'; // 'files' | 'starred' | 'recent' | |
| this.isFetching = false; | |
| this.cachedFiles = []; | |
| this.starred = this.load(STARRED_KEY); | |
| this.recent = this.load(RECENT_KEY); | |
| this.listeners = []; | |
| } | |
| load(key) { | |
| try { | |
| return JSON.parse(localStorage.getItem(key)) || []; | |
| } catch { | |
| return []; | |
| } | |
| } | |
| save(key, data) { | |
| localStorage.setItem(key, JSON.stringify(data)); | |
| } | |
| subscribe(listener) { | |
| this.listeners.push(listener); | |
| return () => { | |
| this.listeners = this.listeners.filter(l => l !== listener); | |
| }; | |
| } | |
| notify(actionType = 'UPDATE', payload = null) { | |
| console.log(`[StateManager] ${actionType}`, payload || ''); | |
| this.listeners.forEach(l => l(this)); | |
| } | |
| setPath(path) { | |
| if (!Array.isArray(path)) return; | |
| this.currentPath = path; | |
| this.notify('SET_PATH', path); | |
| } | |
| setViewMode(mode) { | |
| if (!['grid', 'list'].includes(mode)) return; | |
| this.viewMode = mode; | |
| localStorage.setItem('view_mode', mode); | |
| this.notify('SET_VIEW_MODE', mode); | |
| } | |
| setSearchQuery(query) { | |
| this.searchQuery = typeof query === 'string' ? query : ''; | |
| this.notify('SET_SEARCH', query); | |
| } | |
| setBrowseMode(mode) { | |
| if (!['files', 'starred', 'recent'].includes(mode)) return; | |
| this.currentBrowse = mode; | |
| this.notify('SET_BROWSE', mode); | |
| } | |
| toggleStar(path) { | |
| if (typeof path !== 'string') return; | |
| if (this.starred.includes(path)) { | |
| this.starred = this.starred.filter(p => p !== path); | |
| } else { | |
| this.starred.push(path); | |
| } | |
| this.save(STARRED_KEY, this.starred); | |
| this.notify('TOGGLE_STAR', path); | |
| } | |
| addToRecent(file) { | |
| if (!file || !file.path) return; | |
| this.recent = [file, ...this.recent.filter(f => f.path !== file.path)].slice(0, 20); | |
| this.save(RECENT_KEY, this.recent); | |
| this.notify('ADD_RECENT', file.path); | |
| } | |
| getFolderPath() { | |
| return this.currentPath.join('/'); | |
| } | |
| } | |
| export const stateManager = new StateManager(); | |