import 'dart:async'; import 'package:appinio_swiper/appinio_swiper.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/marathon/marathon_api_client.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_model.dart'; import 'package:mohem_flutter_app/models/marathon/question_model.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class MarathonProvider extends ChangeNotifier { final AppinioSwiperController swiperController = AppinioSwiperController(); MarathonDetailModel marathonDetailModel = MarathonDetailModel(); List cardContentList = []; QuestionModel currentQuestion = QuestionModel(); QuestionCardStatus questionCardStatus = QuestionCardStatus.question; int? selectedOptionIndex; int currentQuestionTime = 0; int totalSecondsToWaitForWinner = 30; int totalQualifiers = 0; void onNewQuestionReceived(QuestionModel newQuestion, BuildContext context) { if (currentQuestionNumber < marathonDetailModel.totalQuestions!) { if (currentQuestionNumber == 0) { if (Utils.isLoading) { Utils.hideLoading(context); } startTimerForQuestion(context); Navigator.pushNamed(context, AppRoutes.marathonScreen); } if (currentQuestionNumber > 0) { swipeCardLeft(); } print("I received a new question and time is $currentQuestionTime and number is $currentQuestionNumber"); selectedOptionIndex = null; currentQuestionNumber++; currentQuestion = newQuestion; cardContentList.add(const CardContent()); currentQuestionTime = newQuestion.questionTime!; questionCardStatus = QuestionCardStatus.question; notifyListeners(); } } void addItemToList(CardContent value) { cardContentList.add(value); notifyListeners(); } void updateCurrentQuestionOptionStatus(QuestionsOptionStatus status, int index) { for (int i = 0; i < currentQuestion.questionOptions!.length; i++) { currentQuestion.questionOptions![i].optionStatus = QuestionsOptionStatus.unSelected; } currentQuestion.questionOptions![index].optionStatus = status; selectedOptionIndex = index; notifyListeners(); } void updateQuestionCardStatus(QuestionCardStatus status) { questionCardStatus = status; notifyListeners(); } bool _isLoading = false; bool get isLoading => _isLoading; set isLoading(bool value) { _isLoading = value; notifyListeners(); } bool _itsMarathonTime = false; bool get itsMarathonTime => _itsMarathonTime; set itsMarathonTime(bool value) { _itsMarathonTime = value; notifyListeners(); } bool _isMarathonCompleted = false; bool get isMarathonCompleted => _isMarathonCompleted; set isMarathonCompleted(bool value) { _isMarathonCompleted = value; notifyListeners(); } int _currentQuestionNumber = 0; int get currentQuestionNumber => _currentQuestionNumber; set currentQuestionNumber(int value) { _currentQuestionNumber = value; notifyListeners(); } int _totalMarathoners = 23; int get totalMarathoners => _totalMarathoners; set totalMarathoners(int value) { _totalMarathoners = value; notifyListeners(); } void swipeCardLeft() { swiperController.swipeLeft(); notifyListeners(); } void getCorrectAnswerAndUpdateAnswerColor() { if (selectedOptionIndex != null) { if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!); } else { updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!); } } } void updateCardStatusToAnswer() { if (currentQuestionNumber == 0) { return; } if (selectedOptionIndex != null) { if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) { updateQuestionCardStatus(QuestionCardStatus.correctAnswer); } else { updateQuestionCardStatus(QuestionCardStatus.wrongAnswer); } } else { updateQuestionCardStatus(QuestionCardStatus.skippedAnswer); } } Timer timerForQuestion = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); void startTimerForQuestion(BuildContext context) { const Duration oneSec = Duration(seconds: 1); timerForQuestion = Timer.periodic( oneSec, (Timer timer) async { if (currentQuestionTime == 2) { getCorrectAnswerAndUpdateAnswerColor(); } if (currentQuestionTime == 0) { updateCardStatusToAnswer(); //todo: we will need to remove this -2 when API is all set if (currentQuestionNumber == marathonDetailModel.totalQuestions! - 1) { updateQuestionCardStatus(QuestionCardStatus.findingWinner); timer.cancel(); cancelTimer(); notifyListeners(); return; } } else { currentQuestionTime--; } notifyListeners(); }, ); } 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 == 0) { cancelTimer(); updateQuestionCardStatus(QuestionCardStatus.winnerFound); return; } totalSecondsToWaitForWinner--; notifyListeners(); }, ); } void resetValues() async { _currentQuestionNumber = 0; cardContentList.clear(); timerForWinnerSelection.cancel(); timerForQuestion.cancel(); _isMarathonCompleted = false; currentQuestionTime = 0; currentQuestion = QuestionModel(); notifyListeners(); } void cancelTimer() { timerForWinnerSelection.cancel(); timerForQuestion.cancel(); notifyListeners(); } Future getMarathonDetailsFromApi() async { isLoading = true; notifyListeners(); await MarathonApiClient().getMarathonToken().whenComplete(() async { marathonDetailModel = await MarathonApiClient().getMarathonDetails(); isLoading = false; notifyListeners(); }); } Future onJoinMarathonPressed(BuildContext context) async { Utils.showLoading(context); try { resetValues(); await MarathonApiClient().buildHubConnection(context); } catch (e, s) { Utils.hideLoading(context); print("error in onJoinMarathonPressed: ${e.toString()}"); Utils.confirmDialog(context, e.toString()); } } }