mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-21 22:18:04 +02:00
fix(epg,ui): utiliser get_simple_data_table pour l'EPG et recaler la sidebar sur le thème
EPG — les trois chemins (backend /api/epg, XtreamService.getShortEpg et getShortEPG) n'utilisaient que get_epg et get_short_epg. Beaucoup de panneaux Xtream ne connaissent pas get_epg : ils répondent 200 avec le bloc d'authentification, sans epg_listings, ce qui produisait un guide vide indiscernable d'une chaîne sans programme. get_short_epg y renvoie epg_listings vide en permanence. - backend : get_simple_data_table en premier, get_short_epg en repli - client : bascule automatique et mémorisée vers le tableau complet dès qu'un panneau est muet sur l'action légère, pour ne pas doubler les requêtes sur chaque tuile de grille - dates dérivées des *_timestamp epoch et émises en ISO-8601 UTC : les champs texte sont dans le fuseau du panneau, sans indicateur de zone, et étaient relus comme de l'heure locale — le guide était décalé et les enregistrements planifiés depuis le guide l'étaient aussi - cache backend : la clé incluait seulement le channelId, deux playlists partageant un stream_id se servaient mutuellement leur guide UI — les deux halos d'ambiance du dashboard étaient restés de l'ancien thème : primary (#FFB68C) à 40 % posé sur le coin haut-gauche, donc pile derrière la sidebar, et info (#A3B8C4, bleu-gris) à 35 % dans une palette entièrement chaude. Ramenés à des braises ember à 8 % / 6 %. - fond via AppColors.backgroundGradient - onglet actif rempli en primaryContainer (surface) et non primary (teinte claire réservée au texte/icônes) - sidebar en niveau flottant : en niveau 1 son fond #181310 se confondait avec le haut du dégradé #1A1310 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
095eb2c1b0
commit
537312908a
4 files changed
+286
-114
No files matched your search
@@ -0,0 +1,74 @@
|
||||
import 'package:test/test.dart';
|
||||
import '../api/epg_api.dart';
|
||||
|
||||
/// Extrait réel d'une réponse `get_simple_data_table` (panneau Xtream) :
|
||||
/// titres/descriptions en base64, horodatages epoch UTC doublés d'une chaîne
|
||||
/// exprimée dans le fuseau du panneau — ici Europe/Amsterdam (UTC+2).
|
||||
const _sampleListing = {
|
||||
'epg_listings': [
|
||||
{
|
||||
'id': '336987829',
|
||||
'epg_id': '104',
|
||||
'title': 'Sm91cm5hbCBkZSAyMGg=', // "Journal de 20h"
|
||||
'lang': '',
|
||||
'start': '2026-08-11 20:00:00',
|
||||
'end': '2026-08-11 20:35:00',
|
||||
'description': 'TCdpbmZvIGR1IHNvaXI=', // "L'info du soir"
|
||||
'channel_id': 'TF1.fr',
|
||||
'start_timestamp': '1786471200', // 2026-08-11T18:00:00Z
|
||||
'stop_timestamp': '1786473300', // 2026-08-11T18:35:00Z
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
void main() {
|
||||
final api = EpgApi((_) async => null);
|
||||
|
||||
group('transformEpgData', () {
|
||||
test('convertit les horodatages epoch en ISO-8601 UTC', () {
|
||||
final result = api.transformEpgData(_sampleListing, '845452');
|
||||
final programme = (result['programmes'] as List).single as Map;
|
||||
|
||||
// Sans cette conversion, le client relisait « 2026-08-11T20:00:00 »
|
||||
// comme de l'heure locale et décalait tout le guide de 2 h.
|
||||
expect(programme['start'], '2026-08-11T18:00:00.000Z');
|
||||
expect(programme['end'], '2026-08-11T18:35:00.000Z');
|
||||
});
|
||||
|
||||
test('décode les titres et descriptions base64', () {
|
||||
final result = api.transformEpgData(_sampleListing, '845452');
|
||||
final programme = (result['programmes'] as List).single as Map;
|
||||
|
||||
expect(programme['title'], 'Journal de 20h');
|
||||
expect(programme['description'], "L'info du soir");
|
||||
expect(programme['channel_id'], '845452');
|
||||
});
|
||||
|
||||
test('retombe sur les champs texte quand les epoch manquent', () {
|
||||
final result = api.transformEpgData({
|
||||
'epg_listings': [
|
||||
{
|
||||
'title': 'Sm91cm5hbCBkZSAyMGg=',
|
||||
'start': '2026-08-11 20:00:00',
|
||||
'stop': '2026-08-11 20:35:00',
|
||||
},
|
||||
],
|
||||
}, '845452');
|
||||
final programme = (result['programmes'] as List).single as Map;
|
||||
|
||||
expect(programme['start'], '2026-08-11T20:00:00');
|
||||
expect(programme['end'], '2026-08-11T20:35:00');
|
||||
});
|
||||
|
||||
test('rend une liste vide sur un payload sans epg_listings', () {
|
||||
// Ce que renvoie un panneau qui ne connaît pas l'action demandée :
|
||||
// un 200 contenant le bloc d'authentification.
|
||||
final result = api.transformEpgData({
|
||||
'user_info': {'auth': 1},
|
||||
'server_info': {'url': 'tit.example'},
|
||||
}, '845452');
|
||||
|
||||
expect(result['programmes'], isEmpty);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user