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.
		
		
		
		
		
			
		
			
				
	
	
		
			231 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			231 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Dart
		
	
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<CardContent> cardContentList = <CardContent>[];
 | 
						|
  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<void> getMarathonDetailsFromApi() async {
 | 
						|
    isLoading = true;
 | 
						|
    notifyListeners();
 | 
						|
    await MarathonApiClient().getMarathonToken().whenComplete(() async {
 | 
						|
      marathonDetailModel = await MarathonApiClient().getMarathonDetails();
 | 
						|
      isLoading = false;
 | 
						|
      notifyListeners();
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> 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());
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |