2026-05-21 10:15:02 +07:00
|
|
|
export type LibraryMovieItem = {
|
|
|
|
|
source: string
|
|
|
|
|
slug: string
|
|
|
|
|
name: string
|
|
|
|
|
originName?: string
|
|
|
|
|
thumb?: string
|
|
|
|
|
poster?: string
|
|
|
|
|
updatedAt?: number
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-24 22:35:13 +07:00
|
|
|
const favoriteKey = 'cinek-favorites'
|
|
|
|
|
const watchLaterKey = 'cinek-watch-later'
|
|
|
|
|
const legacyFavoriteKey = 'kr-phim-favorites'
|
|
|
|
|
const legacyWatchLaterKey = 'kr-phim-watch-later'
|
2026-05-21 10:15:02 +07:00
|
|
|
|
|
|
|
|
function normalizeLibraryItem(item: any): LibraryMovieItem | null {
|
|
|
|
|
if (!item?.slug || !item?.name) return null
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
source: String(item.source || ''),
|
|
|
|
|
slug: String(item.slug),
|
|
|
|
|
name: String(item.name),
|
|
|
|
|
originName: item.originName || item.origin_name || undefined,
|
|
|
|
|
thumb: item.thumb || undefined,
|
|
|
|
|
poster: item.poster || undefined,
|
|
|
|
|
updatedAt: typeof item.updatedAt === 'number'
|
|
|
|
|
? item.updatedAt
|
|
|
|
|
: new Date(item.updated_at || Date.now()).getTime(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-24 22:35:13 +07:00
|
|
|
function readLocalItems(key: string, legacyKey?: string) {
|
2026-05-21 10:15:02 +07:00
|
|
|
if (!import.meta.client) return []
|
|
|
|
|
|
|
|
|
|
try {
|
2026-05-24 22:35:13 +07:00
|
|
|
const raw = window.localStorage.getItem(key) || (legacyKey ? window.localStorage.getItem(legacyKey) : null)
|
2026-05-21 10:15:02 +07:00
|
|
|
const items = raw ? JSON.parse(raw) : []
|
|
|
|
|
|
|
|
|
|
return Array.isArray(items)
|
|
|
|
|
? items.map(normalizeLibraryItem).filter(Boolean) as LibraryMovieItem[]
|
|
|
|
|
: []
|
|
|
|
|
} catch {
|
|
|
|
|
return []
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeLocalItems(key: string, items: LibraryMovieItem[]) {
|
|
|
|
|
if (!import.meta.client) return
|
|
|
|
|
window.localStorage.setItem(key, JSON.stringify(items))
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-24 22:35:13 +07:00
|
|
|
function legacyKeyFor(key: string) {
|
|
|
|
|
if (key === favoriteKey) return legacyFavoriteKey
|
|
|
|
|
if (key === watchLaterKey) return legacyWatchLaterKey
|
|
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-21 10:15:02 +07:00
|
|
|
export function useMovieLibrary() {
|
2026-07-21 23:43:04 -04:00
|
|
|
async function loadItems(key: string, limit = 30) {
|
2026-05-24 22:35:13 +07:00
|
|
|
const localItems = readLocalItems(key, legacyKeyFor(key))
|
2026-05-21 10:15:02 +07:00
|
|
|
|
|
|
|
|
return localItems
|
|
|
|
|
.sort((a, b) => (b.updatedAt || 0) - (a.updatedAt || 0))
|
|
|
|
|
.slice(0, limit)
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-21 23:43:04 -04:00
|
|
|
async function saveItem(key: string, item: LibraryMovieItem) {
|
2026-05-21 10:15:02 +07:00
|
|
|
const normalizedItem = normalizeLibraryItem({
|
|
|
|
|
...item,
|
|
|
|
|
updatedAt: Date.now(),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (!normalizedItem) return false
|
|
|
|
|
|
|
|
|
|
const nextItems = [
|
|
|
|
|
normalizedItem,
|
2026-05-24 22:35:13 +07:00
|
|
|
...readLocalItems(key, legacyKeyFor(key)).filter((savedItem) => !(savedItem.slug === normalizedItem.slug && savedItem.source === normalizedItem.source)),
|
2026-05-21 10:15:02 +07:00
|
|
|
].slice(0, 50)
|
|
|
|
|
|
|
|
|
|
writeLocalItems(key, nextItems)
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-21 23:43:04 -04:00
|
|
|
async function removeItem(key: string, item: LibraryMovieItem) {
|
2026-05-24 22:35:13 +07:00
|
|
|
const nextItems = readLocalItems(key, legacyKeyFor(key))
|
2026-05-21 10:15:02 +07:00
|
|
|
.filter((savedItem) => !(savedItem.slug === item.slug && savedItem.source === item.source))
|
|
|
|
|
writeLocalItems(key, nextItems)
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-21 23:43:04 -04:00
|
|
|
async function isSaved(key: string, item: LibraryMovieItem) {
|
|
|
|
|
return readLocalItems(key, legacyKeyFor(key))
|
2026-05-21 10:15:02 +07:00
|
|
|
.some((savedItem) => savedItem.slug === item.slug && savedItem.source === item.source)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
2026-07-21 23:43:04 -04:00
|
|
|
loadFavorites: (limit?: number) => loadItems(favoriteKey, limit),
|
|
|
|
|
saveFavorite: (item: LibraryMovieItem) => saveItem(favoriteKey, item),
|
|
|
|
|
removeFavorite: (item: LibraryMovieItem) => removeItem(favoriteKey, item),
|
|
|
|
|
isFavorite: (item: LibraryMovieItem) => isSaved(favoriteKey, item),
|
|
|
|
|
saveWatchLater: (item: LibraryMovieItem) => saveItem(watchLaterKey, item),
|
2026-05-21 10:15:02 +07:00
|
|
|
}
|
|
|
|
|
}
|