mirror of
https://github.com/R0m1k3/xtremobile.git
synced 2026-10-24 07:38:16 +02:00
fix(theme): remove every hardcoded Apple/Material colour left in the UI
Porting the palette was not enough: the Warm Cinema charter only reached the widgets that read from AppColors. Nineteen screen and widget files still painted Apple TV values inline, so the app kept showing blue — most visibly on the selected navigation pill. Swept out: - 0xFF0A84FF (Apple blue) on the selected nav pill, category card icons and the "add playlist" button - 0xFF4FC3F7 and 0xFF1565C0 in the player overlays - Colors.blueAccent / Colors.blue in dialogs - Apple greys 1C1C1E / 2C2C2E / 3A3A3C / 8E8E93 -> warm charcoals - 128 Colors.white* -> the onSurfaceNN cream ladder (a pure white on a warm ground reads blue, which is the charter's whole point) - Colors.red / green / amber / yellow / grey* -> error, success, ratingGold, outlineVariant - pure black ink on light fills -> onPrimaryFixed, a warm near-black - the white focus glow -> an ember glow Deliberately left true black: the video surface backgrounds and the scrims over posters and video, where a warm tint would clash with the picture. Adds the onPrimaryFixed / primaryFixed / onSurface70 tokens the sweep needed. Verified: no Material or Apple colour literal remains outside lib/core/theme; flutter analyze reports no errors; 19/19 tests pass; release APK builds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8d74bbb320
commit
694b1257b9
21 files changed
+221
-184
No files matched your search
@@ -16,6 +16,7 @@ import 'package:xtremobile/features/iptv/screens/lite_player_screen.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:xtremobile/core/services/ip_service.dart';
|
||||
import 'package:xtremobile/core/models/iptv_models.dart' as model;
|
||||
import 'package:xtremobile/core/theme/app_colors.dart';
|
||||
|
||||
class MobileLiveTVTab extends ConsumerStatefulWidget {
|
||||
final PlaylistConfig playlist;
|
||||
@@ -130,14 +131,14 @@ class _MobileLiveTVTabState extends ConsumerState<MobileLiveTVTab>
|
||||
final shouldExit = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
backgroundColor: Colors.grey[900],
|
||||
backgroundColor: AppColors.surfaceContainerLowest,
|
||||
title: const Text(
|
||||
"Quitter l'application",
|
||||
style: TextStyle(color: Colors.white),
|
||||
style: TextStyle(color: AppColors.onSurface),
|
||||
),
|
||||
content: const Text(
|
||||
"Voulez-vous vraiment quitter l'application ?",
|
||||
style: TextStyle(color: Colors.white70),
|
||||
style: TextStyle(color: AppColors.onSurface70),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
@@ -145,14 +146,14 @@ class _MobileLiveTVTabState extends ConsumerState<MobileLiveTVTab>
|
||||
autofocus: true,
|
||||
child: const Text(
|
||||
'Annuler',
|
||||
style: TextStyle(color: Colors.blueAccent),
|
||||
style: TextStyle(color: AppColors.primary),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
child: const Text(
|
||||
'Quitter',
|
||||
style: TextStyle(color: Colors.redAccent),
|
||||
style: TextStyle(color: AppColors.error),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -171,7 +172,7 @@ class _MobileLiveTVTabState extends ConsumerState<MobileLiveTVTab>
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
'Erreur: $e',
|
||||
style: const TextStyle(color: Colors.red),
|
||||
style: const TextStyle(color: AppColors.error),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
@@ -235,7 +236,7 @@ class _MobileLiveTVTabState extends ConsumerState<MobileLiveTVTab>
|
||||
// Search Bar
|
||||
TVFocusable(
|
||||
scale: 1.0,
|
||||
focusColor: Colors.white,
|
||||
focusColor: AppColors.onSurface,
|
||||
onPressed: () {
|
||||
setState(() => _isSearchEditing = true);
|
||||
WidgetsBinding.instance
|
||||
@@ -263,7 +264,7 @@ class _MobileLiveTVTabState extends ConsumerState<MobileLiveTVTab>
|
||||
child: ExcludeFocus(
|
||||
excluding: !_isSearchEditing,
|
||||
child: TextField(
|
||||
cursorColor: Colors.white,
|
||||
cursorColor: AppColors.onSurface,
|
||||
controller: _searchController,
|
||||
focusNode: _searchFocusNode,
|
||||
readOnly: !_isSearchEditing,
|
||||
@@ -357,7 +358,7 @@ class _MobileLiveTVTabState extends ConsumerState<MobileLiveTVTab>
|
||||
? Icons.favorite
|
||||
: Icons.favorite_border,
|
||||
color: _showFavoritesOnly
|
||||
? const Color(0xFFFF453A)
|
||||
? AppColors.live
|
||||
: AppDecorations.textSecondary(
|
||||
context),
|
||||
),
|
||||
@@ -535,7 +536,7 @@ class _ChannelListView extends ConsumerWidget {
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Aucune catégorie sélectionnée',
|
||||
style: TextStyle(color: Colors.white70),
|
||||
style: TextStyle(color: AppColors.onSurface70),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -557,7 +558,7 @@ class _ChannelListView extends ConsumerWidget {
|
||||
showFavoritesOnly
|
||||
? 'Sélectionnez une catégorie pour voir vos favoris'
|
||||
: 'Sélectionnez une catégorie pour rechercher',
|
||||
style: const TextStyle(color: Colors.white70),
|
||||
style: const TextStyle(color: AppColors.onSurface70),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
@@ -575,7 +576,7 @@ class _ChannelListView extends ConsumerWidget {
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
'Erreur: $e',
|
||||
style: const TextStyle(color: Colors.red),
|
||||
style: const TextStyle(color: AppColors.error),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
@@ -600,7 +601,7 @@ class _ChannelListView extends ConsumerWidget {
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Aucune chaîne trouvée',
|
||||
style: TextStyle(color: Colors.white70),
|
||||
style: TextStyle(color: AppColors.onSurface70),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -754,12 +755,12 @@ class _MobileChannelCardState extends ConsumerState<_MobileChannelCard> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
color: AppColors.error,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.favorite,
|
||||
color: Colors.white,
|
||||
color: AppColors.onSurface,
|
||||
size: 10,
|
||||
),
|
||||
),
|
||||
@@ -779,7 +780,7 @@ class _MobileChannelCardState extends ConsumerState<_MobileChannelCard> {
|
||||
Text(
|
||||
widget.channel.name,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
color: AppColors.onSurface,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10,
|
||||
),
|
||||
@@ -792,7 +793,7 @@ class _MobileChannelCardState extends ConsumerState<_MobileChannelCard> {
|
||||
Text(
|
||||
_epgTitle!,
|
||||
style: const TextStyle(
|
||||
color: Colors.yellow,
|
||||
color: AppColors.ratingGold,
|
||||
fontSize: 8,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:xtremobile/mobile/providers/mobile_settings_providers.dart';
|
||||
import 'package:xtremobile/mobile/providers/mobile_xtream_providers.dart';
|
||||
import 'package:xtremobile/core/models/iptv_models.dart' as model;
|
||||
import 'package:xtremobile/features/iptv/screens/native_player_screen.dart';
|
||||
import 'package:xtremobile/core/theme/app_colors.dart';
|
||||
|
||||
class MobileMoviesTab extends ConsumerStatefulWidget {
|
||||
final PlaylistConfig playlist;
|
||||
@@ -285,14 +286,14 @@ class _MobileMoviesTabState extends ConsumerState<MobileMoviesTab>
|
||||
final shouldExit = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
backgroundColor: Colors.grey[900],
|
||||
backgroundColor: AppColors.surfaceContainerLowest,
|
||||
title: const Text(
|
||||
"Quitter l'application",
|
||||
style: TextStyle(color: Colors.white),
|
||||
style: TextStyle(color: AppColors.onSurface),
|
||||
),
|
||||
content: const Text(
|
||||
"Voulez-vous vraiment quitter l'application ?",
|
||||
style: TextStyle(color: Colors.white70),
|
||||
style: TextStyle(color: AppColors.onSurface70),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
@@ -300,14 +301,14 @@ class _MobileMoviesTabState extends ConsumerState<MobileMoviesTab>
|
||||
autofocus: true,
|
||||
child: const Text(
|
||||
'Annuler',
|
||||
style: TextStyle(color: Colors.blueAccent),
|
||||
style: TextStyle(color: AppColors.primary),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
child: const Text(
|
||||
'Quitter',
|
||||
style: TextStyle(color: Colors.redAccent),
|
||||
style: TextStyle(color: AppColors.error),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -346,7 +347,7 @@ class _MobileMoviesTabState extends ConsumerState<MobileMoviesTab>
|
||||
// Search Bar
|
||||
TVFocusable(
|
||||
scale: 1.0,
|
||||
focusColor: Colors.white,
|
||||
focusColor: AppColors.onSurface,
|
||||
onPressed: () {
|
||||
setState(() => _isSearchEditing = true);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -367,7 +368,7 @@ class _MobileMoviesTabState extends ConsumerState<MobileMoviesTab>
|
||||
child: ExcludeFocus(
|
||||
excluding: !_isSearchEditing,
|
||||
child: TextField(
|
||||
cursorColor: Colors.white,
|
||||
cursorColor: AppColors.onSurface,
|
||||
controller: _searchController,
|
||||
focusNode: _searchFocusNode,
|
||||
readOnly: !_isSearchEditing,
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:xtremobile/mobile/providers/mobile_settings_providers.dart';
|
||||
import 'package:xtremobile/mobile/providers/mobile_xtream_providers.dart';
|
||||
import 'package:xtremobile/core/models/iptv_models.dart' as model;
|
||||
import 'package:xtremobile/features/iptv/screens/mobile_series_detail_screen.dart';
|
||||
import 'package:xtremobile/core/theme/app_colors.dart';
|
||||
|
||||
class MobileSeriesTab extends ConsumerStatefulWidget {
|
||||
final PlaylistConfig playlist;
|
||||
@@ -269,18 +270,18 @@ class _MobileSeriesTabState extends ConsumerState<MobileSeriesTab>
|
||||
final shouldExit = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
backgroundColor: Colors.grey[900],
|
||||
title: const Text("Quitter l'application", style: TextStyle(color: Colors.white)),
|
||||
content: const Text("Voulez-vous vraiment quitter l'application ?", style: TextStyle(color: Colors.white70)),
|
||||
backgroundColor: AppColors.surfaceContainerLowest,
|
||||
title: const Text("Quitter l'application", style: TextStyle(color: AppColors.onSurface)),
|
||||
content: const Text("Voulez-vous vraiment quitter l'application ?", style: TextStyle(color: AppColors.onSurface70)),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
autofocus: true,
|
||||
child: const Text('Annuler', style: TextStyle(color: Colors.blueAccent)),
|
||||
child: const Text('Annuler', style: TextStyle(color: AppColors.primary)),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
child: const Text('Quitter', style: TextStyle(color: Colors.redAccent)),
|
||||
child: const Text('Quitter', style: TextStyle(color: AppColors.error)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -316,7 +317,7 @@ class _MobileSeriesTabState extends ConsumerState<MobileSeriesTab>
|
||||
// Search Bar
|
||||
TVFocusable(
|
||||
scale: 1.0,
|
||||
focusColor: Colors.white,
|
||||
focusColor: AppColors.onSurface,
|
||||
onPressed: () {
|
||||
setState(() => _isSearchEditing = true);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -337,7 +338,7 @@ class _MobileSeriesTabState extends ConsumerState<MobileSeriesTab>
|
||||
child: ExcludeFocus(
|
||||
excluding: !_isSearchEditing,
|
||||
child: TextField(
|
||||
cursorColor: Colors.white,
|
||||
cursorColor: AppColors.onSurface,
|
||||
controller: _searchController,
|
||||
focusNode: _searchFocusNode,
|
||||
readOnly: !_isSearchEditing,
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:xtremobile/core/theme/app_decorations.dart';
|
||||
import 'package:xtremobile/core/theme/app_theme.dart';
|
||||
import 'package:xtremobile/core/providers/theme_provider.dart';
|
||||
import 'package:xtremobile/features/iptv/screens/mobile_playlist_selection_screen.dart';
|
||||
import 'package:xtremobile/core/theme/app_colors.dart';
|
||||
|
||||
/// Simplified mobile settings tab - optimized for TV remote control
|
||||
class MobileSettingsTab extends ConsumerStatefulWidget {
|
||||
@@ -105,7 +106,7 @@ class _MobileSettingsTabState extends ConsumerState<MobileSettingsTab> {
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Version 1.5.1',
|
||||
'Version 1.6.1',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 13,
|
||||
color: AppDecorations.textSecondary(context),
|
||||
@@ -327,7 +328,7 @@ class _MobileSettingsTabState extends ConsumerState<MobileSettingsTab> {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Cache actualisé ! Relancez l\'app pour recharger.'),
|
||||
backgroundColor: Colors.green,
|
||||
backgroundColor: AppColors.success,
|
||||
duration: Duration(seconds: 3),
|
||||
),
|
||||
);
|
||||
@@ -335,7 +336,7 @@ class _MobileSettingsTabState extends ConsumerState<MobileSettingsTab> {
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Erreur: $e'), backgroundColor: Colors.red),
|
||||
SnackBar(content: Text('Erreur: $e'), backgroundColor: AppColors.error),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
@@ -415,7 +416,7 @@ class _MobileSettingsTabState extends ConsumerState<MobileSettingsTab> {
|
||||
icon,
|
||||
size: 16,
|
||||
color: selected
|
||||
? Colors.white
|
||||
? AppColors.onSurface
|
||||
: AppDecorations.textSecondary(context),
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
@@ -427,7 +428,7 @@ class _MobileSettingsTabState extends ConsumerState<MobileSettingsTab> {
|
||||
? FontWeight.w700
|
||||
: FontWeight.w500,
|
||||
color: selected
|
||||
? Colors.white
|
||||
? AppColors.onSurface
|
||||
: AppDecorations.textSecondary(context),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user