import 'package:flutter/material.dart'; import 'package:manager_api_new/api.dart'; import 'package:manager_app/Components/resource_input_container.dart'; import 'package:manager_app/constants.dart'; import 'package:manager_app/l10n/app_localizations.dart'; /// Le fond immersif d'un lieu, tel que le gestionnaire le choisit. /// /// **Le type n'est pas demandé, il est déduit** de la ressource choisie : une /// `Image360` donne un panorama, une `Video360` une vidéo, un `Model3D` une scène. /// Demander « panorama ou vidéo ? » après avoir fait choisir une vidéo, c'est poser /// une question dont la réponse est déjà sur l'écran — et ouvrir la possibilité d'y /// répondre faux, ce qui donnerait un fond noir sans explication. /// /// Le repli est un champ séparé, et il est proposé à côté plutôt que caché : trois /// canaux sur quatre ne rendent pas un panorama, et c'est lui qu'ils afficheront. class ImmersiveBackgroundPicker extends StatefulWidget { const ImmersiveBackgroundPicker({ super.key, required this.value, required this.onChanged, required this.title, required this.hint, }); final ImmersiveBackgroundDTO? value; final ValueChanged onChanged; final String title; final String hint; @override State createState() => _ImmersiveBackgroundPickerState(); } class _ImmersiveBackgroundPickerState extends State { static const _immersiveTypes = [ ResourceType.Image360, ResourceType.Video360, ResourceType.Model3D, ]; static ImmersiveBackgroundKind _kindOf(ResourceType? type) { if (type == ResourceType.Video360) return ImmersiveBackgroundKind.Video360; if (type == ResourceType.Model3D) return ImmersiveBackgroundKind.Scene3D; return ImmersiveBackgroundKind.Pano; } String _kindLabel(AppLocalizations l, ImmersiveBackgroundKind? kind) { if (kind == ImmersiveBackgroundKind.Video360) return l.backgroundKindVideo360; if (kind == ImmersiveBackgroundKind.Scene3D) return l.backgroundKindScene3D; return l.backgroundKindPano; } @override Widget build(BuildContext context) { final l = AppLocalizations.of(context)!; final value = widget.value; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(widget.title, style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 13)), const SizedBox(height: kSpace2), Text(widget.hint, style: kTextHint), const SizedBox(height: kSpace4), ResourceInputContainer( label: l.backgroundResourceLabel, initialValue: value?.resourceId, inResourceTypes: _immersiveTypes, onChanged: (ResourceDTO resource) { final updated = ImmersiveBackgroundDTO( resourceId: resource.id, kind: _kindOf(resource.type), fallbackResourceId: value?.fallbackResourceId, ); setState(() {}); widget.onChanged(updated); }, ), if (value?.resourceId != null) ...[ const SizedBox(height: kSpace2), Row( children: [ const Icon(Icons.info_outline, size: 14, color: kInk3), const SizedBox(width: kSpace2), Expanded( child: Text(_kindLabel(l, value!.kind), style: kTextHint), ), ], ), const SizedBox(height: kSpace5), ResourceInputContainer( label: l.backgroundFallbackLabel, initialValue: value.fallbackResourceId, inResourceTypes: const [ResourceType.Image], onChanged: (ResourceDTO resource) { final updated = ImmersiveBackgroundDTO( resourceId: value.resourceId, kind: value.kind, fallbackResourceId: resource.id, ); setState(() {}); widget.onChanged(updated); }, ), const SizedBox(height: kSpace2), Text(l.backgroundFallbackHint, style: kTextHint), const SizedBox(height: kSpace4), Align( alignment: Alignment.centerLeft, child: TextButton.icon( onPressed: () { setState(() {}); widget.onChanged(null); }, icon: const Icon(Icons.close, size: 16), label: Text(l.backgroundRemove), ), ), ], ], ); } }