|
|
|
|
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());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|