Ce commit boucle le travail en cours sur la branche (assistant lunettes Meta, passage du lecteur audio flottant a un onglet, ajustements scanner / liste de configurations / telechargement) et y ajoute le badge de version. Le badge, en bas de la feuille Parametres, affiche « flavor . version . commit ». Un APK pose sur une tablette du terrain n'etait rattachable a aucun commit precis : la version du pubspec ne bougeait pas d'un build a l'autre et rien n'indiquait le flavor reellement installe. kGitSha suit le meme schema que kApiBaseUrl, injecte par --dart-define, et kFlavor expose le flavor deja calcule. package_info_plus etait deja une dependance transitive ; il devient direct, puisqu'il est desormais importe. /!\ Un --dart-define modifie n'est PAS pris en compte sans `flutter clean` sur ce projet : verifie a la sentinelle, le SHA restait absent de libapp.so tant que le cache Dart n'etait pas vide. Un build de release destine au terrain doit donc toujours passer par un clean, sinon le badge affiche le SHA du build precedent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
192 lines
7.4 KiB
Dart
192 lines
7.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart' show appFlavor;
|
|
|
|
// Third-party integrations — injectées via --dart-define, jamais committées.
|
|
//
|
|
// ⚠️ GEMINI_API_KEY absente = repli sur la voix système du téléphone, et c'est
|
|
// **le comportement par défaut de tous les builds**. Utile pour tester sans dépenser de
|
|
// jetons, trompeur si on l'ignore : jusqu'au 2026-08-13 le repli était silencieux et
|
|
// personne ne savait que les APK ne parlaient pas avec la voix du produit. Il se signale
|
|
// désormais dans les logs (`[VoiceController] GEMINI_API_KEY absente…`).
|
|
//
|
|
// Pour entendre la vraie voix :
|
|
// flutter run --flavor dev --dart-define=GEMINI_API_KEY=xxxx
|
|
// flutter build apk --flavor mdlf --dart-define=GEMINI_API_KEY=xxxx --dart-define=INSTANCE_ID=... --dart-define=API_BASE_URL=... --dart-define=API_KEY=...
|
|
//
|
|
// Whisper STT (OpenAI ou serveur auto-hébergé compatible) — clé vide = STT du device.
|
|
const kWhisperApiKey = String.fromEnvironment('WHISPER_API_KEY', defaultValue: '');
|
|
const kWhisperEndpoint = String.fromEnvironment('WHISPER_ENDPOINT',
|
|
defaultValue: 'https://api.openai.com/v1/audio/transcriptions');
|
|
|
|
// Gemini TTS (2.5 Flash)
|
|
const kGeminiApiKey = String.fromEnvironment('GEMINI_API_KEY', defaultValue: '');
|
|
// ⚠️ Repli seulement. La voix réelle vient du CMS — `Instance.guideVoiceId`, réglée par le
|
|
// client dans manager-app (sélecteur Viva/Marco). Le défaut valait `Algieba`, une voix que
|
|
// personne n'a validée : il date d'avant le sélecteur, et rien ne lisait le choix du client.
|
|
// Sulafat = Viva (féminine), écoutée et validée le 2026-08-07 ; Umbriel = Marco (masculine).
|
|
const kGeminiTtsVoice = String.fromEnvironment('GEMINI_TTS_VOICE', defaultValue: 'Sulafat');
|
|
const kGeminiTtsPrompt = String.fromEnvironment('GEMINI_TTS_PROMPT',
|
|
defaultValue: 'Voix de guide de musée, ton chaleureux et bienveillant, rythme posé et clair.');
|
|
|
|
// ElevenLabs retiré du pipeline (trop cher). Fichier impl/elevenlabs_tts_engine.dart
|
|
// conservé comme référence mais non utilisé.
|
|
// Lunettes Ray-Ban Meta — DESACTIVE par defaut.
|
|
//
|
|
// Avec meta_wearables_dat 0.1.3 (SDK DAT 0.3.0), le SDK plantait le processus
|
|
// au demarrage sur certains telephones : SIGABRT dans
|
|
// com.facebook.wearable.airshield.security.PrivateKey.<clinit>,
|
|
// « __cxa_guard_acquire detected recursive initialization ». C'est une
|
|
// initialisation statique C++ cote natif (mwdat-core / airshield) : aucun
|
|
// try/catch Dart ne peut l'attraper, l'app meurt avant d'afficher quoi que
|
|
// ce soit. Constate le 2026-09-07 sur Xiaomi klimt / Android 16 / arm64.
|
|
//
|
|
// Migre vers flutter_meta_wearables_dat 0.9.1 (SDK DAT 0.9.0) : le correctif
|
|
// est plausible mais NON VERIFIE — a revalider sur le Xiaomi avant de
|
|
// retirer ce drapeau.
|
|
//
|
|
// Pour tester les lunettes : --dart-define=ENABLE_GLASSES=true
|
|
const kEnableGlasses = bool.fromEnvironment('ENABLE_GLASSES', defaultValue: false);
|
|
|
|
const kPicovoiceAccessKey = String.fromEnvironment('PICOVOICE_ACCESS_KEY', defaultValue: '');
|
|
|
|
// API configuration — injectées au build via --dart-define
|
|
// Ex: flutter build appbundle --flavor mdlf --dart-define=INSTANCE_ID=65ccc67265373befd15be511 --dart-define=API_BASE_URL=https://api.mymuseum.be --dart-define=API_KEY=xxxx
|
|
//
|
|
// Les replis suivent le flavor. Ils étaient constants et pointaient sur le PC de
|
|
// dev : un `flutter run --flavor fortsaintheribert` sans dart-define lançait une
|
|
// app cliente sur http://192.168.31.228:5000, et le boot restait bloqué le temps
|
|
// que le socket meure — écran de splash blanc pendant deux minutes.
|
|
const kApiBaseUrl = String.fromEnvironment('API_BASE_URL',
|
|
defaultValue:
|
|
_flavor == 'dev' ? 'http://192.168.31.228:5000' : 'https://api.mymuseum.be');
|
|
const kApiKey = String.fromEnvironment('API_KEY', defaultValue: '');
|
|
|
|
// Empreinte du commit, injectee au build :
|
|
// --dart-define=GIT_SHA=$(git rev-parse --short HEAD)
|
|
// Affichee avec le numero de version en bas de la feuille Parametres, pour
|
|
// relier un APK installe sur le terrain au commit exact qui l'a produit.
|
|
const kGitSha = String.fromEnvironment('GIT_SHA', defaultValue: 'dev');
|
|
const kInstanceId = String.fromEnvironment('INSTANCE_ID',
|
|
defaultValue: _flavor == 'mdlf'
|
|
? '65ccc67265373befd15be511'
|
|
: _flavor == 'fortsaintheribert'
|
|
? '633ee379d9405f32f166f047'
|
|
: '63514fd67ed8c735aaa4b8f2');
|
|
|
|
// Flavor lu depuis le --flavor gradle (appFlavor). Le --dart-define=FLAVOR reste
|
|
// accepté en repli pour les scripts de build existants.
|
|
const _flavor = appFlavor ?? String.fromEnvironment('FLAVOR', defaultValue: 'dev');
|
|
|
|
// Le meme flavor, lisible hors de ce fichier (badge de version des Parametres).
|
|
const kFlavor = _flavor;
|
|
|
|
// Colors — définies par flavor
|
|
// Pour modifier les couleurs d'un client : changer les valeurs hex ci-dessous
|
|
// puis rebuilder avec --dart-define=FLAVOR=nomduclient
|
|
// Couleurs identiques pour tous les clients actuels
|
|
const kBackgroundColor = Color(0xFFFFFFFF);
|
|
const kMainColor = Color(0xFF306bac);
|
|
const kSecondColor = Color(0xFF309cb0);
|
|
const kConfigurationColor = Color(0xFF2F4858);
|
|
|
|
/*const kArticleTitleSize = 25.0;
|
|
const kArticleDescriptionSize = 12.5;*/
|
|
const kArticleContentSize = 16.0;
|
|
const kArticleContentBiggerSize = 24.0;
|
|
|
|
const List<String> languages = [
|
|
"FR",
|
|
"NL",
|
|
"EN",
|
|
"DE",
|
|
"IT",
|
|
"ES",
|
|
"PL",
|
|
"CN",
|
|
"AR",
|
|
"UK"
|
|
]; // hmmmm depends on config..
|
|
|
|
const String defaultLanguage = "EN";
|
|
|
|
const kDefaultPadding = 20.0;
|
|
|
|
const kMainGrey = Color(0xFF424242);
|
|
const kSecondGrey = Color(0xFF555457);
|
|
//const kSecondRed = Color(0xFF622727);
|
|
const kTextRed = Color(0xFFba0505);
|
|
const kBackgroundGrey = Color(0xFFb5b7b9);
|
|
const kBackgroundSecondGrey = Color(0xFF5b5b63);
|
|
|
|
const kMainColor0 = Color(_flavor == 'mdlf'
|
|
? 0xFFe52122
|
|
: // rouge
|
|
_flavor == 'fortsaintheribert'
|
|
? 0xFF306bac
|
|
: // bleu
|
|
0xFF306bac // test (défaut)
|
|
);
|
|
const kMainColor1 = Color(_flavor == 'mdlf'
|
|
? 0xFFed7082
|
|
: // rouge clair
|
|
_flavor == 'fortsaintheribert'
|
|
? 0xFF308aae
|
|
: // bleu
|
|
0xFF308aae // test (défaut)
|
|
);
|
|
const kMainColor2 = Color(_flavor == 'mdlf'
|
|
? 0xFFed7082
|
|
: // rouge clair
|
|
_flavor == 'fortsaintheribert'
|
|
? 0xFF309cb0
|
|
: // bleu
|
|
0xFF309cb0 // test (défaut)
|
|
);
|
|
|
|
const kAppTitle = _flavor == 'mdlf'
|
|
? 'MDLF'
|
|
: _flavor == 'fortsaintheribert'
|
|
? 'Fort Saint-Héribert'
|
|
: 'MyMuseum Dev';
|
|
|
|
const kSplashLogoAsset = _flavor == 'mdlf'
|
|
? 'assets/splash/mdlf.png'
|
|
: _flavor == 'fortsaintheribert'
|
|
? 'assets/splash/fortsaintheribert.png'
|
|
: 'assets/splash/dev.png';
|
|
|
|
const kLoaderAsset = _flavor == 'mdlf'
|
|
? 'assets/loader/mdlf.png'
|
|
: _flavor == 'fortsaintheribert'
|
|
? 'assets/loader/fortsaintheribert.png'
|
|
: 'assets/loader/dev.png';
|
|
|
|
const kBackgroundLight = Color(0xfff3f3f3);
|
|
|
|
const kGreen = Color(0xFF15bd5b);
|
|
|
|
const kTitleSize = 40.0;
|
|
const kDescriptionSize = 25.0;
|
|
|
|
const kSectionTitleDetailSize = 50.0;
|
|
const kSectionDescriptionDetailSize = 35.0;
|
|
|
|
const kMenuTitleDetailSize = 25.0;
|
|
const kMenuDescriptionDetailSize = 18.0;
|
|
|
|
const kNoneInfoOrIncorrect = 35.0;
|
|
|
|
// our default Shadow
|
|
const kDefaultShadow = BoxShadow(
|
|
offset: Offset(0, 15),
|
|
blurRadius: 27,
|
|
color: kBackgroundGrey, // Black color with 12% opacity
|
|
);
|
|
|
|
/*
|
|
const kTextStyle = TextStyle(
|
|
fontSize: 23,
|
|
color: kPrimaryColor,
|
|
fontWeight: FontWeight.w600,
|
|
);*/
|