diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1e65043..b8776de 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,11 +2,18 @@ + + + + + + - - - - + android:src="@drawable/ic_launcher_foreground" /> + diff --git a/android/app/src/main/res/drawable-xhdpi/banner.png b/android/app/src/main/res/drawable-xhdpi/banner.png new file mode 100644 index 0000000..ec4ec97 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/banner.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png index 0826363..24bdb71 100644 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/banner.png b/android/app/src/main/res/drawable-xxhdpi/banner.png new file mode 100644 index 0000000..df3084b Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/banner.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png index 4daca67..7b0b9af 100644 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/banner.png b/android/app/src/main/res/drawable-xxxhdpi/banner.png new file mode 100644 index 0000000..d38409a Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/banner.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png index 9bf9f2d..6aeefb0 100644 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml index 304732f..dafdfc3 100644 --- a/android/app/src/main/res/drawable/launch_background.xml +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -1,12 +1,10 @@ - + - - - - + android:src="@drawable/ic_launcher_foreground" /> + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index c79c58a..e867917 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,9 +1,8 @@ + - - - + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..e867917 --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 4655f8a..99af34b 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..3bdb109 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 0f8bc61..4c77075 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..0789825 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 73ef1fa..3d6ef21 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..b03ebf0 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 912e1f3..2ec82e1 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..96e7b2a Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index f949b40..3d153c0 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..be21e68 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 19d9c82..590c547 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -1,4 +1,5 @@ - #1a1a2e - \ No newline at end of file + + #1B1B1F + diff --git a/assets/branding/icon_foreground.svg b/assets/branding/icon_foreground.svg new file mode 100644 index 0000000..324ba5d --- /dev/null +++ b/assets/branding/icon_foreground.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/branding/icon_round.svg b/assets/branding/icon_round.svg new file mode 100644 index 0000000..164febd --- /dev/null +++ b/assets/branding/icon_round.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/branding/icon_rounded.svg b/assets/branding/icon_rounded.svg new file mode 100644 index 0000000..32c17df --- /dev/null +++ b/assets/branding/icon_rounded.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/branding/icon_square.svg b/assets/branding/icon_square.svg new file mode 100644 index 0000000..c7e1f46 --- /dev/null +++ b/assets/branding/icon_square.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/branding/tv_banner.svg b/assets/branding/tv_banner.svg new file mode 100644 index 0000000..b58b78d --- /dev/null +++ b/assets/branding/tv_banner.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XtremFlow + IPTV PLAYER + diff --git a/assets/branding/tv_banner_1280x720.png b/assets/branding/tv_banner_1280x720.png new file mode 100644 index 0000000..d8ae2a5 Binary files /dev/null and b/assets/branding/tv_banner_1280x720.png differ diff --git a/assets/images/app_icon_ios.png b/assets/images/app_icon_ios.png new file mode 100644 index 0000000..7c2bd48 Binary files /dev/null and b/assets/images/app_icon_ios.png differ diff --git a/assets/images/logo_xtremflow.png b/assets/images/logo_xtremflow.png index 62d53cc..836a4ee 100644 Binary files a/assets/images/logo_xtremflow.png and b/assets/images/logo_xtremflow.png differ diff --git a/flutter_launcher_icons-ios.yaml b/flutter_launcher_icons-ios.yaml index cb8c11c..87aebb9 100644 --- a/flutter_launcher_icons-ios.yaml +++ b/flutter_launcher_icons-ios.yaml @@ -5,6 +5,6 @@ flutter_launcher_icons: ios: true android: false - image_path: "assets/images/logo_xtremflow.png" + image_path: "assets/images/app_icon_ios.png" # L'App Store et iOS refusent une icône avec canal alpha. remove_alpha_ios: true diff --git a/lib/features/iptv/widgets/mobile_settings_tab.dart b/lib/features/iptv/widgets/mobile_settings_tab.dart index 8d36abe..fec6aac 100644 --- a/lib/features/iptv/widgets/mobile_settings_tab.dart +++ b/lib/features/iptv/widgets/mobile_settings_tab.dart @@ -85,7 +85,7 @@ class _MobileSettingsTabState extends ConsumerState { height: 48, // No decoration for free-floating logo child: Image.asset( - 'assets/images/logo_xtremobile.png', + 'assets/images/logo_xtremflow.png', fit: BoxFit.contain, errorBuilder: (_, __, ___) => Icon( Icons.play_circle_filled, diff --git a/pubspec.yaml b/pubspec.yaml index 3b9bfb6..7dca8a5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -79,12 +79,12 @@ dev_dependencies: riverpod_generator: ^2.4.0 hive_generator: ^2.0.1 +# Les icônes Android (mipmap, adaptative, bannière TV) sont générées par +# scripts/generate_icons.py et versionnées : ne pas les écraser ici. flutter_launcher_icons: - android: true + android: false ios: true - image_path: "assets/images/logo_xtremflow.png" - adaptive_icon_background: "#1a1a2e" - adaptive_icon_foreground: "assets/images/logo_xtremflow.png" + image_path: "assets/images/app_icon_ios.png" # iOS refuse une icône comportant un canal alpha. remove_alpha_ios: true diff --git a/scripts/generate_icons.py b/scripts/generate_icons.py new file mode 100644 index 0000000..407d2da --- /dev/null +++ b/scripts/generate_icons.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python3 +"""Génère toutes les icônes XtremFlow à partir d'un seul dessin vectoriel. + +Palette alignée sur lib/core/theme/app_colors.dart (graphite + bleu Apple). + +Sorties : + assets/branding/*.svg sources vectorielles + assets/images/logo_xtremflow.png logo in-app (fond transparent) + assets/images/app_icon_ios.png icône iOS (carré plein, sans alpha) + android/.../mipmap-*/ic_launcher.png icône legacy (tuile arrondie) + android/.../mipmap-*/ic_launcher_round.png icône legacy ronde + android/.../drawable-*/ic_launcher_foreground.png calque adaptatif + android/.../drawable-xhdpi/banner.png bannière Android TV / Fire TV + +Usage : pip install cairosvg pillow && python3 scripts/generate_icons.py +La bannière utilise la police Inter (Bold) si elle est installée. +""" + +import io +import os + +import cairosvg +from PIL import Image + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +RES = os.path.join(ROOT, "android", "app", "src", "main", "res") + +# Couleurs du thème (app_colors.dart) +BG_TOP = "#2C2C33" # surfaceContainerLow +BG_BOTTOM = "#1B1B1F" # baseLevel0 +BLUE = "#0A84FF" # primaryContainer +BLUE_LIGHT = "#8AB9FF" # primary +CYAN = "#7DD3F2" # tertiary + +DEFS = f""" + + + + + + + + + + + + + + + + + + + + + + + """ + + +def mark(cx, cy, size): + """Le symbole : un bouton play fluide précédé de traînées de vitesse. + + Dessiné dans une boîte de 100x100 centrée sur (cx, cy), mise à l'échelle + à `size` pixels. + """ + s = size / 100.0 + tx, ty = cx - 50 * s, cy - 50 * s + return f""" + + + + + + + + + + """ + + +def svg(w, h, body): + return ( + f'{DEFS}{body}\n\n' + ) + + +def tile(size, radius_ratio, mark_ratio=0.64): + """Tuile graphite (arrondie ou pleine) avec le symbole centré.""" + r = size * radius_ratio + body = f""" + + + + {mark(size / 2, size / 2, size * mark_ratio)}""" + return svg(size, size, body) + + +def round_tile(size): + body = f""" + + + {mark(size / 2, size / 2, size * 0.62)}""" + return svg(size, size, body) + + +def adaptive_foreground(size): + # 108dp de canevas, zone sûre de 66dp : le symbole occupe ~58% du canevas, + # soit l'intérieur du cercle sûr quelle que soit la forme du masque. + return svg(size, size, mark(size / 2, size / 2, size * 0.58)) + + +def banner(w=320, h=180): + """Bannière TV (Android TV / Fire TV) : 320x180 px en xhdpi.""" + body = f""" + + + {mark(w * 0.25, h / 2, h * 0.56)} + XtremFlow + IPTV PLAYER""" + return svg(w, h, body) + + +def render(svg_text, out_path, size=None, flatten=None): + png = cairosvg.svg2png( + bytestring=svg_text.encode(), + output_width=size[0] if size else None, + output_height=size[1] if size else None, + ) + img = Image.open(io.BytesIO(png)).convert("RGBA") + if flatten: + bg = Image.new("RGBA", img.size, flatten) + bg.alpha_composite(img) + img = bg.convert("RGB") + os.makedirs(os.path.dirname(out_path), exist_ok=True) + img.save(out_path, optimize=True) + print(" ", os.path.relpath(out_path, ROOT), img.size) + + +def main(): + brand = os.path.join(ROOT, "assets", "branding") + os.makedirs(brand, exist_ok=True) + sources = { + "icon_rounded.svg": tile(1024, 0.225), + "icon_square.svg": tile(1024, 0), + "icon_round.svg": round_tile(1024), + "icon_foreground.svg": adaptive_foreground(1024), + "tv_banner.svg": banner(), + } + for name, text in sources.items(): + with open(os.path.join(brand, name), "w") as f: + f.write(text) + + print("Assets Flutter :") + render(sources["icon_rounded.svg"], os.path.join(ROOT, "assets/images/logo_xtremflow.png"), (512, 512)) + # iOS applique son propre masque et refuse l'alpha : carré plein. + render(sources["icon_square.svg"], os.path.join(ROOT, "assets/images/app_icon_ios.png"), (1024, 1024), flatten=BG_BOTTOM) + + print("Android :") + densities = {"mdpi": 1, "hdpi": 1.5, "xhdpi": 2, "xxhdpi": 3, "xxxhdpi": 4} + for d, k in densities.items(): + legacy = round(48 * k) + fg = round(108 * k) + render(sources["icon_rounded.svg"], f"{RES}/mipmap-{d}/ic_launcher.png", (legacy, legacy)) + render(sources["icon_round.svg"], f"{RES}/mipmap-{d}/ic_launcher_round.png", (legacy, legacy)) + render(sources["icon_foreground.svg"], f"{RES}/drawable-{d}/ic_launcher_foreground.png", (fg, fg)) + # Bannière TV : 160x90dp -> 320x180 en xhdpi (taille de référence Google/Amazon). + render(sources["tv_banner.svg"], f"{RES}/drawable-xhdpi/banner.png", (320, 180), flatten=BG_BOTTOM) + render(sources["tv_banner.svg"], f"{RES}/drawable-xxhdpi/banner.png", (480, 270), flatten=BG_BOTTOM) + render(sources["tv_banner.svg"], f"{RES}/drawable-xxxhdpi/banner.png", (640, 360), flatten=BG_BOTTOM) + # Aperçu grand format pour les stores / README. + render(sources["tv_banner.svg"], os.path.join(brand, "tv_banner_1280x720.png"), (1280, 720), flatten=BG_BOTTOM) + + +if __name__ == "__main__": + main()