From 603ff1b19fbc0e08fd469f45c872f256320a650c Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Tue, 6 Dec 2022 16:18:31 +0300 Subject: [PATCH] Committing after API replacement from SignalR => InProgress --- assets/langs/ar-SA.json | 3 +- assets/langs/en-US.json | 3 +- lib/api/marathon/marathon_api_client.dart | 46 +++- lib/classes/consts.dart | 6 +- lib/generated/locale_keys.g.dart | 1 + lib/models/marathon/question_model.dart | 4 + lib/ui/landing/dashboard_screen.dart | 10 +- lib/ui/marathon/marathon_provider.dart | 215 +++++++++++------- lib/ui/marathon/marathon_screen.dart | 86 +++---- lib/ui/marathon/marathon_waiting_screen.dart | 4 +- lib/ui/marathon/widgets/marathon_banner.dart | 6 +- .../widgets/marathon_progress_container.dart | 6 +- 12 files changed, 238 insertions(+), 152 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 4e1d930..c4d6d65 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -508,5 +508,6 @@ "winner": "الفائز", "youWantToLeaveMarathon": "هل أنت متأكد أنك تريد العودة؟ سوف تخرج من المسابقة.", "ourSponsor": "راعينا:", - "startingIn": "يبدأ في" + "startingIn": "يبدأ في", + "youAreOutOfContest": "أنت خارج المسابقة." } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 1b0d468..48a1db5 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -508,6 +508,7 @@ "winner": "WINNER", "youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.", "ourSponsor": "Our Sponsor:", - "startingIn": "Starting in" + "startingIn": "Starting in", + "youAreOutOfContest": "You are out of the contest." } \ No newline at end of file diff --git a/lib/api/marathon/marathon_api_client.dart b/lib/api/marathon/marathon_api_client.dart index 1d9eb81..132ec30 100644 --- a/lib/api/marathon/marathon_api_client.dart +++ b/lib/api/marathon/marathon_api_client.dart @@ -65,9 +65,14 @@ class MarathonApiClient { Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonUpcomingUrl + payrollString, token: AppState().getMarathonToken ?? await getMarathonToken()); var json = jsonDecode(response.body); + logger.i("json in getMarathonDetails: $json"); MarathonGenericModel marathonGenericModel = MarathonGenericModel.fromJson(json); + if (marathonGenericModel.data == null) { + return MarathonDetailModel(); + } + MarathonDetailModel marathonDetailModel = MarathonDetailModel.fromJson(marathonGenericModel.data); AppState().setMarathonProjectId = marathonDetailModel.id!; @@ -85,11 +90,17 @@ class MarathonApiClient { Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonJoinParticipantUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); var json = jsonDecode(response.body); + MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); + if (marathonModel.statusCode == 208) { + // means participant is already in the marathon i.e already joined + return true; + } + if (marathonModel.statusCode == 200) { if (marathonModel.data != null && marathonModel.isSuccessful == true) { - logger.i("message: ${marathonModel.data}"); + logger.i("joinMarathonAsParticipant: ${marathonModel.data}"); return true; } else { return false; @@ -99,9 +110,8 @@ class MarathonApiClient { } } - Future getNextQuestion({required String? selectedOptionId, required String? questionId, required String marathonId}) async { + Future getNextQuestion({required String? questionId, required String marathonId}) async { Map jsonObject = { - "selectedOptionId": selectedOptionId, "questionId": questionId, "marathonId": marathonId, }; @@ -109,20 +119,34 @@ class MarathonApiClient { Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonNextQuestionUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); var json = jsonDecode(response.body); - MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); - if (marathonModel.statusCode == 200) { - if (marathonModel.data != null && marathonModel.isSuccessful == true) { - logger.i("message: ${marathonModel.data}"); - return null; - } else { - return null; - } + var data = json["data"]; + + if (data != null) { + QuestionModel newQuestion = QuestionModel.fromJson(data); + return newQuestion; } else { return null; } } + Future submitSelectedOption({required String? selectedAnswerId}) async { + Map jsonObject = {"selectedOptionId": selectedAnswerId}; + + Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonSubmitAnswerUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); + + var json = jsonDecode(response.body); + logger.i("json: $json"); + + MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); + + if (marathonModel.isSuccessful == null) { + return false; + } + + return marathonModel.isSuccessful!; + } + // Future buildHubConnection(BuildContext context, String prizeId) async { // HttpConnectionOptions httpOptions = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); // hubConnection = HubConnectionBuilder() diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index f53c02f..bb38ca2 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -28,15 +28,15 @@ class ApiConsts { static String chatUserImages = chatServerBaseUrl + "empservice/api/employee/"; //Brain Marathon Constants - static String marathonBaseUrl = "https://18.188.181.12/service/api/"; - static String marathonHubConnectionUrl = "https://18.188.181.12/service/MarathonBroadCast"; + static String marathonBaseUrl = "https://marathoon.com/service/api/"; + // static String marathonHubConnectionUrl = "https://18.188.181.12/service/MarathonBroadCast"; static String marathonParticipantLoginUrl = marathonBaseUrl + "auth/participantlogin"; static String marathonProjectGetUrl = marathonBaseUrl + "Project/Project_Get"; static String marathonUpcomingUrl = marathonBaseUrl + "marathon/upcoming/"; static String marathonJoinParticipantUrl = marathonBaseUrl + "participant/participant_join"; static String marathonNextQuestionUrl = marathonBaseUrl + "question/next"; - static String marathonSubmitAnswerUrl = marathonBaseUrl + "question/submit"; + static String marathonSubmitAnswerUrl = marathonBaseUrl + "question/submitquestion"; static String marathonQualifiersUrl = marathonBaseUrl + "winner/getWinner/"; static String marathonSelectedWinner = marathonBaseUrl + "winner/getSelectedWinner/"; diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 2229b3b..1d28232 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -495,5 +495,6 @@ abstract class LocaleKeys { static const youWantToLeaveMarathon = 'youWantToLeaveMarathon'; static const ourSponsor = 'ourSponsor'; static const startingIn = 'startingIn'; + static const youAreOutOfContest = 'youAreOutOfContest'; } diff --git a/lib/models/marathon/question_model.dart b/lib/models/marathon/question_model.dart index 0bb42cd..4501947 100644 --- a/lib/models/marathon/question_model.dart +++ b/lib/models/marathon/question_model.dart @@ -14,6 +14,7 @@ class QuestionModel { String? gapText; String? gapImage; int? questOptionsLimit; + int? remainingParticipantCount; List? questionOptions; QuestionModel({ @@ -28,6 +29,7 @@ class QuestionModel { String? gapText, String? gapImage, int? questOptionsLimit, + int? remainingParticipantCount, List? questionOptions, }); @@ -43,6 +45,7 @@ class QuestionModel { gapText = json['gapText']; gapImage = json['gapImage']; questOptionsLimit = json['questOptionsLimit']; + remainingParticipantCount = json['remainingParticipantCount']; if (json['questionOptions'] != null) { questionOptions = []; json['questionOptions'].forEach((v) { @@ -64,6 +67,7 @@ class QuestionModel { data['gapText'] = gapText; data['gapImage'] = gapImage; data['questOptionsLimit'] = questOptionsLimit; + data['remainingParticipantCount'] = remainingParticipantCount; if (questionOptions != null) { data['questionOptions'] = questionOptions!.map((v) => v.toJson()).toList(); } diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 48270d7..9bd5bbb 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -1,15 +1,12 @@ import 'dart:async'; -import 'dart:convert'; import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.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/extensions/int_extensions.dart'; @@ -18,7 +15,6 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; -import 'package:mohem_flutter_app/ui/landing/itg/its_add_screen_video_image.dart'; import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart'; import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart'; import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart'; @@ -321,9 +317,11 @@ class _DashboardScreenState extends State { ), ], ).paddingOnly(left: 21, right: 21, top: 7), - context.watch().isLoading ? MarathonBannerShimmer().paddingAll(20) : MarathonBanner().paddingAll(20), + context.watch().isLoading + ? const MarathonBannerShimmer().paddingAll(20) + : MarathonBanner(isMarathonUpcoming: context.watch().isUpComingMarathon).paddingAll(20), ServicesWidget(), - // 8.height, + 8.height, Container( width: double.infinity, padding: const EdgeInsets.only(top: 31), diff --git a/lib/ui/marathon/marathon_provider.dart b/lib/ui/marathon/marathon_provider.dart index 46149a4..1cf8efd 100644 --- a/lib/ui/marathon/marathon_provider.dart +++ b/lib/ui/marathon/marathon_provider.dart @@ -13,7 +13,7 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; import 'package:video_player/video_player.dart'; class MarathonProvider extends ChangeNotifier { - // VARIABLES + //****************VARIABLES********** final AppinioSwiperController swiperController = AppinioSwiperController(); @@ -24,9 +24,7 @@ class MarathonProvider extends ChangeNotifier { QuestionCardStatus questionCardStatus = QuestionCardStatus.question; int? selectedOptionIndex; - int currentQuestionTime = 0; - int totalSecondsToWaitForWinner = 30; - int totalSecondsToWaitForMarathon = 20; + String? selectedOptionId; int totalQualifiers = 0; bool _isLoading = false; @@ -38,6 +36,15 @@ class MarathonProvider extends ChangeNotifier { notifyListeners(); } + bool _isUpComingMarathon = true; + + bool get isUpComingMarathon => _isUpComingMarathon; + + set isUpComingMarathon(bool value) { + _isUpComingMarathon = value; + notifyListeners(); + } + bool _itsMarathonTime = false; bool get itsMarathonTime => _itsMarathonTime; @@ -72,7 +79,7 @@ class MarathonProvider extends ChangeNotifier { notifyListeners(); } - int _totalMarathoners = 23; + int _totalMarathoners = 0; int get totalMarathoners => _totalMarathoners; @@ -81,7 +88,7 @@ class MarathonProvider extends ChangeNotifier { notifyListeners(); } - //VIDEO PLAYER + //****************SPONSOR VIDEO PLAYER********** late VideoPlayerController videoController; @@ -101,6 +108,8 @@ class MarathonProvider extends ChangeNotifier { notifyListeners(); } + //****************TIMERS********** + int totalSponsorVideoSeconds = 0; 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) {}); void startTimerToMarathon(BuildContext context) { @@ -140,42 +148,123 @@ class MarathonProvider extends ChangeNotifier { ); } - void populateQuestionStatusesList() { - if (marathonDetailModel.totalQuestions != null) { - for (int i = 0; i < marathonDetailModel.totalQuestions! - 1; i++) { - answerStatusesList.add(QuestionCardStatus.question); - } - notifyListeners(); - } + int totalCurrentQuestionTime = 0; + int currentGapTime = 0; + Timer timerForQuestion = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); + + void startTimerForQuestion() { + 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) { - answerStatusesList[currentQuestionNumber - 1] = status; - 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 == 0) { + timer.cancel(); + updateQuestionCardStatus(QuestionCardStatus.winnerFound); + return; + } else { + totalSecondsToWaitForWinner--; + } + + notifyListeners(); + }, + ); + } + + //****************FUNCTIONS********* + + Future 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 callNextQuestionApi() async { if (currentQuestionNumber < marathonDetailModel.totalQuestions!) { if (currentQuestionNumber == 0) { + currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!))!; if (Utils.isLoading) { Utils.hideLoading(AppRoutes.navigatorKey.currentContext!); } - startTimerForQuestion(AppRoutes.navigatorKey.currentContext!); + startTimerForQuestion(); + updateCardData(); + Navigator.pushReplacementNamed(AppRoutes.navigatorKey.currentContext!, AppRoutes.marathonScreen); + } else { + currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: currentQuestion.id, marathonId: marathonDetailModel.id!))!; } - if (currentQuestionNumber > 0) { - swipeCardLeft(); + notifyListeners(); + } + } + + 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(); } } + void updateAnswerStatusesList(QuestionCardStatus status) { + answerStatusesList[currentQuestionNumber - 1] = status; + notifyListeners(); + } + void addItemToList(CardContent value) { cardContentList.add(value); 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() { swiperController.swipeLeft(); notifyListeners(); @@ -289,7 +327,7 @@ class MarathonProvider extends ChangeNotifier { timerForWinnerSelection.cancel(); timerForQuestion.cancel(); _isMarathonCompleted = false; - currentQuestionTime = 0; + totalCurrentQuestionTime = 0; currentQuestion = QuestionModel(); notifyListeners(); @@ -305,6 +343,11 @@ class MarathonProvider extends ChangeNotifier { notifyListeners(); await MarathonApiClient().getMarathonToken().whenComplete(() async { marathonDetailModel = await MarathonApiClient().getMarathonDetails(); + if (marathonDetailModel.id == null) { + isUpComingMarathon = false; + notifyListeners(); + return; + } populateQuestionStatusesList(); isLoading = false; notifyListeners(); @@ -334,7 +377,17 @@ class MarathonProvider extends ChangeNotifier { Navigator.pushNamed(context, AppRoutes.marathonSponsorVideoScreen); }); } 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()); + } } } } diff --git a/lib/ui/marathon/marathon_screen.dart b/lib/ui/marathon/marathon_screen.dart index 1feee8e..e14f8c9 100644 --- a/lib/ui/marathon/marathon_screen.dart +++ b/lib/ui/marathon/marathon_screen.dart @@ -83,8 +83,8 @@ class MarathonScreen extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - LocaleKeys.sponsoredBy.tr().toText14(color: MyColors.grey77Color), - (AppState().isArabic(context) ? provider.marathonDetailModel.sponsors!.first.nameEn ?? "" : provider.marathonDetailModel.sponsors!.first.nameAr ?? "").toText14( + "${LocaleKeys.sponsoredBy.tr()} ".toText14(color: MyColors.grey77Color), + (AppState().isArabic(context) ? provider.marathonDetailModel.sponsors!.first.nameAr ?? "" : provider.marathonDetailModel.sponsors!.first.nameEn ?? "").toText14( color: MyColors.darkTextColor, isBold: true, ), @@ -103,7 +103,7 @@ class MarathonScreen extends StatelessWidget { ], ], ), - ).paddingOnly(left: 21, right: 21); + ); } Widget getNameContainer(BuildContext context) { @@ -129,14 +129,18 @@ class MarathonScreen extends StatelessWidget { @override Widget build(BuildContext context) { MarathonProvider provider = context.watch(); - return WillPopScope( child: Scaffold( - appBar: AppBarWidget(context, title: LocaleKeys.brainMarathon.tr(), onHomeTapped: () { - Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); - }, onBackTapped: () { - Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); - }), + appBar: AppBarWidget( + context, + title: LocaleKeys.brainMarathon.tr(), + onHomeTapped: () { + Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); + }, + onBackTapped: () { + Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); + }, + ), body: SingleChildScrollView( child: Column( children: [ @@ -151,40 +155,36 @@ class MarathonScreen extends StatelessWidget { if (provider.questionCardStatus == QuestionCardStatus.findingWinner) ...[ getNameContainer(context), ], - if (provider.questionCardStatus == QuestionCardStatus.winnerFound) ...[ - getWinnerWidget(context, provider: provider), - ] else ...[ - QuestionCardBuilder( - onQuestion: (BuildContext context) => QuestionCard(provider: provider), - onCompleted: (BuildContext context) => CustomStatusWidget( - asset: Lottie.asset(MyLottieConsts.allQuestions, height: 200), - title: LocaleKeys.congrats.tr().toText22(color: MyColors.greenColor), - subTitle: LocaleKeys.allQuestionsCorrect.toText18(color: MyColors.darkTextColor, isCentered: true), - ), - onCorrectAnswer: (BuildContext context) => CustomStatusWidget( - asset: getSuccessWidget(gapType: provider.currentQuestion.gapType, gapImage: provider.currentQuestion.gapImage, gapText: provider.currentQuestion.gapText), - title: LocaleKeys.congrats.tr().toText22(color: MyColors.greenColor), - subTitle: LocaleKeys.yourAnswerCorrect.toText18(color: MyColors.darkTextColor, isCentered: true), - ), - onWinner: (BuildContext context) => QuestionCard(provider: provider), - onWrongAnswer: (BuildContext context) => CustomStatusWidget( - asset: Image.asset(MyLottieConsts.wrongAnswerGif, height: 200), - title: LocaleKeys.oops.tr().toText22(color: MyColors.redColor), - subTitle: LocaleKeys.wrongAnswer.tr().toText18(color: MyColors.darkTextColor, isCentered: true), - ), - onSkippedAnswer: (BuildContext context) => CustomStatusWidget( - asset: Image.asset(MyLottieConsts.wrongAnswerGif, height: 200), - title: LocaleKeys.oops.tr().toText22(color: MyColors.redColor), - subTitle: LocaleKeys.youMissedTheQuestion.tr().toText18(color: MyColors.darkTextColor, isCentered: true), - ), - onFindingWinner: (BuildContext context) => CustomStatusWidget( - asset: Lottie.asset(MyLottieConsts.winnerLottie, height: 168), - title: LocaleKeys.fingersCrossed.tr().toText22(color: MyColors.greenColor), - subTitle: LocaleKeys.winnerSelectedRandomly.tr().toText18(color: MyColors.darkTextColor, isCentered: true), - ), - questionCardStatus: provider.questionCardStatus, - ).paddingOnly(top: 12, left: 21, right: 21), - ], + QuestionCardBuilder( + onQuestion: (BuildContext context) => QuestionCard(provider: provider), + onCompleted: (BuildContext context) => CustomStatusWidget( + asset: Lottie.asset(MyLottieConsts.allQuestions, height: 200), + title: LocaleKeys.congrats.tr().toText22(color: MyColors.greenColor), + subTitle: LocaleKeys.allQuestionsCorrect.toText18(color: MyColors.darkTextColor, isCentered: true), + ), + onCorrectAnswer: (BuildContext context) => CustomStatusWidget( + asset: getSuccessWidget(gapType: provider.currentQuestion.gapType, gapImage: provider.currentQuestion.gapImage, gapText: provider.currentQuestion.gapText), + title: LocaleKeys.congrats.tr().toText22(color: MyColors.greenColor), + subTitle: LocaleKeys.yourAnswerCorrect.toText18(color: MyColors.darkTextColor, isCentered: true), + ), + onWinner: (BuildContext context) => getWinnerWidget(context, provider: provider), + onWrongAnswer: (BuildContext context) => CustomStatusWidget( + asset: Image.asset(MyLottieConsts.wrongAnswerGif, height: 200), + title: LocaleKeys.oops.tr().toText22(color: MyColors.redColor), + subTitle: LocaleKeys.wrongAnswer.tr().toText18(color: MyColors.darkTextColor, isCentered: true), + ), + onSkippedAnswer: (BuildContext context) => CustomStatusWidget( + asset: Image.asset(MyLottieConsts.wrongAnswerGif, height: 200), + title: LocaleKeys.oops.tr().toText22(color: MyColors.redColor), + subTitle: LocaleKeys.youMissedTheQuestion.tr().toText18(color: MyColors.darkTextColor, isCentered: true), + ), + onFindingWinner: (BuildContext context) => CustomStatusWidget( + asset: Lottie.asset(MyLottieConsts.winnerLottie, height: 168), + title: LocaleKeys.fingersCrossed.tr().toText22(color: MyColors.greenColor), + subTitle: LocaleKeys.winnerSelectedRandomly.tr().toText18(color: MyColors.darkTextColor, isCentered: true), + ), + questionCardStatus: provider.questionCardStatus, + ).paddingOnly(top: 12, left: 21, right: 21), ], ), ), diff --git a/lib/ui/marathon/marathon_waiting_screen.dart b/lib/ui/marathon/marathon_waiting_screen.dart index 9f52bf6..27f0c08 100644 --- a/lib/ui/marathon/marathon_waiting_screen.dart +++ b/lib/ui/marathon/marathon_waiting_screen.dart @@ -47,8 +47,8 @@ class MarathonWaitingScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ LocaleKeys.startingIn.tr().toText16(), - "00:${provider.currentQuestionTime < 10 ? "0${provider.currentQuestionTime}" : provider.currentQuestionTime}" - .toText18(color: provider.currentQuestionTime < 5 ? MyColors.redColor : MyColors.black), + "00:${provider.totalSecondsToWaitForMarathon < 10 ? "0${provider.totalSecondsToWaitForMarathon}" : provider.totalSecondsToWaitForMarathon}" + .toText18(color: provider.totalSecondsToWaitForMarathon < 5 ? MyColors.redColor : MyColors.black), ], ), ), diff --git a/lib/ui/marathon/widgets/marathon_banner.dart b/lib/ui/marathon/widgets/marathon_banner.dart index e711319..d805362 100644 --- a/lib/ui/marathon/widgets/marathon_banner.dart +++ b/lib/ui/marathon/widgets/marathon_banner.dart @@ -16,7 +16,9 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/countdown_timer.dart'; import 'package:provider/provider.dart'; class MarathonBanner extends StatelessWidget { - const MarathonBanner({Key? key}) : super(key: key); + final bool isMarathonUpcoming; + + const MarathonBanner({Key? key, required this.isMarathonUpcoming}) : super(key: key); @override Widget build(BuildContext context) { @@ -76,7 +78,7 @@ class MarathonBanner extends StatelessWidget { height: double.infinity, ), ), - Expanded( + Expanded( flex: AppState().isArabic(context) ? 4 : 5, child: SizedBox( width: double.infinity, diff --git a/lib/ui/marathon/widgets/marathon_progress_container.dart b/lib/ui/marathon/widgets/marathon_progress_container.dart index 4f76301..c0dae6c 100644 --- a/lib/ui/marathon/widgets/marathon_progress_container.dart +++ b/lib/ui/marathon/widgets/marathon_progress_container.dart @@ -32,8 +32,10 @@ class MarathonProgressContainer extends StatelessWidget { child: "${provider.currentQuestionNumber.toString()} / ${provider.marathonDetailModel.totalQuestions.toString()} ${LocaleKeys.question.tr()}".toText12(color: MyColors.white), ), "${provider.totalMarathoners} ${LocaleKeys.marathoners.tr()}".toText14(), - "00:${provider.currentQuestionTime < 10 ? "0${provider.currentQuestionTime}" : provider.currentQuestionTime}" - .toText18(color: provider.currentQuestionTime < 5 ? MyColors.redColor : MyColors.black), + provider.questionCardStatus == QuestionCardStatus.question + ? "00:${(provider.totalCurrentQuestionTime - provider.currentGapTime) < 10 ? "0${provider.totalCurrentQuestionTime - provider.currentGapTime}" : provider.totalCurrentQuestionTime - provider.currentGapTime}" + .toText18(color: provider.totalCurrentQuestionTime - provider.currentGapTime < 5 ? MyColors.redColor : MyColors.black) + : const SizedBox(), ], ), 12.height,