From 2c6545970e036adac06af9298a65a50649c7c6ae Mon Sep 17 00:00:00 2001 From: Michael SCHAL Date: Mon, 8 Dec 2025 16:16:12 +0100 Subject: [PATCH] feat: Add Movies tab with search, pagination, and hero carousel for movie browsing. --- lib/features/iptv/models/xtream_models.dart | 8 +++++++- lib/features/iptv/widgets/movies_tab.dart | 13 ++----------- lib/features/iptv/widgets/series_tab.dart | 13 ++----------- 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/lib/features/iptv/models/xtream_models.dart b/lib/features/iptv/models/xtream_models.dart index 7b711d2..6f41e20 100644 --- a/lib/features/iptv/models/xtream_models.dart +++ b/lib/features/iptv/models/xtream_models.dart @@ -55,10 +55,16 @@ class Movie { }); factory Movie.fromJson(Map json) { + // Essayer plusieurs champs possibles pour l'image (différentes API Xtream utilisent différents noms) + final imageUrl = json['stream_icon']?.toString() ?? + json['cover']?.toString() ?? + json['movie_image']?.toString() ?? + json['cover_big']?.toString(); + return Movie( streamId: json['stream_id']?.toString() ?? '', name: json['name']?.toString() ?? 'Unknown', - streamIcon: json['stream_icon']?.toString(), + streamIcon: imageUrl, categoryId: json['category_id']?.toString(), categoryName: json['category_name']?.toString() ?? '', containerExtension: json['container_extension']?.toString() ?? 'mp4', diff --git a/lib/features/iptv/widgets/movies_tab.dart b/lib/features/iptv/widgets/movies_tab.dart index c9c9664..3eefb66 100644 --- a/lib/features/iptv/widgets/movies_tab.dart +++ b/lib/features/iptv/widgets/movies_tab.dart @@ -157,15 +157,6 @@ class _MoviesTabState extends ConsumerState { ); } - String? _getProxiedIconUrl(String? originalUrl) { - if (originalUrl == null || originalUrl.isEmpty) return null; - // Proxy toutes les URLs externes (http et https) via notre serveur - if (originalUrl.startsWith('http://') || originalUrl.startsWith('https://')) { - return '/api/xtream/$originalUrl'; - } - return originalUrl; - } - @override Widget build(BuildContext context) { final settings = ref.watch(iptvSettingsProvider); @@ -184,7 +175,7 @@ class _MoviesTabState extends ConsumerState { final heroItems = displayMovies.take(5).map((m) => HeroItem( id: m.streamId, title: m.name, - imageUrl: _getProxiedIconUrl(m.streamIcon) ?? '', + imageUrl: m.streamIcon ?? '', subtitle: m.rating != null ? '${_formatRating(m.rating)} ★' : null, onMoreInfo: () { _playMovie(m); @@ -300,7 +291,7 @@ class _MoviesTabState extends ConsumerState { return MediaCard( title: movie.name, - imageUrl: _getProxiedIconUrl(movie.streamIcon), + imageUrl: movie.streamIcon, subtitle: movie.rating != null ? '${_formatRating(movie.rating)} ★' : null, rating: _formatRating(movie.rating), diff --git a/lib/features/iptv/widgets/series_tab.dart b/lib/features/iptv/widgets/series_tab.dart index b86b8f2..e91beab 100644 --- a/lib/features/iptv/widgets/series_tab.dart +++ b/lib/features/iptv/widgets/series_tab.dart @@ -152,15 +152,6 @@ class _SeriesTabState extends ConsumerState { ); } - String? _getProxiedIconUrl(String? originalUrl) { - if (originalUrl == null || originalUrl.isEmpty) return null; - // Proxy toutes les URLs externes (http et https) via notre serveur - if (originalUrl.startsWith('http://') || originalUrl.startsWith('https://')) { - return '/api/xtream/$originalUrl'; - } - return originalUrl; - } - @override Widget build(BuildContext context) { final settings = ref.watch(iptvSettingsProvider); @@ -182,7 +173,7 @@ class _SeriesTabState extends ConsumerState { final heroItems = displaySeries.take(5).map((s) => HeroItem( id: s.seriesId.toString(), // ID logic might differ for Series title: s.name, - imageUrl: _getProxiedIconUrl(s.cover) ?? '', + imageUrl: s.cover ?? '', subtitle: s.rating != null ? '${_formatRating(s.rating)} ★' : null, onMoreInfo: () => _openSeries(s), )).toList(); @@ -290,7 +281,7 @@ class _SeriesTabState extends ConsumerState { final serie = displaySeries[index]; return MediaCard( title: serie.name, - imageUrl: _getProxiedIconUrl(serie.cover), + imageUrl: serie.cover, subtitle: serie.rating != null ? '${_formatRating(serie.rating)} ★' : null, rating: _formatRating(serie.rating),