import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/mqtt_provider.dart'; class WebcamView extends StatefulWidget { const WebcamView({super.key}); @override State createState() => _WebcamViewState(); } class _WebcamViewState extends State { Timer? _refreshTimer; @override void initState() { super.initState(); _startTimer(); } void _startTimer() { _refreshTimer = Timer.periodic(const Duration(seconds: 2), (timer) { if (mounted) { Provider.of(context, listen: false).requestWebcamFrame(); } }); } @override void dispose() { _refreshTimer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Consumer( builder: (context, provider, child) { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 8, offset: const Offset(0, 4), ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(16), child: provider.webcamImage != null && provider.webcamImage!.isNotEmpty ? Image.memory( base64Decode(provider.webcamImage!), fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return _buildPlaceholder(context, 'Error loading image'); }, ) : _buildPlaceholder(context, 'Menunggu gambar...'), ), ); }, ); } Widget _buildPlaceholder(BuildContext context, String message) { return Container( height: 300, width: double.infinity, color: Colors.grey.shade200, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.videocam_off, size: 64, color: Colors.grey.shade400, ), const SizedBox(height: 16), Text( message, style: TextStyle( color: Colors.grey.shade600, fontSize: 14, ), ), const SizedBox(height: 8), Consumer( builder: (context, provider, child) { return Text( 'Deteksi kehadiran: ${provider.detectionCount}', style: TextStyle( color: Colors.grey.shade600, fontSize: 12, ), ); }, ), ], ), ); } }