56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
|
|
export interface RecentNavigation {
|
|
screenId: string
|
|
path: string
|
|
visitedAt: string
|
|
}
|
|
|
|
const STORAGE_KEY = 'ks.shell.screenPreference.v1'
|
|
const MAX_RECENTS = 10
|
|
const MAX_FAVORITES = 20
|
|
|
|
interface PersistedShape {
|
|
favoriteScreenIds: string[]
|
|
recents: RecentNavigation[]
|
|
}
|
|
|
|
function readPersisted(): PersistedShape {
|
|
if (typeof window === 'undefined') return { favoriteScreenIds: [], recents: [] }
|
|
try {
|
|
const raw = window.localStorage.getItem(STORAGE_KEY)
|
|
if (!raw) return { favoriteScreenIds: [], recents: [] }
|
|
const parsed = JSON.parse(raw) as Partial<PersistedShape>
|
|
return {
|
|
favoriteScreenIds: Array.isArray(parsed.favoriteScreenIds) ? parsed.favoriteScreenIds.slice(0, MAX_FAVORITES) : [],
|
|
recents: Array.isArray(parsed.recents) ? parsed.recents.slice(0, MAX_RECENTS) : []
|
|
}
|
|
} catch {
|
|
return { favoriteScreenIds: [], recents: [] }
|
|
}
|
|
}
|
|
|
|
export const useScreenPreferenceStore = defineStore('ks-screen-preference', {
|
|
state: () => readPersisted(),
|
|
actions: {
|
|
persist() {
|
|
if (typeof window === 'undefined') return
|
|
window.localStorage.setItem(STORAGE_KEY, JSON.stringify({ favoriteScreenIds: this.favoriteScreenIds, recents: this.recents }))
|
|
},
|
|
toggleFavorite(screenId: string) {
|
|
const index = this.favoriteScreenIds.indexOf(screenId)
|
|
if (index >= 0) this.favoriteScreenIds.splice(index, 1)
|
|
else this.favoriteScreenIds = [screenId, ...this.favoriteScreenIds].slice(0, MAX_FAVORITES)
|
|
this.persist()
|
|
},
|
|
isFavorite(screenId: string): boolean {
|
|
return this.favoriteScreenIds.includes(screenId)
|
|
},
|
|
recordVisit(screenId: string, path: string) {
|
|
const withoutCurrent = this.recents.filter(entry => entry.screenId !== screenId)
|
|
this.recents = [{ screenId, path, visitedAt: new Date().toISOString() }, ...withoutCurrent].slice(0, MAX_RECENTS)
|
|
this.persist()
|
|
}
|
|
}
|
|
})
|