import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:manager_api_new/api.dart'; import 'package:manager_app/Screens/Applications/app_configuration_link_screen.dart'; import 'package:manager_app/Screens/Vr_devices/vr_devices_tab.dart'; import 'package:manager_app/Components/immersive_background_picker.dart'; import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/app_context.dart'; import 'package:manager_app/constants.dart'; import 'package:manager_app/l10n/app_localizations.dart'; /// Le canal VR a les deux faces des autres canaux — ce qu'on diffuse et sur quoi /// on le diffuse — mais contrairement au kiosk la flotte porte des informations /// propres au casque (batterie, version, dernier vu) qui n'ont pas leur place /// dans l'écran de configuration. class VrScreen extends StatefulWidget { final ApplicationInstanceDTO applicationInstanceDTO; const VrScreen({super.key, required this.applicationInstanceDTO}); @override State createState() => _VrScreenState(); } class _VrScreenState extends State { int _tab = 0; @override Widget build(BuildContext context) { final l = AppLocalizations.of(context)!; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _tabs(l), const SizedBox(height: kSpace7), Expanded( child: _tab == 0 ? Column( children: [ Expanded( child: AppConfigurationLinkScreen( applicationInstanceDTO: widget.applicationInstanceDTO, ), ), _backgroundCard(l), ], ) : VrDevicesTab( applicationInstanceDTO: widget.applicationInstanceDTO, ), ), ], ); } /// Le fond du menu d'accueil du casque. Il vit ici et pas dans l'écran de /// configuration partagé : celui-ci sert aussi au mobile, au web et au kiosk, qui /// n'ont pas de menu à décorer. /// /// Enregistré à chaque changement, comme l'image principale juste au-dessus — c'est /// la convention de cet écran, et deux comportements d'enregistrement sur la même /// page se paient en contenus perdus. Widget _backgroundCard(AppLocalizations l) { final appContext = Provider.of(context, listen: false); return Container( width: double.infinity, padding: const EdgeInsets.all(kSpace5), decoration: BoxDecoration( color: kSurface, border: Border(top: BorderSide(color: kLine)), ), child: ImmersiveBackgroundPicker( value: widget.applicationInstanceDTO.immersiveBackground, title: l.backgroundTitle, hint: l.backgroundHintMenu, onChanged: (value) async { setState(() => widget.applicationInstanceDTO.immersiveBackground = value); final updated = await updateApplicationInstance( appContext, widget.applicationInstanceDTO); if (updated != null && mounted) { showNotification(kSuccess, kWhite, l.appUpdatedSuccess, context, null); } }, ), ); } Widget _tabs(AppLocalizations l) { return Container( decoration: BoxDecoration(border: Border(bottom: BorderSide(color: kLine))), child: Row( children: [ _tabButton(l.vrTabConfig, 0), _tabButton(l.vrTabHeadsets, 1), ], ), ); } Widget _tabButton(String label, int index) { final selected = _tab == index; return InkWell( onTap: () => setState(() => _tab = index), child: Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 9), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: selected ? kBrand : Colors.transparent, width: 2, ), ), ), child: Text( label, style: TextStyle( fontSize: 14, color: selected ? kInk : kInk3, fontWeight: selected ? FontWeight.w600 : FontWeight.w400, ), ), ), ); } }