diff --git a/assets/lottie/congrats.gif b/assets/lottie/congrats.gif new file mode 100644 index 0000000..f4b0cdb Binary files /dev/null and b/assets/lottie/congrats.gif differ diff --git a/lib/api/marathon/marathon_api_client.dart b/lib/api/marathon/marathon_api_client.dart index 9fcdc68..859b23d 100644 --- a/lib/api/marathon/marathon_api_client.dart +++ b/lib/api/marathon/marathon_api_client.dart @@ -1,14 +1,19 @@ import 'dart:convert'; +import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:logger/logger.dart' as L; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.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/models/marathon/marathon_generic_model.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/models/marathon/winner_model.dart'; +import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; +import 'package:provider/provider.dart'; import 'package:signalr_netcore/hub_connection.dart'; class MarathonApiClient { @@ -41,6 +46,17 @@ class MarathonApiClient { } } + + // Future getGetMenuEntries() async { + // String url = "${ApiConsts.erpRest}GET_MENU_ENTRIES"; + // Map postParams = {"P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E"}; + // postParams.addAll(AppState().postParamsJson); + // return await ApiClient().postJsonForObject((json) { + // GenericResponseModel responseData = GenericResponseModel.fromJson(json); + // return responseData; + // }, url, postParams); + // } + Future getProjectId() async { Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonProjectGetUrl, {}, token: AppState().getMarathonToken ?? await getMarathonToken()); @@ -123,12 +139,53 @@ class MarathonApiClient { var json = jsonDecode(response.body); - logger.i("json in NextQuestion: $json"); - var data = json["data"]; + MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); + + if (marathonModel.statusCode == 404) { + Utils.confirmDialog( + AppRoutes.navigatorKey.currentContext, + marathonModel.message!, + onTap: () { + AppRoutes.navigatorKey.currentContext!.read().resetValues(); + Navigator.of( + AppRoutes.navigatorKey.currentContext!, + ).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + }, + ); + return null; + } + + if (marathonModel.statusCode == 208) { + Utils.confirmDialog( + AppRoutes.navigatorKey.currentContext, + marathonModel.message!, + onTap: () { + AppRoutes.navigatorKey.currentContext!.read().resetValues(); + Navigator.of( + AppRoutes.navigatorKey.currentContext!, + ).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + }, + ); + return null; + } + + if (marathonModel.statusCode == 204) { + Utils.confirmDialog( + AppRoutes.navigatorKey.currentContext, + marathonModel.message!, + onTap: () { + AppRoutes.navigatorKey.currentContext!.read().resetValues(); + Navigator.of( + AppRoutes.navigatorKey.currentContext!, + ).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + }, + ); + return null; + } - if (data != null) { - QuestionModel newQuestion = QuestionModel.fromJson(data); + if (marathonModel.data != null && marathonModel.isSuccessful == true) { + QuestionModel newQuestion = QuestionModel.fromJson(marathonModel.data); return newQuestion; } else { return null; @@ -136,7 +193,7 @@ class MarathonApiClient { } Future submitSelectedOption({required String marathonId, required String? questionId, required String? selectedAnswerId}) async { - Map jsonObject = {"marathonId": marathonId, "questionId": questionId, "selectedOptionId" : selectedAnswerId}; + Map jsonObject = {"marathonId": marathonId, "questionId": questionId, "selectedOptionId": selectedAnswerId}; Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonSubmitAnswerUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index 57bb888..473d57e 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -113,7 +113,7 @@ class Utils { if (!AppState().isAuthenticated) { showDialog( context: cxt, - builder: (cxt) => ConfirmDialog( + builder: (BuildContext cxt) => ConfirmDialog( message: errorMessage, onTap: () { Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route route) => false); @@ -130,11 +130,22 @@ class Utils { } } - static void confirmDialog(cxt, String message) { + static Future showErrorDialog({required BuildContext context, required VoidCallback onOkTapped, required String message}) async { + return showDialog( + context: context, + builder: (BuildContext context) => ConfirmDialog( + message: message, + onTap: onOkTapped, + ), + ); + } + + static void confirmDialog(cxt, String message, {VoidCallback? onTap}) { showDialog( context: cxt, - builder: (cxt) => ConfirmDialog( + builder: (BuildContext cxt) => ConfirmDialog( message: message, + onTap: onTap, ), ); } @@ -317,13 +328,13 @@ class Utils { if (!Platform.isIOS) { await showCupertinoModalPopup( context: context, - builder: (cxt) => Container( + builder: (BuildContext cxt) => Container( height: 250, color: Colors.white, child: CupertinoDatePicker( backgroundColor: Colors.white, mode: CupertinoDatePickerMode.date, - onDateTimeChanged: (value) { + onDateTimeChanged: (DateTime value) { if (value != null && value != selectedDate) { selectedDate = value; } @@ -343,7 +354,7 @@ class Utils { static void readNFc({required Function(String) onRead}) { NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { - var f; + MifareUltralight f; if (Platform.isAndroid) { f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); } else { diff --git a/lib/ui/marathon/marathon_provider.dart b/lib/ui/marathon/marathon_provider.dart index 128b634..f87696d 100644 --- a/lib/ui/marathon/marathon_provider.dart +++ b/lib/ui/marathon/marathon_provider.dart @@ -31,7 +31,6 @@ class MarathonProvider extends ChangeNotifier { String? selectedOptionId; int? totalQualifiers; - //TODO: THIS BUG NEEDS TO BE FIXED. NOT DONE YET String? gapTimeImage; String? gapTimeText; int? gapTimeType; @@ -173,7 +172,7 @@ class MarathonProvider extends ChangeNotifier { 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 + // This 2 is just to show the color of answer tile for 1 and then update card status if (totalCurrentQuestionTime - currentGapTime == 1) { getCorrectAnswerAndUpdateAnswerColor(); } @@ -366,6 +365,8 @@ class MarathonProvider extends ChangeNotifier { } } + void resetProgressColorValues() {} + void resetValues() async { _currentQuestionNumber = 0; cardContentList.clear(); @@ -378,9 +379,14 @@ class MarathonProvider extends ChangeNotifier { totalCurrentQuestionTime = 0; sponsorsSecondsCounter = 0; totalSponsorVideoSeconds = 0; - totalSecondsToWaitForMarathon = 20; + totalSecondsToWaitForMarathon = 0; currentGapTime = 0; currentQuestion = QuestionModel(); + if (answerStatusesList.isNotEmpty) { + for (int i = 0; i < answerStatusesList.length; i++) { + answerStatusesList[i] = QuestionCardStatus.question; + } + } notifyListeners(); } diff --git a/lib/ui/marathon/marathon_screen.dart b/lib/ui/marathon/marathon_screen.dart index c032823..a64b97a 100644 --- a/lib/ui/marathon/marathon_screen.dart +++ b/lib/ui/marathon/marathon_screen.dart @@ -123,7 +123,7 @@ class MarathonScreen extends StatelessWidget { width: 150, fit: BoxFit.contain, errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { - return const Center(); + return Image.asset("assets/images/logos/main_mohemm_logo.png", height: 50, width: 150); }, ) ], diff --git a/lib/ui/marathon/widgets/marathon_banner.dart b/lib/ui/marathon/widgets/marathon_banner.dart index 0487c74..d75322b 100644 --- a/lib/ui/marathon/widgets/marathon_banner.dart +++ b/lib/ui/marathon/widgets/marathon_banner.dart @@ -357,8 +357,7 @@ class MarathonBanner extends StatelessWidget { ], ).onPress(() async { int remainingTimeInMinutes = DateTime.parse(provider.marathonDetailModel.startTime!).difference(DateTime.now()).inMinutes; - - if (remainingTimeInMinutes > 2) { + if (remainingTimeInMinutes > 2 && provider.marathonDetailModel.sponsors != null && provider.marathonDetailModel.sponsors!.isNotEmpty) { Utils.showLoading(context); try { await provider.initializeVideoPlayer().then((_) { diff --git a/lib/ui/marathon/widgets/marathon_details_card.dart b/lib/ui/marathon/widgets/marathon_details_card.dart index e8b37a0..3b686ef 100644 --- a/lib/ui/marathon/widgets/marathon_details_card.dart +++ b/lib/ui/marathon/widgets/marathon_details_card.dart @@ -36,9 +36,9 @@ class MarathonDetailsCard extends StatelessWidget { ) ], ), - if (provider.marathonDetailModel.sponsors != null) ...[ + if (provider.marathonDetailModel.sponsors != null && provider.marathonDetailModel.sponsors!.isNotEmpty) ...[ 5.height, - provider.marathonDetailModel.sponsors?.first.sponsorPrizes != null + provider.marathonDetailModel.sponsors!.first.sponsorPrizes != null ? Row( children: [ "${LocaleKeys.prize.tr()} ".toText16(color: MyColors.grey77Color, isBold: true), @@ -64,7 +64,7 @@ class MarathonDetailsCard extends StatelessWidget { width: 150, fit: BoxFit.contain, errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { - return const Center(); + return Image.asset("assets/images/logos/main_mohemm_logo.png", height: 50, width: 150); }, ) ], diff --git a/lib/ui/marathon/widgets/question_card.dart b/lib/ui/marathon/widgets/question_card.dart index 5f419c5..6fcb5db 100644 --- a/lib/ui/marathon/widgets/question_card.dart +++ b/lib/ui/marathon/widgets/question_card.dart @@ -126,7 +126,11 @@ class AnswerContent extends StatelessWidget { return AnswerTileForText( index: index, onAnswerTapped: () { - provider.updateCurrentQuestionOptionStatus(QuestionsOptionStatus.selected, index); + if (provider.totalCurrentQuestionTime - provider.currentGapTime <= 1) { + null; + } else { + provider.updateCurrentQuestionOptionStatus(QuestionsOptionStatus.selected, index); + } }, ); },