mirror of
https://github.com/R0m1k3/xtremobile.git
synced 2026-10-22 06:38:16 +02:00
feat(live): refresh the channel list on demand and on resume
Live categories and channels were fetched once per app session and kept in memory until the process died, so a TV box left running never picked up provider changes. - Live tab: pull-to-refresh plus a remote-friendly refresh button, and an automatic refetch when the app returns to the foreground after 4 hours. - Settings: the "refresh cache" entry was a no-op delay; it now forces a reload of live channels, movies, series and EPG. - The Xtream service keeps the last non-empty live lists and serves them when a refetch fails, so a refresh on a not-yet-connected network does not blank the screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9ce707a702
commit
60c7f4cece
6 files changed
+396
-241
No files matched your search
@@ -30,10 +30,44 @@ final mobileXtreamServiceProvider =
|
||||
}
|
||||
});
|
||||
|
||||
// A full catalogue refresh from the settings also drops the cached EPG.
|
||||
ref.listen<int>(
|
||||
fullCatalogRefreshTickProvider, (_, __) => service.clearCache());
|
||||
|
||||
ref.onDispose(service.dispose);
|
||||
return service;
|
||||
});
|
||||
|
||||
/// When the live catalogue was last fetched or explicitly refreshed.
|
||||
/// Drives the auto-refresh when the app comes back to the foreground.
|
||||
final liveCatalogRefreshedAtProvider =
|
||||
StateProvider<DateTime>((ref) => DateTime.now());
|
||||
|
||||
/// Bumped by the settings "force refresh". The movies and series tabs, which
|
||||
/// hold their lists in local state, listen to it to reload.
|
||||
final fullCatalogRefreshTickProvider = StateProvider<int>((ref) => 0);
|
||||
|
||||
/// Forces the live categories and channels to be refetched from the panel.
|
||||
///
|
||||
/// The Xtream service is kept: it falls back to its last good lists if the
|
||||
/// refetch fails, so a flaky network never empties the screen.
|
||||
void refreshLiveCatalog(WidgetRef ref) {
|
||||
ref.invalidate(mobileLiveCategoriesProvider);
|
||||
ref.invalidate(mobileLiveChannelsByCategoryProvider);
|
||||
ref.invalidate(mobileLiveChannelsProvider);
|
||||
ref.read(liveCatalogRefreshedAtProvider.notifier).state = DateTime.now();
|
||||
}
|
||||
|
||||
/// Forces the whole catalogue (live, movies, series) and the EPG to reload.
|
||||
void refreshFullCatalog(WidgetRef ref) {
|
||||
refreshLiveCatalog(ref);
|
||||
ref.invalidate(mobileMoviesProvider);
|
||||
ref.invalidate(mobileSeriesCategoriesProvider);
|
||||
ref.invalidate(mobileSeriesProvider);
|
||||
ref.invalidate(mobileSeriesInfoByPlaylistProvider);
|
||||
ref.read(fullCatalogRefreshTickProvider.notifier).state++;
|
||||
}
|
||||
|
||||
/// Mobile-specific live categories provider (for Live TV category grid)
|
||||
final mobileLiveCategoriesProvider =
|
||||
FutureProvider.family<List<model.Category>, PlaylistConfig>(
|
||||
@@ -43,9 +77,9 @@ final mobileLiveCategoriesProvider =
|
||||
});
|
||||
|
||||
/// Mobile-specific live channels provider (loads channels for a specific category)
|
||||
final mobileLiveChannelsByCategoryProvider = FutureProvider.family<
|
||||
List<model.Channel>,
|
||||
(PlaylistConfig, String)>((ref, params) async {
|
||||
final mobileLiveChannelsByCategoryProvider =
|
||||
FutureProvider.family<List<model.Channel>, (PlaylistConfig, String)>(
|
||||
(ref, params) async {
|
||||
final (playlist, categoryId) = params;
|
||||
final service = await ref.watch(mobileXtreamServiceProvider(playlist).future);
|
||||
return service.getLiveChannels(categoryId);
|
||||
@@ -79,8 +113,9 @@ final mobileLiveChannelsProvider =
|
||||
|
||||
for (int batchNum = 0; batchNum < totalBatches; batchNum++) {
|
||||
int startIdx = batchNum * batchSize;
|
||||
int endIdx =
|
||||
(startIdx + batchSize < categories.length) ? startIdx + batchSize : categories.length;
|
||||
int endIdx = (startIdx + batchSize < categories.length)
|
||||
? startIdx + batchSize
|
||||
: categories.length;
|
||||
final batch = categories.sublist(startIdx, endIdx);
|
||||
|
||||
print(
|
||||
@@ -120,7 +155,8 @@ final mobileLiveChannelsProvider =
|
||||
|
||||
/// Mobile-specific movies provider
|
||||
final mobileMoviesProvider =
|
||||
FutureProvider.family<List<model.VodItem>, PlaylistConfig>((ref, playlist) async {
|
||||
FutureProvider.family<List<model.VodItem>, PlaylistConfig>(
|
||||
(ref, playlist) async {
|
||||
final service = await ref.watch(mobileXtreamServiceProvider(playlist).future);
|
||||
return service.getMoviesByCategory(""); // Fetch all or default
|
||||
});
|
||||
@@ -134,8 +170,9 @@ final mobileSeriesCategoriesProvider =
|
||||
});
|
||||
|
||||
/// Mobile-specific series pagination provider
|
||||
final mobileSeriesProvider = FutureProvider.family<List<model.Series>,
|
||||
(PlaylistConfig, String?)>((ref, params) async {
|
||||
final mobileSeriesProvider =
|
||||
FutureProvider.family<List<model.Series>, (PlaylistConfig, String?)>(
|
||||
(ref, params) async {
|
||||
final (playlist, categoryId) = params;
|
||||
final service = await ref.watch(mobileXtreamServiceProvider(playlist).future);
|
||||
return service.getSeriesPaginated(categoryId: categoryId);
|
||||
@@ -161,7 +198,8 @@ class SeriesInfoRequest {
|
||||
}
|
||||
|
||||
final mobileSeriesInfoByPlaylistProvider =
|
||||
FutureProvider.family<model.SeriesInfo?, SeriesInfoRequest>((ref, request) async {
|
||||
FutureProvider.family<model.SeriesInfo?, SeriesInfoRequest>(
|
||||
(ref, request) async {
|
||||
final service =
|
||||
await ref.watch(mobileXtreamServiceProvider(request.playlist).future);
|
||||
return service.getSeriesInfo(request.seriesId);
|
||||
|
||||
Reference in new issue
Block a user