|
|
|
|
|
|
|
|
|
|
|
|
|
|
export interface WatchProgress { |
|
|
currentTime: number; |
|
|
duration: number; |
|
|
lastPlayed: string; |
|
|
completed: boolean; |
|
|
} |
|
|
|
|
|
|
|
|
export interface MyListItem { |
|
|
title: string; |
|
|
type: 'movie' | 'tvshow'; |
|
|
addedAt: string; |
|
|
posterPath?: string; |
|
|
backdropPath?: string; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const saveVideoProgress = ( |
|
|
type: 'movie' | 'tvshow', |
|
|
title: string, |
|
|
seasonEpisode: string | null, |
|
|
progress: WatchProgress |
|
|
): void => { |
|
|
try { |
|
|
|
|
|
const id = seasonEpisode ? `${type}-${title}-${seasonEpisode}` : `${type}-${title}`; |
|
|
|
|
|
|
|
|
const historyStr = localStorage.getItem('watch-history') || '{}'; |
|
|
const history = JSON.parse(historyStr); |
|
|
|
|
|
|
|
|
history[id] = { |
|
|
...progress, |
|
|
title, |
|
|
type, |
|
|
seasonEpisode, |
|
|
updatedAt: new Date().toISOString() |
|
|
}; |
|
|
|
|
|
|
|
|
localStorage.setItem('watch-history', JSON.stringify(history)); |
|
|
} catch (error) { |
|
|
console.error('Failed to save video progress:', error); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const getVideoProgress = ( |
|
|
type: 'movie' | 'tvshow', |
|
|
title: string, |
|
|
seasonEpisode: string | null |
|
|
): WatchProgress | null => { |
|
|
try { |
|
|
|
|
|
const id = seasonEpisode ? `${type}-${title}-${seasonEpisode}` : `${type}-${title}`; |
|
|
|
|
|
|
|
|
const historyStr = localStorage.getItem('watch-history') || '{}'; |
|
|
const history = JSON.parse(historyStr); |
|
|
|
|
|
|
|
|
return history[id] || null; |
|
|
} catch (error) { |
|
|
console.error('Failed to get video progress:', error); |
|
|
return null; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const getWatchHistory = (limit: number = 0): Array<any> => { |
|
|
try { |
|
|
|
|
|
const historyStr = localStorage.getItem('watch-history') || '{}'; |
|
|
const history = JSON.parse(historyStr); |
|
|
|
|
|
|
|
|
const historyArray = Object.values(history).sort((a: any, b: any) => { |
|
|
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(); |
|
|
}); |
|
|
|
|
|
|
|
|
return limit > 0 ? historyArray.slice(0, limit) : historyArray; |
|
|
} catch (error) { |
|
|
console.error('Failed to get watch history:', error); |
|
|
return []; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const clearWatchHistory = (): void => { |
|
|
try { |
|
|
localStorage.removeItem('watch-history'); |
|
|
} catch (error) { |
|
|
console.error('Failed to clear watch history:', error); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const addToMyList = (item: MyListItem): void => { |
|
|
try { |
|
|
|
|
|
const myListStr = localStorage.getItem('my-list') || '[]'; |
|
|
const myList = JSON.parse(myListStr); |
|
|
|
|
|
|
|
|
const exists = myList.some((listItem: MyListItem) => |
|
|
listItem.title === item.title && listItem.type === item.type |
|
|
); |
|
|
|
|
|
|
|
|
if (!exists) { |
|
|
myList.push({ |
|
|
...item, |
|
|
addedAt: new Date().toISOString() |
|
|
}); |
|
|
|
|
|
|
|
|
localStorage.setItem('my-list', JSON.stringify(myList)); |
|
|
} |
|
|
} catch (error) { |
|
|
console.error('Failed to add item to My List:', error); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const removeFromMyList = (title: string, type: 'movie' | 'tvshow'): void => { |
|
|
try { |
|
|
|
|
|
const myListStr = localStorage.getItem('my-list') || '[]'; |
|
|
const myList = JSON.parse(myListStr); |
|
|
|
|
|
|
|
|
const newList = myList.filter((item: MyListItem) => |
|
|
!(item.title === title && item.type === type) |
|
|
); |
|
|
|
|
|
|
|
|
localStorage.setItem('my-list', JSON.stringify(newList)); |
|
|
} catch (error) { |
|
|
console.error('Failed to remove item from My List:', error); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const isInMyList = (title: string, type: 'movie' | 'tvshow'): boolean => { |
|
|
try { |
|
|
|
|
|
const myListStr = localStorage.getItem('my-list') || '[]'; |
|
|
const myList = JSON.parse(myListStr); |
|
|
|
|
|
|
|
|
return myList.some((item: MyListItem) => |
|
|
item.title === title && item.type === type |
|
|
); |
|
|
} catch (error) { |
|
|
console.error('Failed to check if item is in My List:', error); |
|
|
return false; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const getAllFromMyList = (): Array<MyListItem> => { |
|
|
try { |
|
|
|
|
|
const myListStr = localStorage.getItem('my-list') || '[]'; |
|
|
return JSON.parse(myListStr); |
|
|
} catch (error) { |
|
|
console.error('Failed to get My List:', error); |
|
|
return []; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const clearMyList = (): void => { |
|
|
try { |
|
|
localStorage.removeItem('my-list'); |
|
|
} catch (error) { |
|
|
console.error('Failed to clear My List:', error); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
export const storageService = { |
|
|
|
|
|
saveVideoProgress, |
|
|
getVideoProgress, |
|
|
getWatchHistory, |
|
|
clearWatchHistory, |
|
|
|
|
|
|
|
|
addToMyList, |
|
|
removeFromMyList, |
|
|
isInMyList, |
|
|
getAllFromMyList, |
|
|
clearMyList, |
|
|
|
|
|
|
|
|
setItem: (key: string, value: any): void => { |
|
|
try { |
|
|
localStorage.setItem(key, JSON.stringify(value)); |
|
|
} catch (error) { |
|
|
console.error(`Failed to store ${key}:`, error); |
|
|
} |
|
|
}, |
|
|
|
|
|
getItem: <T>(key: string, defaultValue: T): T => { |
|
|
try { |
|
|
const item = localStorage.getItem(key); |
|
|
return item ? JSON.parse(item) : defaultValue; |
|
|
} catch (error) { |
|
|
console.error(`Failed to retrieve ${key}:`, error); |
|
|
return defaultValue; |
|
|
} |
|
|
}, |
|
|
|
|
|
removeItem: (key: string): void => { |
|
|
try { |
|
|
localStorage.removeItem(key); |
|
|
} catch (error) { |
|
|
console.error(`Failed to remove ${key}:`, error); |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
export default storageService; |
|
|
|