import 'package:vibration/vibration.dart'; import 'package:pad_scanner/services/sound_service.dart'; /// Unified feedback events used across the app. enum FeedbackEvent { scanValid, // Valid barcode scanned → beep + short vibrate scanInvalid, // Invalid barcode → error sound + short vibrate submitSuccess, // Submit succeeded → success sound + long vibrate submitFailure, // Submit failed → failure sound + short vibrate duplicateError, // Duplicate (shelf) → alert loop + continuous vibrate networkError, // Network error → failure sound + short vibrate duplicateBoxNo, // Duplicate box no → failure sound + short vibrate alreadyCompleted, // Zongpai already boxed → beep + double vibrate modeSwitch, // Mode toggle → beep only paichanSwitch, // Paichan changed → beep + short vibrate } /// Centralized feedback dispatcher. /// /// Each page manages its own bottom status bar state; this service handles /// the sound, vibration channels only. class FeedbackService { final SoundService _soundService; FeedbackService({SoundService? soundService}) : _soundService = soundService ?? SoundService(); /// Trigger feedback for the given [event]. Future trigger(FeedbackEvent event) async { switch (event) { case FeedbackEvent.scanValid: _soundService.playBeep(); _vibrateShort(); case FeedbackEvent.scanInvalid: _soundService.playError(); _vibrateShort(); case FeedbackEvent.submitSuccess: _soundService.playSuccess(); _vibrateLong(); case FeedbackEvent.submitFailure: _soundService.playFailure(); _vibrateShort(); case FeedbackEvent.duplicateError: _soundService.playAlertLoop(); _vibratePattern(); case FeedbackEvent.networkError: _soundService.playFailure(); _vibrateShort(); case FeedbackEvent.duplicateBoxNo: _soundService.playFailure(); _vibrateShort(); case FeedbackEvent.alreadyCompleted: _soundService.playBeep(); _vibrateDouble(); case FeedbackEvent.modeSwitch: _soundService.playBeep(); case FeedbackEvent.paichanSwitch: _soundService.playBeep(); _vibrateShort(); } } /// Stop any ongoing alert (e.g. when duplicate dialog is closed). Future stopAlert() async { _soundService.stopAlert(); } void _vibrateShort() { Vibration.vibrate(duration: 100); } void _vibrateLong() { Vibration.vibrate(duration: 200); } /// Continuous vibration pattern: 3 bursts to signal critical error. void _vibratePattern() { Vibration.vibrate(pattern: [0, 300, 100, 300, 100, 300]); } /// Two short bursts to signal an already-completed item. void _vibrateDouble() { Vibration.vibrate(pattern: [0, 200, 100, 200]); } Future dispose() async { await _soundService.dispose(); } }