You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			621 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			621 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Dart
		
	
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/api/marathon/marathon_api_client.dart';
 | 
						|
import 'package:mohem_flutter_app/app_state/app_state.dart';
 | 
						|
import 'package:mohem_flutter_app/classes/consts.dart';
 | 
						|
import 'package:mohem_flutter_app/classes/utils.dart';
 | 
						|
import 'package:mohem_flutter_app/config/routes.dart';
 | 
						|
import 'package:mohem_flutter_app/models/marathon/marathon_generic_model.dart';
 | 
						|
import 'package:mohem_flutter_app/models/marathon/marathon_model.dart';
 | 
						|
import 'package:mohem_flutter_app/models/marathon/question_model.dart';
 | 
						|
import 'package:mohem_flutter_app/models/marathon/tutorial_notification_model.dart';
 | 
						|
import 'package:mohem_flutter_app/models/marathon/winner_model.dart';
 | 
						|
import 'package:mohem_flutter_app/models/privilege_list_model.dart';
 | 
						|
import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
 | 
						|
import 'package:video_player/video_player.dart';
 | 
						|
 | 
						|
class MarathonProvider extends ChangeNotifier {
 | 
						|
  //************************************************ VARIABLES **********************************************************
 | 
						|
 | 
						|
  final AppinioSwiperController swiperController = AppinioSwiperController();
 | 
						|
 | 
						|
  MarathonDetailModel marathonDetailModel = MarathonDetailModel();
 | 
						|
  MarathonDetailModel demoMarathonDetailModel = MarathonDetailModel();
 | 
						|
  List<CardContent> cardContentList = <CardContent>[];
 | 
						|
  QuestionModel currentQuestion = QuestionModel();
 | 
						|
  List<QuestionCardStatus> answerStatusesList = <QuestionCardStatus>[];
 | 
						|
  QuestionCardStatus questionCardStatus = QuestionCardStatus.question;
 | 
						|
  List<WinnerModel>? selectedWinners;
 | 
						|
  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 _isUpComingMarathon = true;
 | 
						|
 | 
						|
  bool get isUpComingMarathon => _isUpComingMarathon;
 | 
						|
 | 
						|
  set isUpComingMarathon(bool value) {
 | 
						|
    _isUpComingMarathon = value;
 | 
						|
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  bool _itsMarathonTime = false;
 | 
						|
 | 
						|
  bool get itsMarathonTime => _itsMarathonTime;
 | 
						|
 | 
						|
  set itsMarathonTime(bool value) {
 | 
						|
    _itsMarathonTime = value;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  bool _canPlayDemo = true;
 | 
						|
 | 
						|
  bool get canPlayDemo => _canPlayDemo;
 | 
						|
 | 
						|
  set canPlayDemo(bool value) {
 | 
						|
    _canPlayDemo = 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();
 | 
						|
  }
 | 
						|
 | 
						|
  int _totalMarathoners = 0;
 | 
						|
 | 
						|
  int get totalMarathoners => _totalMarathoners;
 | 
						|
 | 
						|
  set totalMarathoners(int value) {
 | 
						|
    _totalMarathoners = value;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  //****************SPONSOR VIDEO PLAYER**********
 | 
						|
 | 
						|
  late VideoPlayerController videoController;
 | 
						|
 | 
						|
  Future<void> initializeVideoPlayer() async {
 | 
						|
    videoController = VideoPlayerController.network(ApiConsts.marathonBaseUrlServices + marathonDetailModel.sponsors!.first.video!);
 | 
						|
    await videoController.initialize();
 | 
						|
    await videoController.play();
 | 
						|
    await videoController.setVolume(1.0);
 | 
						|
    await videoController.setLooping(false);
 | 
						|
    totalSponsorVideoSeconds = videoController.value.duration.inSeconds;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  void disposeVideoPlayer() {
 | 
						|
    videoController.dispose();
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  // 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();
 | 
						|
  }
 | 
						|
 | 
						|
  Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
 | 
						|
 | 
						|
  void startTimerToWaitForMarathon() {
 | 
						|
    const Duration oneSec = Duration(seconds: 1);
 | 
						|
    timerToWaitForMarathon = Timer.periodic(
 | 
						|
      oneSec,
 | 
						|
      (Timer timer) async {
 | 
						|
        if (totalSecondsToWaitForMarathon == 0) {
 | 
						|
          timer.cancel();
 | 
						|
          if (isUserWaiting) {
 | 
						|
            await callNextQuestionApi();
 | 
						|
          } else {
 | 
						|
            isButtonEnabled = false;
 | 
						|
          }
 | 
						|
          return;
 | 
						|
        } else {
 | 
						|
          totalSecondsToWaitForMarathon--;
 | 
						|
        }
 | 
						|
        notifyListeners();
 | 
						|
      },
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  int totalCurrentQuestionTime = 0;
 | 
						|
  int currentGapTime = 0;
 | 
						|
  Timer timerForQuestion = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
 | 
						|
  int callCountThreshold = 0;
 | 
						|
 | 
						|
  void startTimerForQuestion() {
 | 
						|
    const Duration oneSec = Duration(seconds: 1);
 | 
						|
    timerForQuestion = Timer.periodic(
 | 
						|
      oneSec,
 | 
						|
      (Timer timer) async {
 | 
						|
        // This 1 is just to show the color of answer tile for 1 and then update card status
 | 
						|
        if (totalCurrentQuestionTime - currentGapTime == 0) {
 | 
						|
          if (callCountThreshold == 0) {
 | 
						|
            getCorrectAnswerAndUpdateAnswerColor();
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        if (totalCurrentQuestionTime - currentGapTime == -2) {
 | 
						|
          if (callCountThreshold == 0) {
 | 
						|
            updateCardStatusToAnswer();
 | 
						|
          }
 | 
						|
          // scheduleMicrotask(() async {
 | 
						|
          //   if (AppState().getIsDemoMarathon || isUserOutOfGame) {
 | 
						|
          //     await callNextQuestionApi();
 | 
						|
          //   } else {
 | 
						|
          //     await callSubmitOptionApi().then((bool value) async {
 | 
						|
          //       updateIsUserOutOfGame = !value;
 | 
						|
          //       await callNextQuestionApi();
 | 
						|
          //     });
 | 
						|
          //   }
 | 
						|
          // });
 | 
						|
 | 
						|
          if (currentQuestionNumber == (AppState().getIsDemoMarathon ? demoMarathonDetailModel.totalQuestions! : marathonDetailModel.totalQuestions!)) {
 | 
						|
            isGettingQualifiers = true;
 | 
						|
            updateQuestionCardStatus(QuestionCardStatus.findingWinner);
 | 
						|
            timer.cancel();
 | 
						|
            cancelTimer();
 | 
						|
            notifyListeners();
 | 
						|
          }
 | 
						|
          totalCurrentQuestionTime--;
 | 
						|
          callCountThreshold = 0;
 | 
						|
        }
 | 
						|
 | 
						|
        if (totalCurrentQuestionTime == 0) {
 | 
						|
          gapTimeImage = currentQuestion.gapImage;
 | 
						|
          gapTimeText = currentQuestion.gapText;
 | 
						|
          gapTimeType = currentQuestion.gapType;
 | 
						|
          updateCardData();
 | 
						|
 | 
						|
          return;
 | 
						|
        } else {
 | 
						|
          if (totalCurrentQuestionTime - currentGapTime != -2) {
 | 
						|
            totalCurrentQuestionTime--;
 | 
						|
            callCountThreshold = 0;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        notifyListeners();
 | 
						|
      },
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  int totalSecondsToWaitForWinner = 30;
 | 
						|
  Timer timerForWinnerSelection = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
 | 
						|
 | 
						|
  void startTimerForWinnerSelection() {
 | 
						|
    const Duration oneSec = Duration(seconds: 1);
 | 
						|
    timerForWinnerSelection = Timer.periodic(
 | 
						|
      oneSec,
 | 
						|
      (Timer timer) async {
 | 
						|
        if (totalSecondsToWaitForWinner == 1) {
 | 
						|
          timer.cancel();
 | 
						|
          await callGetSelectedWinnersApi().whenComplete(() => updateQuestionCardStatus(QuestionCardStatus.winnerFound));
 | 
						|
          return;
 | 
						|
        } else if (totalSecondsToWaitForWinner == 15) {
 | 
						|
          totalSecondsToWaitForWinner--;
 | 
						|
          await callGetQualifiersApi();
 | 
						|
        } else {
 | 
						|
          totalSecondsToWaitForWinner--;
 | 
						|
        }
 | 
						|
 | 
						|
        notifyListeners();
 | 
						|
      },
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  //************************************************ FUNCTIONS **********************************************************
 | 
						|
 | 
						|
  void updateLanguageAsPerMarathon(BuildContext context, MarathonDetailModel 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<bool> callSubmitOptionApi() async {
 | 
						|
    return await MarathonApiClient().submitSelectedOption(marathonId: marathonDetailModel.id!, questionId: currentQuestion.id, selectedAnswerId: selectedOptionId);
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> callGetQualifiersApi() async {
 | 
						|
    if (AppState().getIsDemoMarathon) {
 | 
						|
      totalQualifiers = isUserOutOfGame ? 0 : 1;
 | 
						|
    } else {
 | 
						|
      totalQualifiers = await MarathonApiClient().getQualifiers(marathonId: marathonDetailModel.id!);
 | 
						|
    }
 | 
						|
    isGettingQualifiers = false;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> callGetSelectedWinnersApi() async {
 | 
						|
    if (AppState().getIsDemoMarathon) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    selectedWinners = await MarathonApiClient().getSelectedWinner(marathonId: marathonDetailModel.id!);
 | 
						|
    if (selectedWinners != null) {
 | 
						|
      selectedWinners!.removeWhere((WinnerModel element) {
 | 
						|
        if (element.employeeId == AppState().memberInformationList!.eMPLOYEENUMBER) {
 | 
						|
          iAmWinner = true;
 | 
						|
          return true;
 | 
						|
        } else {
 | 
						|
          return false;
 | 
						|
        }
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> callNextQuestionApi() async {
 | 
						|
    if (currentQuestionNumber < (AppState().getIsDemoMarathon ? demoMarathonDetailModel.totalQuestions! : marathonDetailModel.totalQuestions!)) {
 | 
						|
      if (currentQuestionNumber == 0) {
 | 
						|
        if (!AppState().getIsDemoMarathon) {
 | 
						|
          Utils.showLoading(AppRoutes.navigatorKey.currentContext!);
 | 
						|
        }
 | 
						|
        currentQuestion = AppState().getIsDemoMarathon
 | 
						|
            ? await DemoMarathonRepo().getDemoNextQuestion(currentQuestionNumber: currentQuestionNumber)
 | 
						|
            : (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!));
 | 
						|
        gapTimeImage = currentQuestion.gapImage;
 | 
						|
        gapTimeText = currentQuestion.gapText;
 | 
						|
        gapTimeType = currentQuestion.gapType;
 | 
						|
 | 
						|
        startTimerForQuestion();
 | 
						|
        updateCardData();
 | 
						|
        if (Utils.isLoading) {
 | 
						|
          Utils.hideLoading(AppRoutes.navigatorKey.currentContext!);
 | 
						|
        }
 | 
						|
        if (!AppState().getIsDemoMarathon) {
 | 
						|
          totalMarathoners = await MarathonApiClient().getMarathonersCount(marathonId: marathonDetailModel.id!);
 | 
						|
        }
 | 
						|
        Navigator.pushReplacementNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.marathonScreen);
 | 
						|
      } else {
 | 
						|
        currentQuestion = AppState().getIsDemoMarathon
 | 
						|
            ? await DemoMarathonRepo().getDemoNextQuestion(currentQuestionNumber: currentQuestionNumber)
 | 
						|
            : (await MarathonApiClient().getNextQuestion(questionId: currentQuestion.id, marathonId: marathonDetailModel.id!));
 | 
						|
      }
 | 
						|
      notifyListeners();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void updateCardData() {
 | 
						|
    if (currentQuestionNumber > 0) {
 | 
						|
      // swiperController.swipeLeft();
 | 
						|
    }
 | 
						|
    selectedOptionIndex = null;
 | 
						|
    currentQuestionNumber++;
 | 
						|
 | 
						|
    cardContentList.add(const CardContent());
 | 
						|
    totalCurrentQuestionTime = currentQuestion.questionTime! + currentQuestion.nextQuestGap!;
 | 
						|
    currentGapTime = currentQuestion.nextQuestGap!;
 | 
						|
    totalMarathoners = currentQuestion.remainingParticipantCount!;
 | 
						|
    questionCardStatus = QuestionCardStatus.question;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  void populateQuestionStatusesList() {
 | 
						|
    answerStatusesList.clear();
 | 
						|
    if (demoMarathonDetailModel.totalQuestions != null) {
 | 
						|
      for (int i = 0; i < demoMarathonDetailModel.totalQuestions!; i++) {
 | 
						|
        answerStatusesList.add(QuestionCardStatus.question);
 | 
						|
      }
 | 
						|
      notifyListeners();
 | 
						|
    }
 | 
						|
    if (isUpComingMarathon) {
 | 
						|
      if (marathonDetailModel.totalQuestions != null) {
 | 
						|
        for (int i = 0; i < marathonDetailModel.totalQuestions!; i++) {
 | 
						|
          answerStatusesList.add(QuestionCardStatus.question);
 | 
						|
        }
 | 
						|
        notifyListeners();
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void updateAnswerStatusesList(QuestionCardStatus status) {
 | 
						|
    answerStatusesList[currentQuestionNumber - 1] = status;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  void addItemToList(CardContent value) {
 | 
						|
    cardContentList.add(value);
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  void updateCurrentQuestionOptionStatus({required QuestionsOptionStatus status, required int selectedOptIndex, required int correctOptionIndex}) {
 | 
						|
    for (int i = 0; i < currentQuestion.questionOptions!.length; i++) {
 | 
						|
      currentQuestion.questionOptions![i].optionStatus = QuestionsOptionStatus.unSelected;
 | 
						|
    }
 | 
						|
    if (status == QuestionsOptionStatus.wrong) {
 | 
						|
      currentQuestion.questionOptions![correctOptionIndex].optionStatus = QuestionsOptionStatus.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(QuestionCardStatus status) {
 | 
						|
    if (status == QuestionCardStatus.wrongAnswer || status == QuestionCardStatus.skippedAnswer) {
 | 
						|
      if (AppState().getIsDemoMarathon) {
 | 
						|
        updateIsUserOutOfGame = true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    questionCardStatus = status;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  void getCorrectAnswerAndUpdateAnswerColor() {
 | 
						|
    log("correctOptionIndex");
 | 
						|
 | 
						|
    callCountThreshold = 1;
 | 
						|
    int correctOptionIndex = -1;
 | 
						|
    if (demoMarathonDetailModel.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: QuestionsOptionStatus.correct, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex);
 | 
						|
          } else {
 | 
						|
            updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.wrong, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex);
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          await callSubmitOptionApi().then((bool value) async {
 | 
						|
            updateIsUserOutOfGame = !value;
 | 
						|
            if (value) {
 | 
						|
              updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.correct, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex);
 | 
						|
            } else {
 | 
						|
              updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.wrong, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex);
 | 
						|
            }
 | 
						|
          });
 | 
						|
        }
 | 
						|
      });
 | 
						|
    } else {
 | 
						|
      if (!AppState().getIsDemoMarathon) {
 | 
						|
        scheduleMicrotask(() async {
 | 
						|
          await callSubmitOptionApi().then((bool value) async {
 | 
						|
            updateIsUserOutOfGame = !value;
 | 
						|
          });
 | 
						|
        });
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void updateCardStatusToAnswer() {
 | 
						|
    if (currentQuestionNumber == 0) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    callCountThreshold = 1;
 | 
						|
    scheduleMicrotask(() async {
 | 
						|
      await callNextQuestionApi();
 | 
						|
    });
 | 
						|
 | 
						|
    if (selectedOptionIndex == null) {
 | 
						|
      updateQuestionCardStatus(QuestionCardStatus.skippedAnswer);
 | 
						|
      updateAnswerStatusesList(QuestionCardStatus.skippedAnswer);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if (AppState().getIsDemoMarathon) {
 | 
						|
      if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) {
 | 
						|
        updateQuestionCardStatus(QuestionCardStatus.correctAnswer);
 | 
						|
        updateAnswerStatusesList(QuestionCardStatus.correctAnswer);
 | 
						|
      } else {
 | 
						|
        updateQuestionCardStatus(QuestionCardStatus.wrongAnswer);
 | 
						|
        updateAnswerStatusesList(QuestionCardStatus.wrongAnswer);
 | 
						|
      }
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if (!isUserOutOfGame) {
 | 
						|
      updateQuestionCardStatus(QuestionCardStatus.correctAnswer);
 | 
						|
      updateAnswerStatusesList(QuestionCardStatus.correctAnswer);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    updateQuestionCardStatus(QuestionCardStatus.wrongAnswer);
 | 
						|
    updateAnswerStatusesList(QuestionCardStatus.wrongAnswer);
 | 
						|
  }
 | 
						|
 | 
						|
  void resetValues() async {
 | 
						|
    _currentQuestionNumber = 0;
 | 
						|
    iAmWinner = false;
 | 
						|
    cardContentList.clear();
 | 
						|
    itsMarathonTime = false;
 | 
						|
    timerForWinnerSelection.cancel();
 | 
						|
    timerForSponsorVideo.cancel();
 | 
						|
    timerToWaitForMarathon.cancel();
 | 
						|
    timerForQuestion.cancel();
 | 
						|
    _isMarathonCompleted = false;
 | 
						|
    isUserOutOfGame = false;
 | 
						|
    isButtonEnabled = false;
 | 
						|
    isUserWaiting = false;
 | 
						|
    canPlayDemo = true;
 | 
						|
    totalCurrentQuestionTime = 0;
 | 
						|
    sponsorsSecondsCounter = 0;
 | 
						|
    totalSponsorVideoSeconds = 0;
 | 
						|
    totalSecondsToWaitForWinner = 30;
 | 
						|
    totalSecondsToWaitForMarathon = 30;
 | 
						|
    AppState().setIsDemoMarathon = false;
 | 
						|
    currentGapTime = 0;
 | 
						|
    currentQuestion = QuestionModel();
 | 
						|
    if (answerStatusesList.isNotEmpty) {
 | 
						|
      for (int i = 0; i < answerStatusesList.length; i++) {
 | 
						|
        answerStatusesList[i] = QuestionCardStatus.question;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    AppRoutes.navigatorKey.currentContext!.setLocale(savedLocale);
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  void cancelTimer() {
 | 
						|
    timerForQuestion.cancel();
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  bool checkIfPrivilegedForMarathon() {
 | 
						|
    for (PrivilegeListModel element in AppState().privilegeListModel!) {
 | 
						|
      if (element.serviceName == "Marathon") {
 | 
						|
        if (element.previlege != null) {
 | 
						|
          return element.previlege!;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> getMarathonDetailsFromApi() async {
 | 
						|
    isLoading = true;
 | 
						|
    notifyListeners();
 | 
						|
    isPrivilegedWithMarathon = checkIfPrivilegedForMarathon();
 | 
						|
    demoMarathonDetailModel = await DemoMarathonRepo().getDemoMarathonDetails();
 | 
						|
    if (isPrivilegedWithMarathon) {
 | 
						|
      marathonDetailModel = await MarathonApiClient().getMarathonDetails();
 | 
						|
      updateTotalSecondsToWaitForMarathon = marathonDetailModel.marathonBufferTime ?? 30;
 | 
						|
      if (marathonDetailModel.id == null) {
 | 
						|
        isUpComingMarathon = false;
 | 
						|
        isLoading = false;
 | 
						|
        populateQuestionStatusesList();
 | 
						|
        notifyListeners();
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      isUpComingMarathon = true;
 | 
						|
      if (DateTime.parse(marathonDetailModel.startTime!).isAfter(DateTime.now())) {
 | 
						|
        itsMarathonTime = false;
 | 
						|
      }
 | 
						|
      populateQuestionStatusesList();
 | 
						|
    }
 | 
						|
    isLoading = false;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> onJoinMarathonPressed(BuildContext context) async {
 | 
						|
    try {
 | 
						|
      Utils.showLoading(AppRoutes.navigatorKey.currentContext!);
 | 
						|
      MarathonApiClient().joinMarathonAsParticipant().then((MarathonGenericModel? marathonGenericModel) async {
 | 
						|
        Utils.hideLoading(AppRoutes.navigatorKey.currentContext!);
 | 
						|
        if (marathonGenericModel != null && marathonGenericModel.data != null) {
 | 
						|
          isUserWaiting = true;
 | 
						|
          Navigator.pushReplacementNamed(context, AppRoutes.marathonWaitingScreen);
 | 
						|
        } else if (marathonGenericModel!.data == null) {
 | 
						|
          Utils.showToast(marathonGenericModel.message.toString());
 | 
						|
        }
 | 
						|
      });
 | 
						|
    } catch (e) {
 | 
						|
      Utils.hideLoading(AppRoutes.navigatorKey.currentContext!);
 | 
						|
      Utils.confirmDialog(context, e.toString());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> onJoinDemoMarathonPressed(BuildContext context) async {
 | 
						|
    AppState().setIsDemoMarathon = true;
 | 
						|
    await callNextQuestionApi();
 | 
						|
  }
 | 
						|
 | 
						|
  bool isTutorialLoading = false;
 | 
						|
  TutorialNotificationModel? tutorial;
 | 
						|
 | 
						|
  Future<void> getMarathonTutorial() async {
 | 
						|
    isTutorialLoading = true;
 | 
						|
    notifyListeners();
 | 
						|
    tutorial = await MarathonApiClient().getMarathonTutorial();
 | 
						|
    isTutorialLoading = false;
 | 
						|
    notifyListeners();
 | 
						|
  }
 | 
						|
}
 |