fix(mobile): fix XtreamService cache/URL logic and add tab error handling

This commit is contained in:
Michael committed 2026-03-09 18:18:20 +01:00
1 parent e4f8ebcf8f
commit 39f4205d68
2 files changed
+51 -5

No files matched your search

+10 -3
View File
@@ -18,14 +18,16 @@ class XtreamService {
XtreamService() {
_dio = Dio(
BaseOptions(
connectTimeout: const Duration(seconds: 30),
receiveTimeout: const Duration(seconds: 30),
connectTimeout: const Duration(seconds: 15),
receiveTimeout: const Duration(seconds: 15),
sendTimeout: const Duration(seconds: 15),
),
);
// Setup caching for API responses
// Use MemCacheStore on Web to avoid path errors
_cacheOptions = CacheOptions(
store: HiveCacheStore('./cache'),
store: kIsWeb ? MemCacheStore() : HiveCacheStore('./cache'),
policy: CachePolicy.forceCache,
maxStale: const Duration(hours: 1),
priority: CachePriority.high,
@@ -47,11 +49,16 @@ class XtreamService {
}
if (kIsWeb) {
final origin = Uri.base.origin;
// If we are developing locally on a different port than the backend
if (origin.contains('localhost') && !origin.contains('8089')) {
return 'http://localhost:8089';
}
// On mobile devices, 'localhost' is the device itself.
// If origin is localhost but we are on mobile web, it might fail.
// We assume the user is accessing via an IP or hostname.
return origin;
}
// Android emulator bridge
return 'http://10.0.2.2:8089';
}
@@ -42,9 +42,48 @@ class _MobileLiveTVTabState extends ConsumerState<MobileLiveTVTab> {
return Scaffold(
backgroundColor: Colors.transparent, // Handled by MobileScaffold
body: channelsAsync.when(
loading: () => const Center(child: CircularProgressIndicator()),
loading: () => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircularProgressIndicator(),
const SizedBox(height: 16),
const Text('Loading channels...', style: TextStyle(color: Colors.white70)),
const SizedBox(height: 24),
FutureBuilder(
future: Future.delayed(const Duration(seconds: 8)),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return TextButton(
onPressed: () => ref.refresh(liveChannelsByPlaylistProvider(widget.playlist)),
child: const Text('Taking too long? Tap to retry'),
);
}
return const SizedBox.shrink();
},
),
],
),
),
error: (e, s) => Center(
child: Text('Error: $e', style: const TextStyle(color: Colors.white)),
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.error_outline, color: Colors.red, size: 48),
const SizedBox(height: 16),
Text('Failed to load channels', style: GoogleFonts.inter(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text('$e', style: const TextStyle(color: Colors.white54), textAlign: TextAlign.center),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () => ref.refresh(liveChannelsByPlaylistProvider(widget.playlist)),
child: const Text('Retry'),
),
],
),
),
),
data: (groupedChannels) {
var categories = groupedChannels.keys.toList();