mirror of
https://github.com/R0m1k3/xtremobile.git
synced 2026-10-17 04:08:29 +02:00
feat: add XtreamServiceMobile for Xtream Codes API communication with caching and DNS resolution for mobile.
This commit is contained in:
1 parent
80320d0eae
commit
5dd83019d3
8 files changed
+107
-177
No files matched your search
@@ -4,13 +4,13 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../../../core/models/playlist_config.dart';
|
||||
import '../../../../core/theme/app_colors.dart';
|
||||
import '../../../theme/mobile_theme.dart';
|
||||
import '../../../services/local_playlist_service.dart';
|
||||
import '../../../../core/services/playlist_api_service.dart';
|
||||
import 'mobile_dashboard_screen.dart';
|
||||
|
||||
/// Provider for local playlists
|
||||
final localPlaylistsProvider =
|
||||
FutureProvider<List<PlaylistConfig>>((ref) async {
|
||||
final service = LocalPlaylistService();
|
||||
final service = PlaylistApiService();
|
||||
return service.getPlaylists();
|
||||
});
|
||||
|
||||
@@ -24,12 +24,12 @@ class MobilePlaylistScreen extends ConsumerStatefulWidget {
|
||||
}
|
||||
|
||||
class _MobilePlaylistScreenState extends ConsumerState<MobilePlaylistScreen> {
|
||||
final LocalPlaylistService _playlistService = LocalPlaylistService();
|
||||
final PlaylistApiService _playlistService = PlaylistApiService();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_playlistService.init();
|
||||
// _playlistService.init(); // PlaylistAPI service inits internally via HiveService
|
||||
|
||||
// Auto-login: if playlists exist, navigate to first one automatically
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -40,7 +40,7 @@ class _MobilePlaylistScreenState extends ConsumerState<MobilePlaylistScreen> {
|
||||
Future<void> _checkAutoLogin() async {
|
||||
try {
|
||||
final playlists = await _playlistService.getPlaylists();
|
||||
if (playlists.isNotEmpty && mounted) {
|
||||
if (playlists.length == 1 && mounted) {
|
||||
// Navigate to first playlist automatically
|
||||
_navigateToDashboard(playlists.first);
|
||||
}
|
||||
@@ -211,7 +211,7 @@ class _MobilePlaylistScreenState extends ConsumerState<MobilePlaylistScreen> {
|
||||
password: passwordController.text.trim(),
|
||||
);
|
||||
} else {
|
||||
await _playlistService.addPlaylist(
|
||||
await _playlistService.createPlaylist(
|
||||
name: nameController.text.trim(),
|
||||
dns: dns,
|
||||
username: usernameController.text.trim(),
|
||||
|
||||
@@ -37,9 +37,8 @@ class _MobilePlaylistSelectionScreenState
|
||||
|
||||
Future<void> _checkAutoLogin() async {
|
||||
final playlists = await ref.read(playlistsProvider.future);
|
||||
if (playlists.isNotEmpty && mounted) {
|
||||
// Auto-login to the first playlist (or last used)
|
||||
// Ideally last used, but for now first is fine as per request "une playlist existe".
|
||||
// Only auto-login if there is exactly ONE playlist
|
||||
if (playlists.length == 1 && mounted) {
|
||||
context.go('/dashboard', extra: playlists.first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import '../../../../core/models/playlist_config.dart';
|
||||
import '../../../../core/theme/app_colors.dart';
|
||||
import '../../../providers/mobile_settings_providers.dart';
|
||||
import '../../../providers/mobile_xtream_providers.dart';
|
||||
import '../../../../features/iptv/services/xtream_service_mobile.dart';
|
||||
|
||||
import '../screens/native_player_screen.dart';
|
||||
|
||||
class MobileMoviesTab extends ConsumerStatefulWidget {
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import '../../core/models/playlist_config.dart';
|
||||
|
||||
/// Local playlist storage service for mobile
|
||||
/// Uses Hive for persistent local storage
|
||||
class LocalPlaylistService {
|
||||
static const String _boxName = 'playlists_mobile';
|
||||
Box<PlaylistConfig>? _box;
|
||||
|
||||
/// Initialize the service and open the Hive box
|
||||
Future<void> init() async {
|
||||
if (_box != null && _box!.isOpen) return;
|
||||
|
||||
// Register adapter if not already registered
|
||||
if (!Hive.isAdapterRegistered(1)) {
|
||||
Hive.registerAdapter(PlaylistConfigAdapter());
|
||||
}
|
||||
|
||||
_box = await Hive.openBox<PlaylistConfig>(_boxName);
|
||||
}
|
||||
|
||||
/// Get all playlists
|
||||
Future<List<PlaylistConfig>> getPlaylists() async {
|
||||
await init();
|
||||
return _box!.values.toList();
|
||||
}
|
||||
|
||||
/// Add a new playlist
|
||||
Future<PlaylistConfig> addPlaylist({
|
||||
required String name,
|
||||
required String dns,
|
||||
required String username,
|
||||
required String password,
|
||||
}) async {
|
||||
await init();
|
||||
|
||||
final playlist = PlaylistConfig(
|
||||
id: const Uuid().v4(),
|
||||
name: name,
|
||||
dns: dns.endsWith('/') ? dns.substring(0, dns.length - 1) : dns,
|
||||
username: username,
|
||||
password: password,
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
|
||||
await _box!.put(playlist.id, playlist);
|
||||
return playlist;
|
||||
}
|
||||
|
||||
/// Update an existing playlist
|
||||
Future<PlaylistConfig?> updatePlaylist({
|
||||
required String id,
|
||||
required String name,
|
||||
required String dns,
|
||||
required String username,
|
||||
required String password,
|
||||
}) async {
|
||||
await init();
|
||||
|
||||
final existing = _box!.get(id);
|
||||
if (existing == null) return null;
|
||||
|
||||
final updated = existing.copyWith(
|
||||
name: name,
|
||||
dns: dns.endsWith('/') ? dns.substring(0, dns.length - 1) : dns,
|
||||
username: username,
|
||||
password: password,
|
||||
);
|
||||
|
||||
await _box!.put(id, updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
/// Delete a playlist
|
||||
Future<bool> deletePlaylist(String id) async {
|
||||
await init();
|
||||
await _box!.delete(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Get a single playlist by ID
|
||||
Future<PlaylistConfig?> getPlaylist(String id) async {
|
||||
await init();
|
||||
return _box!.get(id);
|
||||
}
|
||||
|
||||
/// Close the box when done
|
||||
Future<void> dispose() async {
|
||||
await _box?.close();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user