mirror of
https://github.com/zimplexing/OrionTV.git
synced 2026-05-14 03:37:29 +08:00
feat: implement user authentication and logout functionality
- Added login/logout buttons to the HomeScreen and SettingsScreen. - Integrated authentication state management using Zustand and cookies. - Updated API to support username and password for login. - Enhanced PlayScreen to handle video playback based on user authentication. - Created a new detailStore to manage video details and sources. - Refactored playerStore to utilize detailStore for episode management. - Added sourceStore to manage video source toggling. - Updated settingsStore to fetch server configuration. - Improved error handling and user feedback with Toast notifications. - Cleaned up unused code and optimized imports across components.
This commit is contained in:
57
app/play.tsx
57
app/play.tsx
@@ -10,50 +10,51 @@ import { SourceSelectionModal } from "@/components/SourceSelectionModal";
|
||||
import { SeekingBar } from "@/components/SeekingBar";
|
||||
import { NextEpisodeOverlay } from "@/components/NextEpisodeOverlay";
|
||||
import { LoadingOverlay } from "@/components/LoadingOverlay";
|
||||
import usePlayerStore from "@/stores/playerStore";
|
||||
import useDetailStore from "@/stores/detailStore";
|
||||
import { useTVRemoteHandler } from "@/hooks/useTVRemoteHandler";
|
||||
import Toast from "react-native-toast-message";
|
||||
import usePlayerStore from "@/stores/playerStore";
|
||||
|
||||
export default function PlayScreen() {
|
||||
const videoRef = useRef<Video>(null);
|
||||
const router = useRouter();
|
||||
useKeepAwake();
|
||||
const { source, id, episodeIndex, position } = useLocalSearchParams<{
|
||||
source: string;
|
||||
id: string;
|
||||
const { episodeIndex: episodeIndexStr } = useLocalSearchParams<{
|
||||
episodeIndex: string;
|
||||
position: string;
|
||||
}>();
|
||||
const episodeIndex = parseInt(episodeIndexStr || "0", 10);
|
||||
|
||||
const { detail } = useDetailStore();
|
||||
const {
|
||||
detail,
|
||||
episodes,
|
||||
currentEpisodeIndex,
|
||||
status,
|
||||
isLoading,
|
||||
showControls,
|
||||
showEpisodeModal,
|
||||
showSourceModal,
|
||||
showNextEpisodeOverlay,
|
||||
initialPosition,
|
||||
introEndTime,
|
||||
setVideoRef,
|
||||
loadVideo,
|
||||
handlePlaybackStatusUpdate,
|
||||
setShowControls,
|
||||
setShowEpisodeModal,
|
||||
setShowSourceModal,
|
||||
setShowNextEpisodeOverlay,
|
||||
reset,
|
||||
playEpisode,
|
||||
togglePlayPause,
|
||||
seek,
|
||||
} = usePlayerStore();
|
||||
|
||||
useEffect(() => {
|
||||
setVideoRef(videoRef);
|
||||
if (source && id) {
|
||||
loadVideo(source, id, parseInt(episodeIndex || "0", 10), parseInt(position || "0", 10));
|
||||
}
|
||||
// The detail is already in the detailStore, no need to load it again.
|
||||
// We just need to set the current episode in the player store.
|
||||
usePlayerStore.setState({
|
||||
currentEpisodeIndex: episodeIndex,
|
||||
episodes: detail?.episodes.map((ep, index) => ({ url: ep, title: `第 ${index + 1} 集` })) || [],
|
||||
});
|
||||
|
||||
return () => {
|
||||
reset(); // Reset state when component unmounts
|
||||
};
|
||||
}, [source, id, episodeIndex, position, setVideoRef, loadVideo, reset]);
|
||||
}, [episodeIndex, detail, setVideoRef, reset]);
|
||||
|
||||
const { onScreenPress } = useTVRemoteHandler();
|
||||
|
||||
@@ -70,17 +71,9 @@ export default function PlayScreen() {
|
||||
const backHandler = BackHandler.addEventListener("hardwareBackPress", backAction);
|
||||
|
||||
return () => backHandler.remove();
|
||||
}, [
|
||||
showControls,
|
||||
showEpisodeModal,
|
||||
showSourceModal,
|
||||
setShowControls,
|
||||
setShowEpisodeModal,
|
||||
setShowSourceModal,
|
||||
router,
|
||||
]);
|
||||
}, [showControls, setShowControls, router]);
|
||||
|
||||
if (!detail && isLoading) {
|
||||
if (!detail) {
|
||||
return (
|
||||
<ThemedView style={[styles.container, styles.centered]}>
|
||||
<ActivityIndicator size="large" color="#fff" />
|
||||
@@ -88,7 +81,7 @@ export default function PlayScreen() {
|
||||
);
|
||||
}
|
||||
|
||||
const currentEpisode = episodes[currentEpisodeIndex];
|
||||
const currentEpisode = detail.episodes[episodeIndex];
|
||||
|
||||
return (
|
||||
<ThemedView focusable style={styles.container}>
|
||||
@@ -96,9 +89,9 @@ export default function PlayScreen() {
|
||||
<Video
|
||||
ref={videoRef}
|
||||
style={styles.videoPlayer}
|
||||
source={{ uri: currentEpisode?.url }}
|
||||
source={{ uri: currentEpisode }}
|
||||
usePoster
|
||||
posterSource={{ uri: detail?.videoInfo.poster ?? "" }}
|
||||
posterSource={{ uri: detail?.poster ?? "" }}
|
||||
resizeMode={ResizeMode.CONTAIN}
|
||||
onPlaybackStatusUpdate={handlePlaybackStatusUpdate}
|
||||
onLoad={() => {
|
||||
@@ -108,6 +101,10 @@ export default function PlayScreen() {
|
||||
}
|
||||
usePlayerStore.setState({ isLoading: false });
|
||||
}}
|
||||
onError={() => {
|
||||
usePlayerStore.setState({ isLoading: false });
|
||||
Toast.show({ type: "error", text1: "播放失败,请更换源后重试" });
|
||||
}}
|
||||
onLoadStart={() => usePlayerStore.setState({ isLoading: true })}
|
||||
useNativeControls={false}
|
||||
shouldPlay
|
||||
|
||||
Reference in New Issue
Block a user