diff --git a/lib/Components/ai_generated_badge.dart b/lib/Components/ai_generated_badge.dart new file mode 100644 index 0000000..120d849 --- /dev/null +++ b/lib/Components/ai_generated_badge.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:manager_api_new/api.dart'; + +/// Mention « image générée par IA » posée sur une image produite par le Studio (lot 6). +/// +/// Elle est due au visiteur, pas au client : une reconstitution n'est pas une photographie +/// d'archive, et rien dans l'image ne le dit. Le texte suit la langue de visite — l'app +/// visiteur n'a pas d'infrastructure de traduction pour ses propres libellés, les dix +/// langues publiées sont donc portées ici. +class AiGeneratedBadge extends StatelessWidget { + const AiGeneratedBadge({Key? key, required this.language}) : super(key: key); + + final String? language; + + static const _labels = { + 'FR': 'Image générée par IA', + 'NL': 'Beeld gegenereerd door AI', + 'EN': 'AI-generated image', + 'DE': 'KI-generiertes Bild', + 'ES': 'Imagen generada por IA', + 'IT': 'Immagine generata dall’IA', + 'PL': 'Obraz wygenerowany przez SI', + 'CN': '人工智能生成的图像', + 'AR': 'صورة من إنتاج الذكاء الاصطناعي', + 'UK': 'Зображення, створене ШІ', + 'LB': 'Bild generéiert vun der KI', + }; + + /// Une image générée doit porter la mention ; une image téléversée, jamais. + static bool isGenerated(ResourceDTO? resource) => + resource?.origin == ResourceOrigin.Generated; + + @override + Widget build(BuildContext context) { + final label = _labels[(language ?? 'FR').toUpperCase()] ?? _labels['FR']!; + + return Container( + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3), + decoration: BoxDecoration( + color: Colors.black.withValues(alpha: 0.72), + borderRadius: BorderRadius.circular(4), + ), + child: Text( + label, + style: const TextStyle(color: Colors.white, fontSize: 9, letterSpacing: 0.2), + ), + ); + } +} diff --git a/lib/Components/cached_custom_resource.dart b/lib/Components/cached_custom_resource.dart index e4813f5..217c4f4 100644 --- a/lib/Components/cached_custom_resource.dart +++ b/lib/Components/cached_custom_resource.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'dart:typed_data'; +import 'package:tablet_app/Components/ai_generated_badge.dart'; import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:manager_api_new/api.dart'; @@ -26,7 +27,27 @@ class CachedCustomResource extends StatelessWidget { }); @override + /// L'image porte sa mention quelle que soit la branche de rendu prise en dessous. + /// Même geste que dans l'app visiteur : la poser ici évite d'y penser à chaque écran. Widget build(BuildContext context) { + final resource = _resource(context); + if (!AiGeneratedBadge.isGenerated(resourceDTO)) return resource; + + final tabletAppContext = + Provider.of(context, listen: false).getContext() as TabletAppContext; + return Stack( + children: [ + Positioned.fill(child: resource), + Positioned( + left: 6, + bottom: 6, + child: AiGeneratedBadge(language: tabletAppContext.language), + ), + ], + ); + } + + Widget _resource(BuildContext context) { final appContext = Provider.of(context); TabletAppContext tabletAppContext = appContext.getContext(); Size size = MediaQuery.of(context).size;