import 'dart:async'; import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:hmg_qline/config/dependency_injection.dart'; import 'package:hmg_qline/constants/app_constants.dart'; import 'package:hmg_qline/models/global_config_model.dart'; import 'package:hmg_qline/models/ticket_model.dart'; import 'package:hmg_qline/repositories/screen_details_repo.dart'; import 'package:hmg_qline/repositories/signalR_repo.dart'; import 'package:hmg_qline/services/audio_service.dart'; import 'package:hmg_qline/services/cache_service.dart'; import 'package:hmg_qline/services/text_to_speech_service.dart'; import 'package:hmg_qline/view_models/screen_config_view_model.dart'; class QueuingViewModel extends ChangeNotifier { final ScreenDetailsRepo screenDetailsRepo; final SignalrRepo signalrRepo; final CacheService cacheService; final AudioService audioService; final TextToSpeechService textToSpeechService; QueuingViewModel({ required this.screenDetailsRepo, required this.signalrRepo, required this.cacheService, required this.audioService, required this.textToSpeechService, }); Future initializeQueueingVM() async { await startHubConnection(); initializeAudioPlayer(); initializeTextToSpeech(); } Future startHubConnection() async { ScreenConfigViewModel screenConfigViewModel = getIt.get(); await signalrRepo.startHubConnection( deviceIp: screenConfigViewModel.currentScreenIP, onHubTicketCall: onHubTicketCall, onHubConfigCall: onHubConfigCall, onHubReconnected: onHubReconnected, onHubDisconnected: onHubDisconnected, onHubConnecting: onHubConnecting, ); } initializeAudioPlayer() { audioService.listenAudioPlayerEvents(onAudioCompleted: onToneCompleted); } initializeTextToSpeech() { textToSpeechService.listenToTextToSpeechEvents(onVoiceCompleted: onVoiceCompleted); } Future onHubConfigCall(var response) async { log("onHubConfigCall: $response"); // TODO: // ScreenConfigViewModel screenConfigViewModel = getIt.get(); // screenConfigViewModel.updateGlobalConfigurationsModel(true); } Future onHubReconnected(var response) async { log("onHubConnected: $response"); ScreenConfigViewModel screenConfigViewModel = getIt.get(); screenConfigViewModel.updateIsHubConnected(true); log("screenConfigViewModel: ${screenConfigViewModel.isHubConnected}"); screenConfigViewModel.notifyListeners(); } Future onHubDisconnected(var response) async { log("onHubDisconnected: $response"); ScreenConfigViewModel screenConfigViewModel = getIt.get(); screenConfigViewModel.updateIsHubConnected(false); screenConfigViewModel.notifyListeners(); } Future onHubConnecting(var response) async => log("onHubConnecting: $response"); Future onToneCompleted() async { GlobalConfigurationsModel globalConfigurationsModel = getIt.get().globalConfigurationsModel; if (globalConfigurationsModel.isVoiceReq) { textToSpeechService.speechText( globalConfigurationsModel: globalConfigurationsModel, ticket: currentTickets.first, ); } else { waitAndCallNextTicketIfThere(); } } Future onVoiceCompleted() async { waitAndCallNextTicketIfThere(); } waitAndCallNextTicketIfThere() { GlobalConfigurationsModel globalConfigurationsModel = getIt.get().globalConfigurationsModel; Timer(Duration(seconds: globalConfigurationsModel.concurrentCallDelaySec ?? 1), () async { if (queueTickets.isNotEmpty) { currentTickets.insert(0, queueTickets.first); notifyListeners(); queueTickets.removeAt(0); voiceCallTicket(ticketData: currentTickets.first.ticketModel); } else { isCallingInProgress = false; } }); } Future onHubTicketCall(List? response) async { logger.i("onHubTicketCall: $response"); if (response != null && response.isNotEmpty) { TicketDetailsModel ticketDetailsModel = TicketDetailsModel.fromJson(response.first as Map); addNewTicket(ticketDetailsModel); } } bool isCallingInProgress = false; // Tickets Management List currentTickets = []; List queueTickets = []; void addNewTicket(TicketDetailsModel ticket) { if (!isCallingInProgress) { currentTickets.insert(0, ticket); voiceCallTicket(ticketData: currentTickets.first.ticketModel); } else { queueTickets.add(ticket); log("inQueue Length: ${queueTickets.length}"); } notifyListeners(); } Future voiceCallTicket({required TicketData? ticketData}) async { if (ticketData == null) return; GlobalConfigurationsModel globalConfigurationsModel = getIt.get().globalConfigurationsModel; if (globalConfigurationsModel.isToneReq) { isCallingInProgress = true; await audioService.playTone(path: AppAssets.callTone); } else if (globalConfigurationsModel.isVoiceReq) { isCallingInProgress = true; await textToSpeechService.speechText( globalConfigurationsModel: globalConfigurationsModel, ticket: currentTickets.first, ); } else { waitAndCallNextTicketIfThere(); } } }