mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-11 17:30:00 +02:00
Merge pull request #10 from R0m1k3/antigravity
chore: Stop explicitly copying pubspec.lock as flutter pub get genera…
This commit is contained in:
commit
4ad68c7a50
9 files changed
+96
-8
No files matched your search
+2
-1
@@ -14,9 +14,10 @@ RUN git config --global --add safe.directory /app
|
||||
RUN flutter config --enable-web
|
||||
|
||||
# Copy dependency files first for better caching
|
||||
# Note: pubspec.lock will be generated by flutter pub get if missing
|
||||
COPY pubspec.yaml ./
|
||||
|
||||
# Get dependencies
|
||||
# Get dependencies (generates pubspec.lock automatically)
|
||||
RUN flutter pub get
|
||||
|
||||
# Copy source code
|
||||
|
||||
@@ -71,6 +71,7 @@ class Series {
|
||||
final String name;
|
||||
final String? cover;
|
||||
final String? categoryId;
|
||||
final String categoryName;
|
||||
final String? rating;
|
||||
|
||||
const Series({
|
||||
@@ -78,6 +79,7 @@ class Series {
|
||||
required this.name,
|
||||
this.cover,
|
||||
this.categoryId,
|
||||
this.categoryName = '',
|
||||
this.rating,
|
||||
});
|
||||
|
||||
@@ -87,6 +89,7 @@ class Series {
|
||||
name: json['name']?.toString() ?? 'Unknown',
|
||||
cover: json['cover']?.toString(),
|
||||
categoryId: json['category_id']?.toString(),
|
||||
categoryName: json['category_name']?.toString() ?? '',
|
||||
rating: json['rating']?.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,16 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../../core/models/playlist_config.dart';
|
||||
import '../services/xtream_service.dart';
|
||||
|
||||
/// Singleton Xtream service provider
|
||||
final xtreamServiceProvider = Provider<XtreamService>((ref) {
|
||||
/// Family provider for Xtream service - one instance per playlist
|
||||
final xtreamServiceProvider = Provider.family<XtreamService, PlaylistConfig>((ref, playlist) {
|
||||
final service = XtreamService();
|
||||
service.setPlaylist(playlist);
|
||||
ref.onDispose(() => service.dispose());
|
||||
return service;
|
||||
});
|
||||
|
||||
/// Singleton Xtream service provider (legacy, for activeXtreamServiceProvider)
|
||||
final _singletonXtreamServiceProvider = Provider<XtreamService>((ref) {
|
||||
final service = XtreamService();
|
||||
ref.onDispose(() => service.dispose());
|
||||
return service;
|
||||
@@ -14,7 +22,7 @@ final selectedPlaylistProvider = StateProvider<PlaylistConfig?>((ref) => null);
|
||||
|
||||
/// Provider that watches for playlist changes and updates Xtream service
|
||||
final activeXtreamServiceProvider = Provider<XtreamService>((ref) {
|
||||
final service = ref.watch(xtreamServiceProvider);
|
||||
final service = ref.watch(_singletonXtreamServiceProvider);
|
||||
final playlist = ref.watch(selectedPlaylistProvider);
|
||||
|
||||
if (playlist != null) {
|
||||
|
||||
@@ -28,7 +28,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tabs = [
|
||||
LiveTVTab(playlist: widget.playlist),
|
||||
const LiveTVTab(),
|
||||
MoviesTab(playlist: widget.playlist),
|
||||
SeriesTab(playlist: widget.playlist),
|
||||
const SettingsTab(),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
|
||||
import 'package:dio_cache_interceptor_hive_store/dio_cache_interceptor_hive_store.dart';
|
||||
import '../../../core/models/playlist_config.dart';
|
||||
import '../../../core/models/iptv_models.dart';
|
||||
import '../models/xtream_models.dart' as xm;
|
||||
|
||||
/// Xtream Codes API Service
|
||||
///
|
||||
@@ -180,6 +181,68 @@ class XtreamService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get movies with pagination support
|
||||
Future<List<xm.Movie>> getMovies({int offset = 0, int limit = 100}) async {
|
||||
if (_currentPlaylist == null) throw Exception('No playlist configured');
|
||||
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
_currentPlaylist!.apiBaseUrl,
|
||||
queryParameters: {
|
||||
'username': _currentPlaylist!.username,
|
||||
'password': _currentPlaylist!.password,
|
||||
'action': 'get_vod_streams',
|
||||
},
|
||||
options: Options(extra: _cacheOptions.toExtra()),
|
||||
);
|
||||
|
||||
final List<dynamic> allMovies = response.data as List<dynamic>;
|
||||
|
||||
// Apply pagination
|
||||
final endIndex = (offset + limit) > allMovies.length ? allMovies.length : offset + limit;
|
||||
if (offset >= allMovies.length) return [];
|
||||
|
||||
final paginatedMovies = allMovies.sublist(offset, endIndex);
|
||||
|
||||
return paginatedMovies
|
||||
.map((movieData) => xm.Movie.fromJson(movieData as Map<String, dynamic>))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
throw Exception('Failed to fetch movies: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get series with pagination support (returns flat list)
|
||||
Future<List<xm.Series>> getSeriesPaginated({int offset = 0, int limit = 100}) async {
|
||||
if (_currentPlaylist == null) throw Exception('No playlist configured');
|
||||
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
_currentPlaylist!.apiBaseUrl,
|
||||
queryParameters: {
|
||||
'username': _currentPlaylist!.username,
|
||||
'password': _currentPlaylist!.password,
|
||||
'action': 'get_series',
|
||||
},
|
||||
options: Options(extra: _cacheOptions.toExtra()),
|
||||
);
|
||||
|
||||
final List<dynamic> allSeries = response.data as List<dynamic>;
|
||||
|
||||
// Apply pagination
|
||||
final endIndex = (offset + limit) > allSeries.length ? allSeries.length : offset + limit;
|
||||
if (offset >= allSeries.length) return [];
|
||||
|
||||
final paginatedSeries = allSeries.sublist(offset, endIndex);
|
||||
|
||||
return paginatedSeries
|
||||
.map((seriesData) => xm.Series.fromJson(seriesData as Map<String, dynamic>))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
throw Exception('Failed to fetch series: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get short EPG for a specific stream
|
||||
///
|
||||
/// Returns "Now" and "Next" program info
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../core/models/playlist_config.dart';
|
||||
import '../models/xtream_models.dart';
|
||||
import '../providers/xtream_provider.dart';
|
||||
import '../screens/video_player_screen.dart';
|
||||
|
||||
class MoviesTab extends ConsumerStatefulWidget {
|
||||
final PlaylistConfig playlist;
|
||||
|
||||
const MoviesTab({super.key, required this.playlist});
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../core/models/playlist_config.dart';
|
||||
import '../services/xtream_service.dart';
|
||||
import '../models/xtream_models.dart';
|
||||
import '../providers/xtream_provider.dart';
|
||||
|
||||
class SeriesTab extends ConsumerStatefulWidget {
|
||||
final PlaylistConfig playlist;
|
||||
@@ -52,7 +53,7 @@ class _SeriesTabState extends ConsumerState<SeriesTab> {
|
||||
|
||||
try {
|
||||
final service = ref.read(xtreamServiceProvider(widget.playlist));
|
||||
final newSeries = await service.getSeries(
|
||||
final newSeries = await service.getSeriesPaginated(
|
||||
offset: _currentOffset,
|
||||
limit: _pageSize,
|
||||
);
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ class MyApp extends ConsumerWidget {
|
||||
seedColor: Colors.blue,
|
||||
brightness: Brightness.light,
|
||||
),
|
||||
cardTheme: CardTheme(
|
||||
cardTheme: CardThemeData(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -41,7 +41,7 @@ class MyApp extends ConsumerWidget {
|
||||
seedColor: Colors.blue,
|
||||
brightness: Brightness.dark,
|
||||
),
|
||||
cardTheme: CardTheme(
|
||||
cardTheme: CardThemeData(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
|
||||
@@ -30,6 +30,8 @@ dependencies:
|
||||
video_player: ^2.8.2
|
||||
video_player_web: ^2.3.0 # Required for web platform
|
||||
chewie: ^1.7.5
|
||||
media_kit: ^1.1.10
|
||||
media_kit_video: ^1.2.4
|
||||
|
||||
# UI Components
|
||||
google_fonts: ^6.1.0
|
||||
|
||||
Reference in new issue
Block a user