feat: Implement user authentication and data management features

- Added LoginModal component for user login functionality.
- Introduced API routes for user login, favorites, play records, and search history management.
- Created JSON files for storing favorites, play records, and search history.
- Updated API service to handle new endpoints and refactored data management to use API calls instead of local storage.
- Adjusted data structures in types and services to align with new API responses.
This commit is contained in:
zimplexing
2025-07-14 16:21:28 +08:00
parent f06b10feec
commit 0452bfe21f
20 changed files with 941 additions and 497 deletions

View File

@@ -11,7 +11,7 @@ interface Episode {
}
interface VideoDetail {
videoInfo: ApiVideoDetail["videoInfo"];
videoInfo: ApiVideoDetail;
episodes: Episode[];
sources: SearchResult[];
}
@@ -89,15 +89,16 @@ const usePlayerStore = create<PlayerState>((set, get) => ({
});
try {
const videoDetail = await api.getVideoDetail(source, id);
const episodes = videoDetail.episodes.map((ep, index) => ({ url: ep, title: `${index + 1}` }));
const searchResults = await api.searchVideos(videoDetail.videoInfo.title);
const sources = searchResults.results.filter((r) => r.title === videoDetail.videoInfo.title);
const currentSourceIndex = sources.findIndex((s) => s.source === source && s.id.toString() === id);
const [{ results: sources }, resources] = await Promise.all([
api.searchVideo(videoDetail.title, source),
api.getResources(),
]);
const currentSourceIndex = resources.findIndex((s) => s.key === source);
const episodes = sources.map((ep, index) => ({ url: ep.episodes[index], title: `${index + 1}` }));
const playRecord = await PlayRecordManager.get(source, id);
set({
detail: { videoInfo: videoDetail.videoInfo, episodes, sources },
detail: { videoInfo: videoDetail, episodes, sources },
episodes,
sources,
currentSourceIndex: currentSourceIndex !== -1 ? currentSourceIndex : 0,
@@ -123,12 +124,17 @@ const usePlayerStore = create<PlayerState>((set, get) => ({
try {
const videoDetail = await api.getVideoDetail(newSource.source, newSource.id.toString());
const episodes = videoDetail.episodes.map((ep, index) => ({ url: ep, title: `${index + 1}` }));
const searchResults = await api.searchVideo(videoDetail.title, newSource.source);
if (!searchResults.results || searchResults.results.length === 0) {
throw new Error("No episodes found for this source.");
}
const sourceDetail = searchResults.results[0];
const episodes = sourceDetail.episodes.map((ep, index) => ({ url: ep, title: `${index + 1}` }));
set({
detail: {
...detail,
videoInfo: videoDetail.videoInfo,
videoInfo: videoDetail,
episodes,
},
episodes,
@@ -248,7 +254,7 @@ const usePlayerStore = create<PlayerState>((set, get) => ({
};
PlayRecordManager.save(videoInfo.source, videoInfo.id, {
title: videoInfo.title,
cover: videoInfo.cover || "",
poster: videoInfo.poster || "",
index: currentEpisodeIndex,
total_episodes: episodes.length,
play_time: status.positionMillis,