mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 00:32:04 +00:00
Refactor catalog loading logic in HomeScreen to ensure loading state is accurately represented. Update placeholder rendering with animations and improve layout for better user experience during content loading.
This commit is contained in:
parent
e2403ecd71
commit
ab7134bd3a
1 changed files with 34 additions and 30 deletions
|
|
@ -236,28 +236,22 @@ const HomeScreen = () => {
|
||||||
|
|
||||||
// Start all catalog loading promises but don't wait for them
|
// Start all catalog loading promises but don't wait for them
|
||||||
// They will update the state progressively as they complete
|
// They will update the state progressively as they complete
|
||||||
Promise.allSettled(catalogPromises).then(() => {
|
await Promise.allSettled(catalogPromises);
|
||||||
// Final cleanup: Filter out null values to get only successfully loaded catalogs
|
|
||||||
setCatalogs(prevCatalogs => prevCatalogs.filter(catalog => catalog !== null));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// Only set catalogsLoading to false after all promises have settled
|
||||||
|
setCatalogsLoading(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[HomeScreen] Error in progressive catalog loading:', error);
|
console.error('[HomeScreen] Error in progressive catalog loading:', error);
|
||||||
} finally {
|
|
||||||
setCatalogsLoading(false);
|
setCatalogsLoading(false);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Only count feature section as loading if it's enabled in settings
|
// Only count feature section as loading if it's enabled in settings
|
||||||
// Render the screen immediately and let placeholders/skeletons handle progressive loading
|
// For catalogs, we show them progressively, so loading should be false as soon as we have any content
|
||||||
const isLoading = useMemo(() => {
|
const isLoading = useMemo(() =>
|
||||||
// Show a full-screen loader only if we literally have no data to display yet
|
(showHeroSection ? featuredLoading : false) || (catalogsLoading && loadedCatalogCount === 0),
|
||||||
const noHeroSection = !showHeroSection;
|
[showHeroSection, featuredLoading, catalogsLoading, loadedCatalogCount]
|
||||||
const noFeaturedData = !featuredContent && featuredLoading;
|
);
|
||||||
const noCatalogsReady = catalogs.length === 0 && catalogsLoading;
|
|
||||||
|
|
||||||
return noHeroSection && noCatalogsReady && noFeaturedData;
|
|
||||||
}, [showHeroSection, featuredContent, featuredLoading, catalogsLoading, catalogs.length]);
|
|
||||||
|
|
||||||
// React to settings changes
|
// React to settings changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -528,20 +522,25 @@ const HomeScreen = () => {
|
||||||
);
|
);
|
||||||
case 'placeholder':
|
case 'placeholder':
|
||||||
return (
|
return (
|
||||||
<View style={styles.catalogPlaceholder}>
|
<Animated.View entering={FadeIn.duration(300)}>
|
||||||
<View style={styles.placeholderHeader}>
|
<View style={styles.catalogPlaceholder}>
|
||||||
<View style={[styles.placeholderTitle, { backgroundColor: currentTheme.colors.elevation1 }]} />
|
<View style={styles.placeholderHeader}>
|
||||||
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
<View style={[styles.placeholderTitle, { backgroundColor: currentTheme.colors.elevation1 }]} />
|
||||||
|
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
||||||
|
</View>
|
||||||
|
<ScrollView
|
||||||
|
horizontal
|
||||||
|
showsHorizontalScrollIndicator={false}
|
||||||
|
contentContainerStyle={styles.placeholderPosters}>
|
||||||
|
{[...Array(5)].map((_, posterIndex) => (
|
||||||
|
<View
|
||||||
|
key={posterIndex}
|
||||||
|
style={[styles.placeholderPoster, { backgroundColor: currentTheme.colors.elevation1 }]}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.placeholderPosters}>
|
</Animated.View>
|
||||||
{[...Array(4)].map((_, posterIndex) => (
|
|
||||||
<View
|
|
||||||
key={posterIndex}
|
|
||||||
style={[styles.placeholderPoster, { backgroundColor: currentTheme.colors.elevation1 }]}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
case 'welcome':
|
case 'welcome':
|
||||||
return <FirstTimeWelcome />;
|
return <FirstTimeWelcome />;
|
||||||
|
|
@ -559,11 +558,11 @@ const HomeScreen = () => {
|
||||||
|
|
||||||
const ListFooterComponent = useMemo(() => (
|
const ListFooterComponent = useMemo(() => (
|
||||||
<>
|
<>
|
||||||
{catalogsLoading && catalogs.length < totalCatalogsRef.current && (
|
{catalogsLoading && loadedCatalogCount > 0 && loadedCatalogCount < totalCatalogsRef.current && (
|
||||||
<View style={styles.loadingMoreCatalogs}>
|
<View style={styles.loadingMoreCatalogs}>
|
||||||
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
||||||
<Text style={[styles.loadingMoreText, { color: currentTheme.colors.textMuted }]}>
|
<Text style={[styles.loadingMoreText, { color: currentTheme.colors.textMuted }]}>
|
||||||
Loading more content... ({loadedCatalogCount}/{totalCatalogsRef.current})
|
Loading catalogs... ({loadedCatalogCount}/{totalCatalogsRef.current})
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
@ -609,8 +608,9 @@ const HomeScreen = () => {
|
||||||
initialNumToRender={5}
|
initialNumToRender={5}
|
||||||
maxToRenderPerBatch={5}
|
maxToRenderPerBatch={5}
|
||||||
windowSize={11}
|
windowSize={11}
|
||||||
removeClippedSubviews={false}
|
removeClippedSubviews={Platform.OS === 'android'}
|
||||||
onEndReachedThreshold={0.5}
|
onEndReachedThreshold={0.5}
|
||||||
|
updateCellsBatchingPeriod={50}
|
||||||
maintainVisibleContentPosition={{
|
maintainVisibleContentPosition={{
|
||||||
minIndexForVisible: 0,
|
minIndexForVisible: 0,
|
||||||
autoscrollToTopThreshold: 10
|
autoscrollToTopThreshold: 10
|
||||||
|
|
@ -697,6 +697,8 @@ const styles = StyleSheet.create<any>({
|
||||||
padding: 16,
|
padding: 16,
|
||||||
marginHorizontal: 16,
|
marginHorizontal: 16,
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.2)',
|
||||||
|
borderRadius: 8,
|
||||||
},
|
},
|
||||||
loadingMoreText: {
|
loadingMoreText: {
|
||||||
marginLeft: 12,
|
marginLeft: 12,
|
||||||
|
|
@ -719,12 +721,14 @@ const styles = StyleSheet.create<any>({
|
||||||
},
|
},
|
||||||
placeholderPosters: {
|
placeholderPosters: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
paddingVertical: 8,
|
||||||
gap: 8,
|
gap: 8,
|
||||||
},
|
},
|
||||||
placeholderPoster: {
|
placeholderPoster: {
|
||||||
width: POSTER_WIDTH,
|
width: POSTER_WIDTH,
|
||||||
aspectRatio: 2/3,
|
aspectRatio: 2/3,
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
|
marginRight: 2,
|
||||||
},
|
},
|
||||||
emptyCatalog: {
|
emptyCatalog: {
|
||||||
padding: 32,
|
padding: 32,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue