From 6c44c0ec5991484caaee04466e8bbcd5e7f36ce4 Mon Sep 17 00:00:00 2001 From: tapframe Date: Mon, 9 Jun 2025 02:21:41 +0530 Subject: [PATCH] Add close button to VideoPlayer and improve loading indicators in StreamsScreen This update introduces a close button in the VideoPlayer component for better user control during video loading. Additionally, the StreamsScreen has been enhanced to show loading indicators for individual stream providers, improving the user experience by providing visual feedback during data fetching. --- src/components/player/VideoPlayer.tsx | 9 +++ src/components/player/utils/playerStyles.ts | 12 ++++ src/screens/StreamsScreen.tsx | 64 +++++++++++++++------ 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/components/player/VideoPlayer.tsx b/src/components/player/VideoPlayer.tsx index c44be091..3ea80d77 100644 --- a/src/components/player/VideoPlayer.tsx +++ b/src/components/player/VideoPlayer.tsx @@ -9,6 +9,7 @@ import * as ScreenOrientation from 'expo-screen-orientation'; import { storageService } from '../../services/storageService'; import { logger } from '../../utils/logger'; import AsyncStorage from '@react-native-async-storage/async-storage'; +import { MaterialIcons } from '@expo/vector-icons'; import { DEFAULT_SUBTITLE_SIZE, @@ -747,6 +748,14 @@ const VideoPlayer: React.FC = () => { ]} pointerEvents={isOpeningAnimationComplete ? 'none' : 'auto'} > + + + + Loading video... diff --git a/src/components/player/utils/playerStyles.ts b/src/components/player/utils/playerStyles.ts index 561e0d55..e2834e2e 100644 --- a/src/components/player/utils/playerStyles.ts +++ b/src/components/player/utils/playerStyles.ts @@ -752,4 +752,16 @@ export const styles = StyleSheet.create({ fontSize: 12, marginTop: 2, }, + loadingCloseButton: { + position: 'absolute', + top: 40, + right: 20, + width: 44, + height: 44, + backgroundColor: 'rgba(0, 0, 0, 0.6)', + borderRadius: 22, + justifyContent: 'center', + alignItems: 'center', + zIndex: 9999, + }, }); \ No newline at end of file diff --git a/src/screens/StreamsScreen.tsx b/src/screens/StreamsScreen.tsx index 4c470dfd..5ed54079 100644 --- a/src/screens/StreamsScreen.tsx +++ b/src/screens/StreamsScreen.tsx @@ -856,11 +856,8 @@ export const StreamsScreen = () => { const renderItem = useCallback(({ item, index, section }: { item: Stream; index: number; section: any }) => { const stream = item; - const isLoading = loadingProviders[section.addonId]; - - // Special handling for HDRezka streams - const quality = stream.title?.match(/(\d+)p/)?.[1] || null; - const isHDRezka = section.addonId === 'hdrezka'; + // Don't show loading for individual streams that are already available and displayed + const isLoading = false; // If streams are being rendered, they're available and shouldn't be loading return ( { onPress={() => handleStreamPress(stream)} index={index} isLoading={isLoading} - statusMessage={providerStatus[section.addonId]?.message} + statusMessage={undefined} theme={currentTheme} /> ); - }, [handleStreamPress, loadingProviders, providerStatus, currentTheme]); + }, [handleStreamPress, currentTheme]); - const renderSectionHeader = useCallback(({ section }: { section: { title: string; addonId: string } }) => ( - - {section.title} - - ), [styles.streamGroupTitle]); + const renderSectionHeader = useCallback(({ section }: { section: { title: string; addonId: string } }) => { + const isProviderLoading = loadingProviders[section.addonId]; + + return ( + + + {section.title} + {isProviderLoading && ( + + + + Loading... + + + )} + + + ); + }, [styles.streamGroupTitle, styles.sectionHeaderContainer, styles.sectionHeaderContent, styles.sectionLoadingIndicator, styles.sectionLoadingText, loadingProviders, colors.primary]); // Cleanup on unmount useEffect(() => { @@ -1088,7 +1100,8 @@ export const StreamsScreen = () => { )} - {isLoading || (Object.keys(streams).length === 0 && (loadingStreams || loadingEpisodeStreams)) ? ( + {/* Show streams immediately as they become available, with loading indicators for pending providers */} + {Object.keys(streams).length === 0 && (loadingStreams || loadingEpisodeStreams) ? ( { Finding available streams... - ) : Object.keys(streams).length === 0 ? ( + ) : Object.keys(streams).length === 0 && !loadingStreams && !loadingEpisodeStreams ? ( { bounces={true} overScrollMode="never" ListFooterComponent={ - isLoading ? ( + (loadingStreams || loadingEpisodeStreams) ? ( Loading more sources... @@ -1540,6 +1553,21 @@ const createStyles = (colors: any) => StyleSheet.create({ alignItems: 'center', zIndex: 9999, }, + sectionHeaderContainer: { + padding: 16, + }, + sectionHeaderContent: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + sectionLoadingIndicator: { + flexDirection: 'row', + alignItems: 'center', + }, + sectionLoadingText: { + marginLeft: 8, + }, }); export default memo(StreamsScreen); \ No newline at end of file