mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-30 11:46:36 +08:00
feat(libraries): add pin-to-top for media library list (#10)
Allow users to pin frequently used libraries to the top of the Libraries page. Pinned order is stored in localStorage and applied to both entry cards and preview shelves. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: truewhile <truewhile@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
const STORAGE_KEY = 'mmtl_pinned_libraries'
|
||||
|
||||
function parsePinnedIds(raw: string | null): string[] {
|
||||
if (!raw) return []
|
||||
try {
|
||||
const parsed = JSON.parse(raw)
|
||||
if (!Array.isArray(parsed)) return []
|
||||
return parsed.filter((id): id is string => typeof id === 'string' && id.trim() !== '')
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export function readPinnedLibraryIds(): string[] {
|
||||
if (typeof window === 'undefined') return []
|
||||
return parsePinnedIds(window.localStorage.getItem(STORAGE_KEY))
|
||||
}
|
||||
|
||||
export function writePinnedLibraryIds(ids: string[]): void {
|
||||
if (typeof window === 'undefined') return
|
||||
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(ids))
|
||||
}
|
||||
|
||||
export function togglePinnedLibraryId(id: string): string[] {
|
||||
const current = readPinnedLibraryIds()
|
||||
const index = current.indexOf(id)
|
||||
const next = index >= 0 ? current.filter((item) => item !== id) : [...current, id]
|
||||
writePinnedLibraryIds(next)
|
||||
return next
|
||||
}
|
||||
|
||||
export function isLibraryPinned(id: string, pinnedIds: string[]): boolean {
|
||||
return pinnedIds.includes(id)
|
||||
}
|
||||
|
||||
export function sortLibraryPreviews<T extends { library: { id: string } }>(items: T[], pinnedIds: string[]): T[] {
|
||||
if (pinnedIds.length === 0) return items
|
||||
const rank = new Map(pinnedIds.map((id, index) => [id, index]))
|
||||
return [...items].sort((a, b) => {
|
||||
const aRank = rank.get(a.library.id)
|
||||
const bRank = rank.get(b.library.id)
|
||||
const aPinned = aRank !== undefined
|
||||
const bPinned = bRank !== undefined
|
||||
if (aPinned !== bPinned) return aPinned ? -1 : 1
|
||||
if (aPinned && bPinned) return aRank - bRank
|
||||
return 0
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user