|
|
|
@ -13,7 +13,7 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
|
|
|
|
import 'package:video_player/video_player.dart';
|
|
|
|
import 'package:video_player/video_player.dart';
|
|
|
|
|
|
|
|
|
|
|
|
class MarathonProvider extends ChangeNotifier {
|
|
|
|
class MarathonProvider extends ChangeNotifier {
|
|
|
|
// VARIABLES
|
|
|
|
//****************VARIABLES**********
|
|
|
|
|
|
|
|
|
|
|
|
final AppinioSwiperController swiperController = AppinioSwiperController();
|
|
|
|
final AppinioSwiperController swiperController = AppinioSwiperController();
|
|
|
|
|
|
|
|
|
|
|
|
@ -24,9 +24,7 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
QuestionCardStatus questionCardStatus = QuestionCardStatus.question;
|
|
|
|
QuestionCardStatus questionCardStatus = QuestionCardStatus.question;
|
|
|
|
|
|
|
|
|
|
|
|
int? selectedOptionIndex;
|
|
|
|
int? selectedOptionIndex;
|
|
|
|
int currentQuestionTime = 0;
|
|
|
|
String? selectedOptionId;
|
|
|
|
int totalSecondsToWaitForWinner = 30;
|
|
|
|
|
|
|
|
int totalSecondsToWaitForMarathon = 20;
|
|
|
|
|
|
|
|
int totalQualifiers = 0;
|
|
|
|
int totalQualifiers = 0;
|
|
|
|
|
|
|
|
|
|
|
|
bool _isLoading = false;
|
|
|
|
bool _isLoading = false;
|
|
|
|
@ -38,6 +36,15 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool _isUpComingMarathon = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool get isUpComingMarathon => _isUpComingMarathon;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set isUpComingMarathon(bool value) {
|
|
|
|
|
|
|
|
_isUpComingMarathon = value;
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool _itsMarathonTime = false;
|
|
|
|
bool _itsMarathonTime = false;
|
|
|
|
|
|
|
|
|
|
|
|
bool get itsMarathonTime => _itsMarathonTime;
|
|
|
|
bool get itsMarathonTime => _itsMarathonTime;
|
|
|
|
@ -72,7 +79,7 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int _totalMarathoners = 23;
|
|
|
|
int _totalMarathoners = 0;
|
|
|
|
|
|
|
|
|
|
|
|
int get totalMarathoners => _totalMarathoners;
|
|
|
|
int get totalMarathoners => _totalMarathoners;
|
|
|
|
|
|
|
|
|
|
|
|
@ -81,7 +88,7 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//VIDEO PLAYER
|
|
|
|
//****************SPONSOR VIDEO PLAYER**********
|
|
|
|
|
|
|
|
|
|
|
|
late VideoPlayerController videoController;
|
|
|
|
late VideoPlayerController videoController;
|
|
|
|
|
|
|
|
|
|
|
|
@ -101,6 +108,8 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//****************TIMERS**********
|
|
|
|
|
|
|
|
|
|
|
|
int totalSponsorVideoSeconds = 0;
|
|
|
|
int totalSponsorVideoSeconds = 0;
|
|
|
|
Timer timerForSponsorVideo = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
|
|
|
|
Timer timerForSponsorVideo = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
|
|
|
|
|
|
|
|
|
|
|
|
@ -122,8 +131,7 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FUNCTIONS
|
|
|
|
int totalSecondsToWaitForMarathon = 20;
|
|
|
|
|
|
|
|
|
|
|
|
Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
|
|
|
|
Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
|
|
|
|
|
|
|
|
|
|
|
|
void startTimerToMarathon(BuildContext context) {
|
|
|
|
void startTimerToMarathon(BuildContext context) {
|
|
|
|
@ -140,42 +148,123 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void populateQuestionStatusesList() {
|
|
|
|
int totalCurrentQuestionTime = 0;
|
|
|
|
if (marathonDetailModel.totalQuestions != null) {
|
|
|
|
int currentGapTime = 0;
|
|
|
|
for (int i = 0; i < marathonDetailModel.totalQuestions! - 1; i++) {
|
|
|
|
Timer timerForQuestion = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
|
|
|
|
answerStatusesList.add(QuestionCardStatus.question);
|
|
|
|
|
|
|
|
}
|
|
|
|
void startTimerForQuestion() {
|
|
|
|
notifyListeners();
|
|
|
|
const Duration oneSec = Duration(seconds: 1);
|
|
|
|
}
|
|
|
|
timerForQuestion = Timer.periodic(
|
|
|
|
|
|
|
|
oneSec,
|
|
|
|
|
|
|
|
(Timer timer) async {
|
|
|
|
|
|
|
|
// This 2 is just to show the color of answer tile for 2 seconds and then update card status
|
|
|
|
|
|
|
|
if (totalCurrentQuestionTime - currentGapTime == currentQuestion.questionTime! - 2) {
|
|
|
|
|
|
|
|
getCorrectAnswerAndUpdateAnswerColor();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (totalCurrentQuestionTime == currentGapTime) {
|
|
|
|
|
|
|
|
updateCardStatusToAnswer();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await callSubmitOptionApi().then((bool value) async {
|
|
|
|
|
|
|
|
if (value) {
|
|
|
|
|
|
|
|
await callNextQuestionApi();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (totalCurrentQuestionTime == 0) {
|
|
|
|
|
|
|
|
updateCardData();
|
|
|
|
|
|
|
|
if (currentQuestionNumber == marathonDetailModel.totalQuestions! - 1) {
|
|
|
|
|
|
|
|
updateQuestionCardStatus(QuestionCardStatus.findingWinner);
|
|
|
|
|
|
|
|
timer.cancel();
|
|
|
|
|
|
|
|
cancelTimer();
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
totalCurrentQuestionTime--;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void updateAnswerStatusesList(QuestionCardStatus status) {
|
|
|
|
int totalSecondsToWaitForWinner = 30;
|
|
|
|
answerStatusesList[currentQuestionNumber - 1] = status;
|
|
|
|
Timer timerForWinnerSelection = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
|
|
|
|
void startTimerForWinnerSelection() {
|
|
|
|
|
|
|
|
const Duration oneSec = Duration(seconds: 1);
|
|
|
|
|
|
|
|
timerForWinnerSelection = Timer.periodic(
|
|
|
|
|
|
|
|
oneSec,
|
|
|
|
|
|
|
|
(Timer timer) async {
|
|
|
|
|
|
|
|
if (totalSecondsToWaitForWinner == 0) {
|
|
|
|
|
|
|
|
timer.cancel();
|
|
|
|
|
|
|
|
updateQuestionCardStatus(QuestionCardStatus.winnerFound);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
totalSecondsToWaitForWinner--;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//****************FUNCTIONS*********
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Future<bool> callSubmitOptionApi() async {
|
|
|
|
|
|
|
|
return await MarathonApiClient().submitSelectedOption(selectedAnswerId: selectedOptionId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onNewQuestionReceived(QuestionModel newQuestion) {
|
|
|
|
// TODO: here I need to add a logic where I should call this function for Api but for the 1st question it should behave differently
|
|
|
|
|
|
|
|
// TODO: Verify the callings!!!
|
|
|
|
|
|
|
|
Future<void> callNextQuestionApi() async {
|
|
|
|
if (currentQuestionNumber < marathonDetailModel.totalQuestions!) {
|
|
|
|
if (currentQuestionNumber < marathonDetailModel.totalQuestions!) {
|
|
|
|
if (currentQuestionNumber == 0) {
|
|
|
|
if (currentQuestionNumber == 0) {
|
|
|
|
|
|
|
|
currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!))!;
|
|
|
|
if (Utils.isLoading) {
|
|
|
|
if (Utils.isLoading) {
|
|
|
|
Utils.hideLoading(AppRoutes.navigatorKey.currentContext!);
|
|
|
|
Utils.hideLoading(AppRoutes.navigatorKey.currentContext!);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
startTimerForQuestion(AppRoutes.navigatorKey.currentContext!);
|
|
|
|
startTimerForQuestion();
|
|
|
|
|
|
|
|
updateCardData();
|
|
|
|
|
|
|
|
|
|
|
|
Navigator.pushReplacementNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.marathonScreen);
|
|
|
|
Navigator.pushReplacementNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.marathonScreen);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: currentQuestion.id, marathonId: marathonDetailModel.id!))!;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (currentQuestionNumber > 0) {
|
|
|
|
notifyListeners();
|
|
|
|
swipeCardLeft();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void updateCardData() {
|
|
|
|
|
|
|
|
if (currentQuestionNumber > 0) {
|
|
|
|
|
|
|
|
print("swiped it away!!");
|
|
|
|
|
|
|
|
swipeCardLeft();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
selectedOptionIndex = null;
|
|
|
|
|
|
|
|
currentQuestionNumber++;
|
|
|
|
|
|
|
|
cardContentList.add(const CardContent());
|
|
|
|
|
|
|
|
totalCurrentQuestionTime = currentQuestion.questionTime! + currentQuestion.nextQuestGap!;
|
|
|
|
|
|
|
|
currentGapTime = currentQuestion.nextQuestGap!;
|
|
|
|
|
|
|
|
totalMarathoners = currentQuestion.remainingParticipantCount!;
|
|
|
|
|
|
|
|
questionCardStatus = QuestionCardStatus.question;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void populateQuestionStatusesList() {
|
|
|
|
|
|
|
|
if (marathonDetailModel.totalQuestions != null) {
|
|
|
|
|
|
|
|
for (int i = 0; i < marathonDetailModel.totalQuestions! - 1; i++) {
|
|
|
|
|
|
|
|
answerStatusesList.add(QuestionCardStatus.question);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
selectedOptionIndex = null;
|
|
|
|
|
|
|
|
currentQuestionNumber++;
|
|
|
|
|
|
|
|
currentQuestion = newQuestion;
|
|
|
|
|
|
|
|
cardContentList.add(const CardContent());
|
|
|
|
|
|
|
|
currentQuestionTime = newQuestion.questionTime!;
|
|
|
|
|
|
|
|
questionCardStatus = QuestionCardStatus.question;
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void updateAnswerStatusesList(QuestionCardStatus status) {
|
|
|
|
|
|
|
|
answerStatusesList[currentQuestionNumber - 1] = status;
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void addItemToList(CardContent value) {
|
|
|
|
void addItemToList(CardContent value) {
|
|
|
|
cardContentList.add(value);
|
|
|
|
cardContentList.add(value);
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
@ -227,57 +316,6 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
|
|
|
// we can enable this check if we do not want to show the user QuestionGapImages
|
|
|
|
|
|
|
|
// if (!isUserOutOfGame) {
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
|
|
|
timer.cancel();
|
|
|
|
|
|
|
|
updateQuestionCardStatus(QuestionCardStatus.winnerFound);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
totalSecondsToWaitForWinner--;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void swipeCardLeft() {
|
|
|
|
void swipeCardLeft() {
|
|
|
|
swiperController.swipeLeft();
|
|
|
|
swiperController.swipeLeft();
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
@ -289,7 +327,7 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
timerForWinnerSelection.cancel();
|
|
|
|
timerForWinnerSelection.cancel();
|
|
|
|
timerForQuestion.cancel();
|
|
|
|
timerForQuestion.cancel();
|
|
|
|
_isMarathonCompleted = false;
|
|
|
|
_isMarathonCompleted = false;
|
|
|
|
currentQuestionTime = 0;
|
|
|
|
totalCurrentQuestionTime = 0;
|
|
|
|
currentQuestion = QuestionModel();
|
|
|
|
currentQuestion = QuestionModel();
|
|
|
|
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
@ -305,6 +343,11 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
await MarathonApiClient().getMarathonToken().whenComplete(() async {
|
|
|
|
await MarathonApiClient().getMarathonToken().whenComplete(() async {
|
|
|
|
marathonDetailModel = await MarathonApiClient().getMarathonDetails();
|
|
|
|
marathonDetailModel = await MarathonApiClient().getMarathonDetails();
|
|
|
|
|
|
|
|
if (marathonDetailModel.id == null) {
|
|
|
|
|
|
|
|
isUpComingMarathon = false;
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
populateQuestionStatusesList();
|
|
|
|
populateQuestionStatusesList();
|
|
|
|
isLoading = false;
|
|
|
|
isLoading = false;
|
|
|
|
notifyListeners();
|
|
|
|
notifyListeners();
|
|
|
|
@ -334,7 +377,17 @@ class MarathonProvider extends ChangeNotifier {
|
|
|
|
Navigator.pushNamed(context, AppRoutes.marathonSponsorVideoScreen);
|
|
|
|
Navigator.pushNamed(context, AppRoutes.marathonSponsorVideoScreen);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
Navigator.pushReplacementNamed(context, AppRoutes.marathonWaitingScreen);
|
|
|
|
try {
|
|
|
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
|
|
|
bool isJoined = await MarathonApiClient().joinMarathonAsParticipant();
|
|
|
|
|
|
|
|
if (isJoined) {
|
|
|
|
|
|
|
|
print("joined");
|
|
|
|
|
|
|
|
callNextQuestionApi();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (e, s) {
|
|
|
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
|
|
|
Utils.confirmDialog(context, e.toString());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|