| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- import Store from 'electron-store'
- import { randomUUID } from 'crypto'
- import type { Playlist, PlaylistItem, PlaylistSettings } from '@shared/types'
- import { findAndMutate } from '../utils/collections'
- interface PlaylistStore {
- playlists: Playlist[]
- }
- const DEFAULT_SETTINGS: PlaylistSettings = {
- randomize: false,
- sortBy: 'manual',
- defaultDurationSec: 600,
- defaultVolume: 100
- }
- const store = new Store<PlaylistStore>({
- name: 'playlists',
- defaults: { playlists: [] }
- })
- function updatePlaylist(id: string, mutate: (playlist: Playlist) => void | false): Playlist | null {
- const playlists = store.get('playlists')
- const playlist = findAndMutate(playlists, id, (p) => {
- if (mutate(p) === false) return false
- p.updatedAt = Date.now()
- })
- if (playlist) store.set('playlists', playlists)
- return playlist
- }
- export function getAllPlaylists(): Playlist[] {
- return store.get('playlists')
- }
- export function getPlaylist(id: string): Playlist | null {
- return store.get('playlists').find((p) => p.id === id) ?? null
- }
- export function createPlaylist(title: string): Playlist {
- const now = Date.now()
- const playlist: Playlist = {
- id: randomUUID(),
- title,
- items: [],
- settings: { ...DEFAULT_SETTINGS },
- createdAt: now,
- updatedAt: now
- }
- const playlists = store.get('playlists')
- playlists.push(playlist)
- store.set('playlists', playlists)
- return playlist
- }
- export function renamePlaylist(id: string, title: string): Playlist | null {
- return updatePlaylist(id, (playlist) => {
- playlist.title = title
- })
- }
- export function deletePlaylist(id: string): void {
- const playlists = store.get('playlists').filter((p) => p.id !== id)
- store.set('playlists', playlists)
- }
- export function updatePlaylistSettings(
- id: string,
- patch: Partial<PlaylistSettings>
- ): Playlist | null {
- return updatePlaylist(id, (playlist) => {
- playlist.settings = { ...playlist.settings, ...patch }
- })
- }
- export function addItemsToPlaylist(id: string, wallpaperIds: string[]): Playlist | null {
- return updatePlaylist(id, (playlist) => {
- const existing = new Set(playlist.items.map((i) => i.wallpaperId))
- for (const wallpaperId of wallpaperIds) {
- if (!existing.has(wallpaperId)) {
- playlist.items.push({ wallpaperId })
- existing.add(wallpaperId)
- }
- }
- })
- }
- export function removeItemsFromPlaylist(id: string, wallpaperIds: string[]): Playlist | null {
- return updatePlaylist(id, (playlist) => {
- const remove = new Set(wallpaperIds)
- playlist.items = playlist.items.filter((i) => !remove.has(i.wallpaperId))
- })
- }
- /** Reorders items to match the given wallpaperId sequence (used for manual drag-reorder). */
- export function reorderPlaylistItems(id: string, orderedWallpaperIds: string[]): Playlist | null {
- return updatePlaylist(id, (playlist) => {
- const byId = new Map(playlist.items.map((i) => [i.wallpaperId, i]))
- const reordered: PlaylistItem[] = []
- for (const wallpaperId of orderedWallpaperIds) {
- const item = byId.get(wallpaperId)
- if (item) {
- reordered.push(item)
- byId.delete(wallpaperId)
- }
- }
- // Append anything not mentioned in orderedWallpaperIds (defensive, shouldn't normally happen)
- reordered.push(...byId.values())
- playlist.items = reordered
- })
- }
- export function updatePlaylistItem(
- id: string,
- wallpaperId: string,
- patch: { volume?: number; durationSec?: number }
- ): Playlist | null {
- return updatePlaylist(id, (playlist) => {
- const item = playlist.items.find((i) => i.wallpaperId === wallpaperId)
- if (!item) return false
- if ('volume' in patch) item.volume = patch.volume
- if ('durationSec' in patch) item.durationSec = patch.durationSec
- })
- }
- /**
- * Remove playlist item references that don't exist in the library anymore.
- * Returns the number of stale references removed.
- */
- export function cleanupPlaylists(validWallpaperIds: Set<string>): number {
- const playlists = store.get('playlists')
- let removed = 0
- for (const playlist of playlists) {
- const before = playlist.items.length
- playlist.items = playlist.items.filter((i) => validWallpaperIds.has(i.wallpaperId))
- removed += before - playlist.items.length
- }
- if (removed > 0) {
- store.set('playlists', playlists)
- console.log(`[Playlist] Cleanup: removed ${removed} stale item(s)`)
- }
- return removed
- }
|