mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-22 22:48:04 +02:00
Multi-IPTV : le quota du navigateur ne doit plus écraser le choix d'IPTV
Console du navigateur, à deux playlists : QuotaExceededError: Failed to execute 'setItem' on 'Storage': Setting the value of 'xtream_cache_<id>_live_channels' exceeded the quota. Les catalogues mis en cache (chaînes, films, séries), plusieurs Mo par IPTV, saturent le stockage. L'erreur était avalée, mais le stockage restait plein : toute écriture suivante échouait, dont celle de localStorage['selected_playlist']. L'entrée gardait l'IPTV précédente, AuthedHttp envoyait un X-Playlist-Id périmé, le serveur résolvait la même playlist pour les deux, et Auto NBA n'avait qu'une règle commune — désactivée d'un côté, désactivée de l'autre. - persistSelectedPlaylist purge les catalogues et réessaye avant de renoncer ; elle ne lève plus jamais, sans quoi le clic de sélection n'aurait plus posé l'état du tout. - _saveToLocalCache purge les catalogues des autres IPTV puis réessaye : un catalogue se recharge depuis le serveur, le choix d'IPTV ne se devine pas. Non vérifié localement : le SDK Flutter de cette machine (3.10.3) est antérieur au ^3.13.0 exigé par le projet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5169d0843a
commit
52504d4e1a
2 files changed
+61
-8
No files matched your search
@@ -57,14 +57,48 @@ final selectedPlaylistProvider = StateProvider<PlaylistConfig?>((ref) {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Préfixe des caches de catalogue (chaînes, films, séries) par IPTV.
|
||||||
|
const xtreamCachePrefix = 'xtream_cache_';
|
||||||
|
|
||||||
|
/// Vide les caches de catalogue pour rendre de la place.
|
||||||
|
///
|
||||||
|
/// Ces caches pèsent plusieurs mégaoctets par IPTV et saturent le quota du
|
||||||
|
/// navigateur ; ils se reconstruisent au prochain chargement.
|
||||||
|
void clearXtreamCaches() {
|
||||||
|
final keys = html.window.localStorage.keys
|
||||||
|
.where((k) => k.startsWith(xtreamCachePrefix))
|
||||||
|
.toList();
|
||||||
|
for (final key in keys) {
|
||||||
|
html.window.localStorage.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Écrit l'IPTV courante là où `AuthedHttp` la relit pour poser l'en-tête
|
/// Écrit l'IPTV courante là où `AuthedHttp` la relit pour poser l'en-tête
|
||||||
/// `X-Playlist-Id`.
|
/// `X-Playlist-Id`.
|
||||||
|
///
|
||||||
|
/// Quota saturé, `setItem` lève : les caches de catalogue remplissent le
|
||||||
|
/// stockage et faisaient échouer cette écriture-ci, minuscule mais décisive.
|
||||||
|
/// L'entrée restait sur l'IPTV précédente, l'en-tête désignait la mauvaise
|
||||||
|
/// playlist, et les deux IPTV retombaient sur la même. Le catalogue cède donc
|
||||||
|
/// la place, et un échec résiduel ne doit jamais empêcher le changement
|
||||||
|
/// d'IPTV.
|
||||||
void persistSelectedPlaylist(PlaylistConfig? playlist) {
|
void persistSelectedPlaylist(PlaylistConfig? playlist) {
|
||||||
if (playlist != null) {
|
if (playlist == null) {
|
||||||
html.window.localStorage['selected_playlist'] =
|
try {
|
||||||
jsonEncode(playlist.toJson());
|
html.window.localStorage.remove('selected_playlist');
|
||||||
} else {
|
} catch (_) {}
|
||||||
html.window.localStorage.remove('selected_playlist');
|
return;
|
||||||
|
}
|
||||||
|
final value = jsonEncode(playlist.toJson());
|
||||||
|
try {
|
||||||
|
html.window.localStorage['selected_playlist'] = value;
|
||||||
|
} catch (_) {
|
||||||
|
try {
|
||||||
|
clearXtreamCaches();
|
||||||
|
html.window.localStorage['selected_playlist'] = value;
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('Impossible de persister l\'IPTV choisie: $e');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -333,12 +333,31 @@ class XtreamService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Met le catalogue en cache, en cédant la place plutôt qu'en saturant.
|
||||||
|
///
|
||||||
|
/// Un catalogue pèse plusieurs mégaoctets et il y en a un par IPTV : à deux
|
||||||
|
/// playlists, le quota du navigateur était atteint. L'erreur était avalée
|
||||||
|
/// ici, mais le stockage restait plein — et toute autre écriture échouait
|
||||||
|
/// à son tour, à commencer par celle de l'IPTV sélectionnée, bien plus
|
||||||
|
/// importante que ce cache. On purge donc les catalogues des autres IPTV
|
||||||
|
/// avant de réessayer, puis on renonce : ils se rechargent depuis le
|
||||||
|
/// serveur, le choix d'IPTV, lui, ne se devine pas.
|
||||||
void _saveToLocalCache(String key, Map<String, dynamic> data) {
|
void _saveToLocalCache(String key, Map<String, dynamic> data) {
|
||||||
if (!kIsWeb) return;
|
if (!kIsWeb) return;
|
||||||
|
final storageKey = 'xtream_cache_${_currentPlaylist?.id}_$key';
|
||||||
|
final jsonStr = jsonEncode(data);
|
||||||
try {
|
try {
|
||||||
final jsonStr = jsonEncode(data);
|
html.window.localStorage[storageKey] = jsonStr;
|
||||||
html.window.localStorage['xtream_cache_${_currentPlaylist?.id}_$key'] =
|
return;
|
||||||
jsonStr;
|
} catch (_) {}
|
||||||
|
try {
|
||||||
|
final stale = html.window.localStorage.keys
|
||||||
|
.where((k) => k.startsWith('xtream_cache_') && k != storageKey)
|
||||||
|
.toList();
|
||||||
|
for (final k in stale) {
|
||||||
|
html.window.localStorage.remove(k);
|
||||||
|
}
|
||||||
|
html.window.localStorage[storageKey] = jsonStr;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Error saving to local cache ($key): $e');
|
debugPrint('Error saving to local cache ($key): $e');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user