Studio lot 6 : mention « image générée par IA » chez le visiteur
Une reconstitution n'est pas une photographie d'archive, et rien dans l'image ne le dit : la mention est due au visiteur. Elle est posée au-dessus des trois branches de rendu (réseau, cache hors ligne, URL externe) plutôt qu'à chacune, pour qu'aucun point d'affichage ne puisse l'oublier. Traduite dans les onze langues publiées : l'app visiteur n'a pas d'infrastructure de traduction pour ses propres libellés. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9e213968f5
commit
bac086f1e1
49
lib/Components/ai_generated_badge.dart
Normal file
49
lib/Components/ai_generated_badge.dart
Normal file
@ -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),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:tablet_app/Components/ai_generated_badge.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
@ -26,7 +27,27 @@ class CachedCustomResource extends StatelessWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@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) {
|
Widget build(BuildContext context) {
|
||||||
|
final resource = _resource(context);
|
||||||
|
if (!AiGeneratedBadge.isGenerated(resourceDTO)) return resource;
|
||||||
|
|
||||||
|
final tabletAppContext =
|
||||||
|
Provider.of<AppContext>(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<AppContext>(context);
|
final appContext = Provider.of<AppContext>(context);
|
||||||
TabletAppContext tabletAppContext = appContext.getContext();
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user