mymuseum-visitapp/lib/Components/GlassesStatusWidget.dart
2026-07-17 15:23:12 +02:00

87 lines
3.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:mymuseum_visitapp/Components/VoiceModeSheet.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart';
import 'package:mymuseum_visitapp/Services/meta_glasses_service.dart';
import 'package:mymuseum_visitapp/Services/voice_controller.dart';
import 'package:provider/provider.dart';
/// Icône circulaire positionnée en haut à droite de l'écran d'accueil.
///
/// Visible si :
/// - Les lunettes sont connectées (quel que soit le mode)
/// - OU un mode vocal est actif (voiceOnly ou glasses)
///
/// Tap → ouvre VoiceModeSheet.
class GlassesStatusWidget extends StatelessWidget {
final VisitAppContext visitAppContext;
const GlassesStatusWidget({super.key, required this.visitAppContext});
@override
Widget build(BuildContext context) {
return Consumer<VoiceController>(
builder: (context, controller, _) {
return ValueListenableBuilder<GlassesState>(
valueListenable: MetaGlassesService.instance.state,
builder: (context, glassesState, _) {
final isConnected = glassesState == GlassesState.connected ||
glassesState == GlassesState.streaming;
final modeActive = controller.mode != VoiceMode.none;
final featureAvailable = controller.isFeatureAvailable(visitAppContext);
if (!featureAvailable && !isConnected && !modeActive) return const SizedBox.shrink();
final Color iconColor = switch ((isConnected, controller.mode)) {
(true, VoiceMode.glasses) => Colors.greenAccent,
(_, VoiceMode.voiceOnly) => Colors.lightBlueAccent,
(true, _) => Colors.white70,
_ => Colors.white38,
};
return GestureDetector(
onTap: () => VoiceModeSheet.show(context, visitAppContext: visitAppContext),
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.3),
shape: BoxShape.circle,
),
child: Stack(
alignment: Alignment.center,
children: [
Icon(
controller.mode == VoiceMode.voiceOnly
? Icons.mic
: Icons.remove_red_eye_outlined,
color: iconColor,
size: 22,
),
// Point vert en bas à droite si mode actif
if (modeActive)
Positioned(
bottom: 8,
right: 8,
child: Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: controller.mode == VoiceMode.glasses
? Colors.greenAccent
: Colors.lightBlueAccent,
shape: BoxShape.circle,
border: Border.all(color: Colors.black54, width: 1),
),
),
),
],
),
),
);
},
);
},
);
}
}