import 'dart:async'; import 'dart:developer'; import 'package:appinio_swiper/appinio_swiper.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/marathon/demo_marathon_repo.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/models/disclosure/disclosure_details_model.dart'; import 'package:mohem_flutter_app/models/disclosure/disclosure_question_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/ui/disclosure/widgets/disclosure_question_card.dart'; class DisclosureProvider extends ChangeNotifier { //************************************************ VARIABLES ********************************************************** final AppinioSwiperController swiperController = AppinioSwiperController(); DisclosureQuestionsOptionStatus currentQuestionSelectionStatus = DisclosureQuestionsOptionStatus.unSelected; DisclosureDetailsModel disclosureDetailsModel = DisclosureDetailsModel(); List cardContentList = []; DisclosureQuestionModel currentQuestion = DisclosureQuestionModel(); List answerStatusesList = []; DisclosureQuestionCardStatus questionCardStatus = DisclosureQuestionCardStatus.question; int? selectedOptionIndex; String? selectedOptionId; int? totalQualifiers; Locale savedLocale = const Locale("en", "US"); String? gapTimeImage; String? gapTimeText; int? gapTimeType; bool iAmWinner = false; bool isGettingQualifiers = false; bool isPrivilegedWithMarathon = false; bool _isLoading = false; bool get isLoading => _isLoading; set isLoading(bool value) { _isLoading = value; notifyListeners(); } bool _isButtonEnabled = false; bool get isButtonEnabled => _isButtonEnabled; set isButtonEnabled(bool value) { _isButtonEnabled = value; notifyListeners(); } bool _isUserWaiting = false; bool get isUserWaiting => _isUserWaiting; set isUserWaiting(bool value) { _isUserWaiting = value; notifyListeners(); } bool _isMarathonCompleted = false; bool get isMarathonCompleted => _isMarathonCompleted; set isMarathonCompleted(bool value) { _isMarathonCompleted = value; notifyListeners(); } bool isUserOutOfGame = false; set updateIsUserOutOfGame(bool value) { isUserOutOfGame = value; notifyListeners(); } int _currentQuestionNumber = 0; int get currentQuestionNumber => _currentQuestionNumber; set currentQuestionNumber(int value) { _currentQuestionNumber = value; notifyListeners(); } void updateCurrentQuestionSelectionStatus(DisclosureQuestionsOptionStatus value) { currentQuestionSelectionStatus = value; notifyListeners(); } int _totalMarathoners = 0; int get totalMarathoners => _totalMarathoners; set totalMarathoners(int value) { _totalMarathoners = value; notifyListeners(); } //****************SPONSOR VIDEO PLAYER********** // 9c47d281-c5b5-4b5d-a90a-08dacb8cbdb6 // MarathonI //************************************************ TIMERS ********************************************************** int sponsorsSecondsCounter = 0; int totalSponsorVideoSeconds = 0; Timer timerForSponsorVideo = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); void startTimerForSponsorVideo() { const Duration oneSec = Duration(seconds: 1); timerForSponsorVideo = Timer.periodic( oneSec, (Timer timer) async { sponsorsSecondsCounter++; if (totalSponsorVideoSeconds == 0) { timer.cancel(); notifyListeners(); return; } else { totalSponsorVideoSeconds--; } notifyListeners(); }, ); } int totalSecondsToWaitForMarathon = 30; set updateTotalSecondsToWaitForMarathon(int value) { totalSecondsToWaitForMarathon = value; notifyListeners(); } //************************************************ FUNCTIONS ********************************************************** void updateLanguageAsPerMarathon(BuildContext context, DisclosureDetailsModel detailModel) { savedLocale = context.locale; if (detailModel.selectedLanguage == 1) { context.setLocale(const Locale("en", "US")); } else if (detailModel.selectedLanguage == 2) { context.setLocale(const Locale("ar", "SA")); } else if (detailModel.selectedLanguage == 3) { } else { context.setLocale(const Locale("en", "US")); } } Future callGetQualifiersApi() async { if (AppState().getIsDemoMarathon) { totalQualifiers = isUserOutOfGame ? 0 : 1; } isGettingQualifiers = false; notifyListeners(); } Future callGetSelectedWinnersApi() async { if (AppState().getIsDemoMarathon) { return; } } Future callNextQuestionApi() async { if (currentQuestionNumber < (disclosureDetailsModel.totalQuestions!)) { if (currentQuestionNumber == 0) { currentQuestion = await DisclosureRepo().getDisclosureNextQuestion(currentQuestionNumber: currentQuestionNumber); gapTimeImage = currentQuestion.gapImage; gapTimeText = currentQuestion.gapText; gapTimeType = currentQuestion.gapType; updateCardData(); if (Utils.isLoading) { Utils.hideLoading(AppRoutes.navigatorKey.currentContext!); } Navigator.pushReplacementNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.disclosureScreen); } else { currentQuestion = await DisclosureRepo().getDisclosureNextQuestion(currentQuestionNumber: currentQuestionNumber); } notifyListeners(); } } void updateCardData() { if (currentQuestionNumber > 0) { // swiperController.swipeLeft(); } selectedOptionIndex = null; currentQuestionNumber++; cardContentList.add(const DisclosureCardContent()); totalMarathoners = currentQuestion.remainingParticipantCount!; questionCardStatus = DisclosureQuestionCardStatus.question; notifyListeners(); } void populateQuestionStatusesList() { answerStatusesList.clear(); if (disclosureDetailsModel.totalQuestions != null) { for (int i = 0; i < disclosureDetailsModel.totalQuestions!; i++) { answerStatusesList.add(DisclosureQuestionCardStatus.question); } notifyListeners(); } } void updateAnswerStatusesList(DisclosureQuestionCardStatus status) { answerStatusesList[currentQuestionNumber - 1] = status; notifyListeners(); } void updateCurrentQuestionOptionStatus({required DisclosureQuestionsOptionStatus status, required int selectedOptIndex, required int correctOptionIndex}) { if (selectedOptionIndex == 0) {} for (int i = 0; i < currentQuestion.questionOptions!.length; i++) { currentQuestion.questionOptions![i].optionStatus = DisclosureQuestionsOptionStatus.unSelected; } if (status == DisclosureQuestionsOptionStatus.wrong) { currentQuestion.questionOptions![correctOptionIndex].optionStatus = DisclosureQuestionsOptionStatus.correct; // if person's answer is wrong we have to show him the actual right answer } currentQuestion.questionOptions![selectedOptIndex].optionStatus = status; selectedOptionId = currentQuestion.questionOptions![selectedOptIndex].id; selectedOptionIndex = selectedOptIndex; notifyListeners(); } void updateQuestionCardStatus(DisclosureQuestionCardStatus status) { if (status == DisclosureQuestionCardStatus.wrongAnswer || status == DisclosureQuestionCardStatus.skippedAnswer) { if (AppState().getIsDemoMarathon) { updateIsUserOutOfGame = true; } } questionCardStatus = status; notifyListeners(); } void getCorrectAnswerAndUpdateAnswerColor() { log("correctOptionIndex"); int correctOptionIndex = -1; if (disclosureDetailsModel.displayCorrectAnswer ?? false) { correctOptionIndex = currentQuestion.questionOptions!.indexWhere((QuestionOptions element) => element.isCorrectOption ?? false); log("correctOptionIndex: $correctOptionIndex"); } if (selectedOptionIndex != null) { scheduleMicrotask(() async { if (AppState().getIsDemoMarathon) { if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { updateCurrentQuestionOptionStatus(status: DisclosureQuestionsOptionStatus.correct, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex); } else { updateCurrentQuestionOptionStatus(status: DisclosureQuestionsOptionStatus.wrong, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex); } } }); } else { if (!AppState().getIsDemoMarathon) {} } } void updateCardStatusToAnswer() { if (currentQuestionNumber == 0) { return; } scheduleMicrotask(() async { await callNextQuestionApi(); }); if (selectedOptionIndex == null) { updateQuestionCardStatus(DisclosureQuestionCardStatus.skippedAnswer); updateAnswerStatusesList(DisclosureQuestionCardStatus.skippedAnswer); return; } if (AppState().getIsDemoMarathon) { if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { updateQuestionCardStatus(DisclosureQuestionCardStatus.correctAnswer); updateAnswerStatusesList(DisclosureQuestionCardStatus.correctAnswer); } else { updateQuestionCardStatus(DisclosureQuestionCardStatus.wrongAnswer); updateAnswerStatusesList(DisclosureQuestionCardStatus.wrongAnswer); } return; } if (!isUserOutOfGame) { updateQuestionCardStatus(DisclosureQuestionCardStatus.correctAnswer); updateAnswerStatusesList(DisclosureQuestionCardStatus.correctAnswer); return; } updateQuestionCardStatus(DisclosureQuestionCardStatus.wrongAnswer); updateAnswerStatusesList(DisclosureQuestionCardStatus.wrongAnswer); } void resetValues() async { _currentQuestionNumber = 0; iAmWinner = false; cardContentList.clear(); timerForSponsorVideo.cancel(); _isMarathonCompleted = false; isUserOutOfGame = false; isButtonEnabled = false; isUserWaiting = false; sponsorsSecondsCounter = 0; totalSponsorVideoSeconds = 0; totalSecondsToWaitForMarathon = 30; AppState().setIsDemoMarathon = false; currentQuestion = DisclosureQuestionModel(); if (answerStatusesList.isNotEmpty) { for (int i = 0; i < answerStatusesList.length; i++) { answerStatusesList[i] = DisclosureQuestionCardStatus.question; } } AppRoutes.navigatorKey.currentContext!.setLocale(savedLocale); notifyListeners(); } bool checkIfPrivilegedForMarathon() { for (PrivilegeListModel element in AppState().privilegeListModel!) { if (element.serviceName == "Marathon") { if (element.previlege != null) { return element.previlege!; } } } return false; } Future getDisclosureDetails() async { isLoading = true; notifyListeners(); disclosureDetailsModel = await DisclosureRepo().getDisclosureDetails(); log("here: ${disclosureDetailsModel.descEn}"); populateQuestionStatusesList(); isLoading = false; notifyListeners(); } Future onJoinDemoMarathonPressed(BuildContext context) async { AppState().setIsDemoMarathon = true; await callNextQuestionApi(); } }