mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-20 05:28:05 +02:00
fix(ui): prevent NaN division crash in TvChannelGrid and fix playlist silent failure
- tv_channel_grid.dart: guard screenWidth <= 0 / NaN / Infinite on first Flutter Web layout pass (previously caused NaN ~/ 225.03 crash cascade). Also use .clamp(1.0, infinity) on item width for belt-and-suspenders safety. Fix invalid 'padding.vertical as double?' cast in TvHorizontalList by using padding.resolve(TextDirection.ltr).top instead. - playlist_api_service.dart: remove silent catch-and-return-empty in getPlaylists(). Exceptions now propagate to the Riverpod FutureProvider so the UI shows the real error state (with Retry button) instead of a misleading 'No playlists available' when the API call actually failed (e.g., 401 Unauthorized or network error).
This commit is contained in:
1 parent
288bf9e6ee
commit
9755f51af5
2 files changed
+40
-28
No files matched your search
@@ -5,28 +5,29 @@ import '../models/playlist_config.dart';
|
||||
class PlaylistApiService {
|
||||
final ApiClient _api = ApiClient();
|
||||
|
||||
/// Get all playlists for current user
|
||||
/// Get all playlists for current user.
|
||||
///
|
||||
/// Throws on API error so the Riverpod [FutureProvider] can expose the
|
||||
/// [AsyncError] state — ensuring the UI shows a proper error with Retry,
|
||||
/// instead of silently rendering an empty list.
|
||||
Future<List<PlaylistConfig>> getPlaylists() async {
|
||||
try {
|
||||
final response = await _api.get('/api/playlists');
|
||||
final data = response.data as Map<String, dynamic>;
|
||||
final playlistsData = data['playlists'] as List<dynamic>;
|
||||
final response = await _api.get('/api/playlists');
|
||||
final data = response.data as Map<String, dynamic>;
|
||||
final playlistsData = data['playlists'] as List<dynamic>;
|
||||
|
||||
return playlistsData.map((p) {
|
||||
final playlist = p as Map<String, dynamic>;
|
||||
return PlaylistConfig(
|
||||
id: playlist['id'] as String,
|
||||
name: playlist['name'] as String,
|
||||
dns: playlist['serverUrl'] as String? ?? playlist['dns'] as String,
|
||||
username: playlist['username'] as String,
|
||||
password: playlist['password'] as String,
|
||||
createdAt: DateTime.tryParse(playlist['createdAt'] as String? ?? '') ?? DateTime.now(),
|
||||
);
|
||||
}).toList();
|
||||
} catch (e) {
|
||||
print('Error fetching playlists: $e');
|
||||
return [];
|
||||
}
|
||||
return playlistsData.map((p) {
|
||||
final playlist = p as Map<String, dynamic>;
|
||||
return PlaylistConfig(
|
||||
id: playlist['id'] as String,
|
||||
name: playlist['name'] as String,
|
||||
dns: playlist['serverUrl'] as String? ?? playlist['dns'] as String,
|
||||
username: playlist['username'] as String,
|
||||
password: playlist['password'] as String,
|
||||
createdAt:
|
||||
DateTime.tryParse(playlist['createdAt'] as String? ?? '') ??
|
||||
DateTime.now(),
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/// Create a new playlist
|
||||
|
||||
Reference in new issue
Block a user