mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +00:00
Enhance StreamsScreen loading state management and provider status updates
This update improves the loading state management in the StreamsScreen component by refining how loading cycles are tracked and provider statuses are updated. It introduces a more dynamic approach to handling expected providers, ensuring accurate loading indicators and success/error messages based on the availability of streams. Additionally, a helper function for sorting stream quality has been added, enhancing the user experience when selecting streams. Overall, these changes contribute to a more robust and user-friendly streaming experience.
This commit is contained in:
parent
5751d755db
commit
a4b09e6afe
1 changed files with 122 additions and 44 deletions
|
|
@ -267,41 +267,108 @@ export const StreamsScreen = () => {
|
|||
}
|
||||
}>({});
|
||||
|
||||
// Monitor streams loading start
|
||||
// Monitor streams loading start and completion
|
||||
useEffect(() => {
|
||||
const now = Date.now();
|
||||
// Define all providers you expect to load. This could be dynamic.
|
||||
const expectedProviders = ['stremio', 'hdrezka'];
|
||||
|
||||
if (loadingStreams || loadingEpisodeStreams) {
|
||||
logger.log("⏱️ Stream loading started");
|
||||
const now = Date.now();
|
||||
setLoadStartTime(now);
|
||||
setProviderLoadTimes({});
|
||||
// --- Stream Loading has STARTED or is IN PROGRESS ---
|
||||
logger.log("⏱️ Stream loading started or in progress...");
|
||||
|
||||
// Reset provider status - include HDRezka
|
||||
setProviderStatus({
|
||||
'stremio': {
|
||||
loading: true,
|
||||
success: false,
|
||||
error: false,
|
||||
message: 'Loading...',
|
||||
timeStarted: now,
|
||||
timeCompleted: 0
|
||||
},
|
||||
'hdrezka': {
|
||||
loading: true,
|
||||
success: false,
|
||||
error: false,
|
||||
message: 'Loading...',
|
||||
timeStarted: now,
|
||||
timeCompleted: 0
|
||||
}
|
||||
});
|
||||
// Set load start time only if this is the beginning of a new loading cycle
|
||||
if (loadStartTime === 0) {
|
||||
setLoadStartTime(now);
|
||||
}
|
||||
|
||||
// Also update the simpler loading state - include HDRezka
|
||||
setLoadingProviders({
|
||||
'stremio': true,
|
||||
'hdrezka': true
|
||||
setProviderLoadTimes({}); // Reset individual provider load times tracker
|
||||
|
||||
// Update provider status to loading for all expected providers
|
||||
setProviderStatus(prevStatus => {
|
||||
const newStatus = { ...prevStatus };
|
||||
expectedProviders.forEach(providerId => {
|
||||
// If not already marked as loading, or if it's a fresh cycle, set to loading
|
||||
if (!newStatus[providerId] || !newStatus[providerId].loading || loadStartTime === 0) {
|
||||
newStatus[providerId] = {
|
||||
loading: true,
|
||||
success: false,
|
||||
error: false,
|
||||
message: 'Loading...',
|
||||
timeStarted: (newStatus[providerId]?.loading && newStatus[providerId]?.timeStarted) ? newStatus[providerId].timeStarted : now,
|
||||
timeCompleted: 0,
|
||||
};
|
||||
}
|
||||
});
|
||||
return newStatus;
|
||||
});
|
||||
|
||||
// Update simple loading flag for all expected providers
|
||||
setLoadingProviders(prevLoading => {
|
||||
const newLoading = { ...prevLoading };
|
||||
expectedProviders.forEach(providerId => {
|
||||
newLoading[providerId] = true;
|
||||
});
|
||||
return newLoading;
|
||||
});
|
||||
|
||||
} else if (loadStartTime > 0) {
|
||||
// --- Stream Loading has FINISHED ---
|
||||
// (loadStartTime > 0 implies a loading cycle was active and has now completed)
|
||||
logger.log("🏁 Stream loading finished. Processing results.");
|
||||
|
||||
const currentStreamsData = type === 'series' ? episodeStreams : groupedStreams;
|
||||
|
||||
// Update simple loading flag: all expected providers are no longer loading
|
||||
setLoadingProviders(prevLoading => {
|
||||
const newLoading = { ...prevLoading };
|
||||
expectedProviders.forEach(providerId => {
|
||||
newLoading[providerId] = false;
|
||||
});
|
||||
return newLoading;
|
||||
});
|
||||
|
||||
// Update detailed provider status based on results
|
||||
setProviderStatus(prevStatus => {
|
||||
const newStatus = { ...prevStatus };
|
||||
expectedProviders.forEach(providerId => {
|
||||
if (newStatus[providerId]) { // Ensure the provider entry exists
|
||||
const providerHasStreams = currentStreamsData[providerId] &&
|
||||
currentStreamsData[providerId].streams &&
|
||||
currentStreamsData[providerId].streams.length > 0;
|
||||
|
||||
newStatus[providerId] = {
|
||||
...newStatus[providerId], // Preserve timeStarted
|
||||
loading: false,
|
||||
success: providerHasStreams,
|
||||
// Mark error if it was loading and now no streams, and wasn't already successful
|
||||
error: !providerHasStreams && newStatus[providerId].loading && !newStatus[providerId].success,
|
||||
message: providerHasStreams ? 'Loaded successfully' : (newStatus[providerId].error ? 'Error or no streams' : 'No streams found'),
|
||||
timeCompleted: now,
|
||||
};
|
||||
} else {
|
||||
// Fallback if somehow not initialized (should be caught by loading phase)
|
||||
newStatus[providerId] = {
|
||||
loading: false,
|
||||
success: false,
|
||||
error: true,
|
||||
message: 'Provider status error (not initialized)',
|
||||
timeStarted: 0,
|
||||
timeCompleted: now,
|
||||
};
|
||||
}
|
||||
});
|
||||
return newStatus;
|
||||
});
|
||||
|
||||
// Update the set of available providers based on what actually loaded streams
|
||||
const providersWithStreams = new Set(Object.keys(currentStreamsData));
|
||||
setAvailableProviders(providersWithStreams);
|
||||
|
||||
// Reset loadStartTime to signify the end of this loading cycle
|
||||
setLoadStartTime(0);
|
||||
}
|
||||
}, [loadingStreams, loadingEpisodeStreams]);
|
||||
}, [loadingStreams, loadingEpisodeStreams, groupedStreams, episodeStreams, type /* loadStartTime is intentionally omitted from deps here */]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (type === 'series' && episodeId) {
|
||||
|
|
@ -314,20 +381,14 @@ export const StreamsScreen = () => {
|
|||
loadEpisodeStreams(episodeId);
|
||||
} else if (type === 'movie') {
|
||||
logger.log(`🎬 Loading movie streams for: ${id}`);
|
||||
setLoadingProviders({
|
||||
'stremio': true,
|
||||
'hdrezka': true
|
||||
});
|
||||
// setLoadingProviders({ // This is now handled by the main effect
|
||||
// 'stremio': true,
|
||||
// 'hdrezka': true
|
||||
// });
|
||||
loadStreams();
|
||||
}
|
||||
}, [type, episodeId]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const streams = type === 'series' ? episodeStreams : groupedStreams;
|
||||
const providers = new Set(Object.keys(streams));
|
||||
setAvailableProviders(providers);
|
||||
}, [type, groupedStreams, episodeStreams]);
|
||||
|
||||
React.useEffect(() => {
|
||||
// Trigger entrance animations
|
||||
headerOpacity.value = withTiming(1, { duration: 400 });
|
||||
|
|
@ -609,6 +670,13 @@ export const StreamsScreen = () => {
|
|||
const streams = type === 'series' ? episodeStreams : groupedStreams;
|
||||
const installedAddons = stremioService.getInstalledAddons();
|
||||
|
||||
// Helper function to extract quality as a number for sorting
|
||||
const getQualityNumeric = (title: string | undefined): number => {
|
||||
if (!title) return 0;
|
||||
const match = title.match(/(\d+)p/);
|
||||
return match ? parseInt(match[1], 10) : 0;
|
||||
};
|
||||
|
||||
// Filter streams by selected provider - only if not "all"
|
||||
const filteredEntries = Object.entries(streams)
|
||||
.filter(([addonId]) => {
|
||||
|
|
@ -633,11 +701,21 @@ export const StreamsScreen = () => {
|
|||
if (indexB !== -1) return 1;
|
||||
return 0;
|
||||
})
|
||||
.map(([addonId, { addonName, streams }]) => ({
|
||||
title: addonName,
|
||||
addonId,
|
||||
data: streams
|
||||
}));
|
||||
.map(([addonId, { addonName, streams: providerStreams }]) => {
|
||||
let sortedProviderStreams = providerStreams;
|
||||
if (addonId === 'hdrezka') {
|
||||
sortedProviderStreams = [...providerStreams].sort((a, b) => {
|
||||
const qualityA = getQualityNumeric(a.title);
|
||||
const qualityB = getQualityNumeric(b.title);
|
||||
return qualityB - qualityA; // Sort descending (e.g., 1080p before 720p)
|
||||
});
|
||||
}
|
||||
return {
|
||||
title: addonName,
|
||||
addonId,
|
||||
data: sortedProviderStreams
|
||||
};
|
||||
});
|
||||
|
||||
return filteredEntries;
|
||||
}, [selectedProvider, type, episodeStreams, groupedStreams]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue