diff --git a/lib/api/marathon/marathon_api_client.dart b/lib/api/marathon/marathon_api_client.dart index 132ec30..a9266d2 100644 --- a/lib/api/marathon/marathon_api_client.dart +++ b/lib/api/marathon/marathon_api_client.dart @@ -8,6 +8,7 @@ import 'package:mohem_flutter_app/classes/consts.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:signalr_netcore/hub_connection.dart'; class MarathonApiClient { @@ -19,6 +20,7 @@ class MarathonApiClient { String employeeSession = AppState().postParamsObject?.pSessionId.toString() ?? ""; Map jsonObject = {"userName": employeeUserName, "password": employeeSession}; + Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonParticipantLoginUrl, jsonObject); var json = jsonDecode(response.body); @@ -80,10 +82,11 @@ class MarathonApiClient { return marathonDetailModel; } - Future joinMarathonAsParticipant() async { + Future joinMarathonAsParticipant() async { Map jsonObject = { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER ?? "", - "employeeName": AppState().memberInformationList!.eMPLOYEENAME ?? "", + "employeeNameAr": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "", + "employeeNameEn": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "", "marathonId": AppState().getMarathonProjectId!, }; @@ -95,31 +98,33 @@ class MarathonApiClient { if (marathonModel.statusCode == 208) { // means participant is already in the marathon i.e already joined - return true; + return marathonModel.data["remainingTime"]; } if (marathonModel.statusCode == 200) { if (marathonModel.data != null && marathonModel.isSuccessful == true) { logger.i("joinMarathonAsParticipant: ${marathonModel.data}"); - return true; + return marathonModel.data["remainingTime"]; } else { - return false; + return null; } } else { - return false; + return null; } } Future getNextQuestion({required String? questionId, required String marathonId}) async { Map jsonObject = { - "questionId": questionId, + "previousQuestionId": questionId, "marathonId": marathonId, - }; + }; Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonNextQuestionUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); var json = jsonDecode(response.body); + + logger.i("json in NextQuestion: $json"); var data = json["data"]; if (data != null) { @@ -130,13 +135,13 @@ class MarathonApiClient { } } - Future submitSelectedOption({required String? selectedAnswerId}) async { - Map jsonObject = {"selectedOptionId": selectedAnswerId}; + Future submitSelectedOption({required String marathonId, required String? questionId, required String? selectedAnswerId}) async { + Map jsonObject = {"marathonId": marathonId, "questionId": questionId, "selectedOptionId" : selectedAnswerId}; Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonSubmitAnswerUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); var json = jsonDecode(response.body); - logger.i("json: $json"); + logger.i("json in submitSelectedOption : $json"); MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); @@ -147,6 +152,42 @@ class MarathonApiClient { return marathonModel.isSuccessful!; } + Future getQualifiers({required String marathonId}) async { + Map params = {"marathonId": marathonId}; + Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonQualifiersUrl, queryParameters: params, token: AppState().getMarathonToken ?? await getMarathonToken()); + + var json = jsonDecode(response.body); + logger.i("json in getQualifiers: $json"); + + MarathonGenericModel marathonGenericModel = MarathonGenericModel.fromJson(json); + + if (marathonGenericModel.isSuccessful == true && marathonGenericModel.statusCode == 200 && marathonGenericModel.data != null) { + return marathonGenericModel.data["winnerCount"]; + } + return null; + } + + Future?> getSelectedWinner({required String marathonId}) async { + Map params = {"marathonId": marathonId}; + Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonSelectedWinner, queryParameters: params, token: AppState().getMarathonToken ?? await getMarathonToken()); + + var json = jsonDecode(response.body); + logger.i("json in getSelectedWinner: $json"); + + MarathonGenericModel marathonGenericModel = MarathonGenericModel.fromJson(json); + + if (marathonGenericModel.isSuccessful == true && marathonGenericModel.statusCode == 200 && marathonGenericModel.data != null) { + List winners = []; + List data = marathonGenericModel.data as List; + + for (Map winner in data) { + winners.add(WinnerModel.fromJson(winner)); + } + return winners; + } + return null; + } + // 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 1230c8b..7ee0c23 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -25,21 +25,21 @@ class ApiConsts { static String chatFavUser = chatServerBaseApiUrl + "FavUser/"; static String chatUserImages = chatServerBaseUrl + "empservice/api/employee/"; - //Brain Marathon Constants static String marathonBaseUrl = "https://marathoon.com/service/api/"; 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 marathonJoinParticipantUrl = marathonBaseUrl + "participant/join"; static String marathonNextQuestionUrl = marathonBaseUrl + "question/next"; static String marathonSubmitAnswerUrl = marathonBaseUrl + "question/submit"; static String marathonQualifiersUrl = marathonBaseUrl + "winner/getWinner/"; static String marathonSelectedWinner = marathonBaseUrl + "winner/getSelectedWinner/"; //DummyCards for the UI - static CardContent dummyQuestion = const CardContent(); + + static int tabletMinLength = 500; } class SharedPrefsConsts { diff --git a/lib/config/routes.dart b/lib/config/routes.dart index d1b6b08..af6af26 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -22,7 +22,6 @@ import 'package:mohem_flutter_app/ui/marathon/marathon_intro_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_sponsor_video_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_waiting_screen.dart'; -import 'package:mohem_flutter_app/ui/marathon/marathon_winner_selection.dart'; import 'package:mohem_flutter_app/ui/marathon/winner_screen.dart'; import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart'; import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart'; @@ -186,7 +185,6 @@ class AppRoutes { //Marathon static const String marathonIntroScreen = "/marathonIntroScreen"; static const String marathonScreen = "/marathonScreen"; - static const String marathonWinnerSelection = "/marathonWinnerSelection"; static const String marathonWinnerScreen = "/marathonWinnerScreen"; static const String marathonSponsorVideoScreen = "/marathonSponsorVideoScreen"; static const String marathonWaitingScreen = "/marathonWaitingScreen"; @@ -296,7 +294,6 @@ class AppRoutes { // Marathon marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(), marathonScreen: (BuildContext context) => MarathonScreen(), - marathonWinnerSelection: (BuildContext context) => MarathonWinnerSelection(), marathonWinnerScreen: (BuildContext context) => WinnerScreen(), marathonSponsorVideoScreen: (BuildContext context) => const SponsorVideoScreen(), marathonWaitingScreen: (BuildContext context) => const MarathonWaitingScreen(), diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 3261149..494daaf 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -140,8 +140,9 @@ extension EmailValidator on String { style: TextStyle(color: color ?? MyColors.grey3AColor, fontSize: 21, letterSpacing: -0.84, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600)), ); - Widget toText22({Color? color, bool isBold = false}) => Text( + Widget toText22({Color? color, bool isBold = false, bool isCentered = false}) => Text( this, + textAlign: isCentered ? TextAlign.center : null, style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); @@ -151,12 +152,13 @@ extension EmailValidator on String { ); Widget toText30({Color? color, bool isBold = false}) => Text( - this, - style: TextStyle(height: 20 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.2, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), - ); + this, + style: TextStyle(height: 20 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.2, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); - Widget toText32({Color? color, bool isBold = false}) => Text( + Widget toText32({Color? color, bool isBold = false, bool isCentered = false}) => Text( this, + textAlign: isCentered ? TextAlign.center : null, style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index a54ff37..8a2113d 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -516,7 +516,16 @@ class CodegenLoader extends AssetLoader{ "codeExpire": "انتهت صلاحية رمز التحقق", "typeheretoreply": "اكتب هنا للرد", "favorite": "مفضلتي", - "searchfromchat": "البحث من الدردشة" + "searchfromchat": "البحث من الدردشة", + "yourAnswerCorrect": "إجابتك صحيحة", + "youMissedTheQuestion": "نفد منك الوقت. أنت خارج اللعبة. لكن يمكنك الاستمرار وكمشاهد.", + "wrongAnswer": "إجابتك غير صحيحة. أنت خارج اللعبة. لكن يمكنك الاستمرار وكمشاهد.", + "oops": "أوه!!!", + "winner": "الفائز", + "youWantToLeaveMarathon": "هل أنت متأكد أنك تريد العودة؟ سوف تخرج من المسابقة.", + "ourSponsor": "راعينا:", + "startingIn": "يبدأ في", + "youAreOutOfContest": "أنت خارج المسابقة." }; static const Map en_US = { "mohemm": "Mohemm", @@ -1020,7 +1029,16 @@ static const Map en_US = { "allQuestionsCorrect": "You have answered all questions correct", "typeheretoreply": "Type here to reply", "favorite": "My Favorites", - "searchfromchat": "Search from chat" + "searchfromchat": "Search from chat", + "yourAnswerCorrect": "Your answer is correct", + "youMissedTheQuestion": "You ran out of time. You are out of the game. But you can continue and as a viewer.", + "wrongAnswer": "Your answer is Incorrect. You are out of the game. But you can continue and as a viewer.", + "oops": "Ooopsss!!!!", + "winner": "WINNER", + "youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.", + "ourSponsor": "Our Sponsor:", + "startingIn": "Starting in", + "youAreOutOfContest": "You are out of the contest." }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart deleted file mode 100644 index 1d28232..0000000 --- a/lib/generated/locale_keys.g.dart +++ /dev/null @@ -1,500 +0,0 @@ -// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart - -abstract class LocaleKeys { - static const mohemm = 'mohemm'; - static const english = 'english'; - static const arabic = 'arabic'; - static const login = 'login'; - static const pleaseEnterLoginDetails = 'pleaseEnterLoginDetails'; - static const username = 'username'; - static const password = 'password'; - static const welcomeBack = 'welcomeBack'; - static const wouldYouLikeToLoginWithCurrentUsername = 'wouldYouLikeToLoginWithCurrentUsername'; - static const lastLoginDetails = 'lastLoginDetails'; - static const verificationType = 'verificationType'; - static const pleaseVerify = 'pleaseVerify'; - static const pleaseVerifyForBio = 'pleaseVerifyForBio'; - static const verifyThroughFace = 'verifyThroughFace'; - static const verifyThroughFingerprint = 'verifyThroughFingerprint'; - static const verifyThroughSMS = 'verifyThroughSMS'; - static const verifyThroughWhatsapp = 'verifyThroughWhatsapp'; - static const useAnotherAccount = 'useAnotherAccount'; - static const pleaseEnterTheVerificationCodeSentTo = 'pleaseEnterTheVerificationCodeSentTo'; - static const theVerificationCodeWillExpireIn = 'theVerificationCodeWillExpireIn'; - static const goodMorning = 'goodMorning'; - static const markAttendance = 'markAttendance'; - static const timeLeftToday = 'timeLeftToday'; - static const checkIn = 'checkIn'; - static const workList = 'workList'; - static const leaveBalance = 'leaveBalance'; - static const missingSwipes = 'missingSwipes'; - static const ticketBalance = 'ticketBalance'; - static const services = 'services'; - static const viewAllServices = 'viewAllServices'; - static const monthlyAttendance = 'monthlyAttendance'; - static const vacationRule = 'vacationRule'; - static const vacationType = 'vacationType'; - static const startDateT = 'startDateT'; - static const endDateT = 'endDateT'; - static const workFromHome = 'workFromHome'; - static const ticketRequest = 'ticketRequest'; - static const viewAllOffers = 'viewAllOffers'; - static const offers = 'offers'; - static const discounts = 'discounts'; - static const newString = 'newString'; - static const setTheNewPassword = 'setTheNewPassword'; - static const typeYourNewPasswordBelow = 'typeYourNewPasswordBelow'; - static const confirmPassword = 'confirmPassword'; - static const update = 'update'; - static const title = 'title'; - static const home = 'home'; - static const mySalary = 'mySalary'; - static const createRequest = 'createRequest'; - static const forgotPassword = 'forgotPassword'; - static const employeeId = 'employeeId'; - static const loginCodeWillSentToMobileNumber = 'loginCodeWillSentToMobileNumber'; - static const changePassword = 'changePassword'; - static const ok = 'ok'; - static const confirm = 'confirm'; - static const passwordChangedSuccessfully = 'passwordChangedSuccessfully'; - static const itemsForSale = 'itemsForSale'; - static const attendanceDetails = 'attendanceDetails'; - static const order = 'order'; - static const earlyOut = 'earlyOut'; - static const shortage = 'shortage'; - static const excess = 'excess'; - static const lateIn = 'lateIn'; - static const approvedCheckOut = 'approvedCheckOut'; - static const approvedCheckIn = 'approvedCheckIn'; - static const actualCheckOut = 'actualCheckOut'; - static const actualCheckIn = 'actualCheckIn'; - static const present = 'present'; - static const pres = 'pres'; - static const shiftTime = 'shiftTime'; - static const absent = 'absent'; - static const attendance = 'attendance'; - static const scheduleDays = 'scheduleDays'; - static const offDays = 'offDays'; - static const nonAnalyzed = 'nonAnalyzed'; - static const shortageHour = 'shortageHour'; - static const stats = 'stats'; - static const completed = 'completed'; - static const msg = 'msg'; - static const msg_named = 'msg_named'; - static const clickMe = 'clickMe'; - static const doNotUseRecentPassword = 'doNotUseRecentPassword'; - static const atLeastOneLowercase = 'atLeastOneLowercase'; - static const atLeastOneUppercase = 'atLeastOneUppercase'; - static const atLeastOneNumeric = 'atLeastOneNumeric'; - static const minimum8Characters = 'minimum8Characters'; - static const doNotAddRepeatingLetters = 'doNotAddRepeatingLetters'; - static const itShouldContainSpecialCharacter = 'itShouldContainSpecialCharacter'; - static const confirmPasswordMustMatch = 'confirmPasswordMustMatch'; - static const sms = 'sms'; - static const fingerPrint = 'fingerPrint'; - static const face = 'face'; - static const whatsapp = 'whatsapp'; - static const reject = 'reject'; - static const approve = 'approve'; - static const cancel = 'cancel'; - static const requestedItems = 'requestedItems'; - static const request = 'request'; - static const myRequest = 'myRequest'; - static const actions = 'actions'; - static const delegate = 'delegate'; - static const request_info = 'request_info'; - static const attachments = 'attachments'; - static const info = 'info'; - static const employeeNumber = 'employeeNumber'; - static const assignmentNumber = 'assignmentNumber'; - static const employeeName = 'employeeName'; - static const scheduleDate = 'scheduleDate'; - static const shiftType = 'shiftType'; - static const shift = 'shift'; - static const breakText = 'breakText'; - static const actualSwipeStart = 'actualSwipeStart'; - static const actualSwipeEnd = 'actualSwipeEnd'; - static const approvedSwipeStart = 'approvedSwipeStart'; - static const approvedSwipeStartReason = 'approvedSwipeStartReason'; - static const approvedSwipeEnd = 'approvedSwipeEnd'; - static const approvedSwipeEndReason = 'approvedSwipeEndReason'; - static const from = 'from'; - static const to = 'to'; - static const sent = 'sent'; - static const closed = 'closed'; - static const id = 'id'; - static const responder = 'responder'; - static const jobTitle = 'jobTitle'; - static const grade = 'grade'; - static const jobCategory = 'jobCategory'; - static const category = 'category'; - static const employeeEmailAddress = 'employeeEmailAddress'; - static const payrollBranch = 'payrollBranch'; - static const yourChangeHasBeenSavedSuccessfully = 'yourChangeHasBeenSavedSuccessfully'; - static const code = 'code'; - static const unit = 'unit'; - static const quantity = 'quantity'; - static const dateRequired = 'dateRequired'; - static const lineStatus = 'lineStatus'; - static const statusDate = 'statusDate'; - static const transactionType = 'transactionType'; - static const operatingUnit = 'operatingUnit'; - static const organizationCode = 'organizationCode'; - static const organization = 'organization'; - static const fromSubInventory = 'fromSubInventory'; - static const fromLocator = 'fromLocator'; - static const toSubInventory = 'toSubInventory'; - static const toLocator = 'toLocator'; - static const shipToLocator = 'shipToLocator'; - static const itemHistory = 'itemHistory'; - static const mfg = 'mfg'; - static const lineType = 'lineType'; - static const price = 'price'; - static const lineAmount = 'lineAmount'; - static const lineDiscount = 'lineDiscount'; - static const needByDate = 'needByDate'; - static const promisedDate = 'promisedDate'; - static const deliverToLocation = 'deliverToLocation'; - static const requisitionNumber = 'requisitionNumber'; - static const requester = 'requester'; - static const quotationAnalysis = 'quotationAnalysis'; - static const subject = 'subject'; - static const description = 'description'; - static const supplier = 'supplier'; - static const site = 'site'; - static const buyer = 'buyer'; - static const preparer = 'preparer'; - static const creationDate = 'creationDate'; - static const shipToLocation = 'shipToLocation'; - static const quotationNumber = 'quotationNumber'; - static const quotationDate = 'quotationDate'; - static const paymentTerms = 'paymentTerms'; - static const currency = 'currency'; - static const grossAmount = 'grossAmount'; - static const discountAmount = 'discountAmount'; - static const customDuty = 'customDuty'; - static const shipHandle = 'shipHandle'; - static const otherCharges = 'otherCharges'; - static const totalPOAmountWithVAT = 'totalPOAmountWithVAT'; - static const totalPOAmountInWords = 'totalPOAmountInWords'; - static const requestNumber = 'requestNumber'; - static const uom = 'uom'; - static const operatingCode = 'operatingCode'; - static const poNumber = 'poNumber'; - static const revision = 'revision'; - static const quantityOrdered = 'quantityOrdered'; - static const quantityReceived = 'quantityReceived'; - static const bonusQuantity = 'bonusQuantity'; - static const purchasePrice = 'purchasePrice'; - static const discountPer = 'discountPer'; - static const balanceQuantity = 'balanceQuantity'; - static const netPrice = 'netPrice'; - static const closureStatus = 'closureStatus'; - static const quotationNetPrice = 'quotationNetPrice'; - static const quotationUOM = 'quotationUOM'; - static const quotationQty = 'quotationQty'; - static const itemCode = 'itemCode'; - static const vendorName = 'vendorName'; - static const quotationMFGPartNumber = 'quotationMFGPartNumber'; - static const quotationDeliveryDate = 'quotationDeliveryDate'; - static const quotationBonusQuantity = 'quotationBonusQuantity'; - static const quotationLineTotal = 'quotationLineTotal'; - static const rfqUOM = 'rfqUOM'; - static const rfqQty = 'rfqQty'; - static const rfqNumber = 'rfqNumber'; - static const human = 'human'; - static const resources = 'resources'; - static const details = 'details'; - static const noDataAvailable = 'noDataAvailable'; - static const productName = 'productName'; - static const productDescription = 'productDescription'; - static const unitPrice = 'unitPrice'; - static const manufacturerName = 'manufacturerName'; - static const manufacturerPartName = 'manufacturerPartName'; - static const supplierName = 'supplierName'; - static const supplierContact = 'supplierContact'; - static const chargeToPatient = 'chargeToPatient'; - static const justification = 'justification'; - static const itemDescription = 'itemDescription'; - static const groupCode = 'groupCode'; - static const primaryUOM = 'primaryUOM'; - static const subgroupDescription = 'subgroupDescription'; - static const subgroupCode = 'subgroupCode'; - static const groupDescription = 'groupDescription'; - static const templateName = 'templateName'; - static const itemCreationStatus = 'itemCreationStatus'; - static const standardizationApprovalStatus = 'standardizationApprovalStatus'; - static const standardizationApprovalRejectionReason = 'standardizationApprovalRejectionReason'; - static const analyzedBy = 'analyzedBy'; - static const approvedDate = 'approvedDate'; - static const itemType = 'itemType'; - static const relatedTo = 'relatedTo'; - static const requestDate = 'requestDate'; - static const analyzedDate = 'analyzedDate'; - static const urgent = 'urgent'; - static const requestDetails = 'requestDetails'; - static const approvalLevel = 'approvalLevel'; - static const requesterDetails = 'requesterDetails'; - static const myAttendance = 'myAttendance'; - static const workOnBreak = 'workOnBreak'; - static const next = 'next'; - static const apply = 'apply'; - static const mobile = 'mobile'; - static const completingYear = 'completingYear'; - static const year = 'year'; - static const month = 'month'; - static const day = 'day'; - static const address = 'address'; - static const phoneNumber = 'phoneNumber'; - static const businessGroup = 'businessGroup'; - static const Payroll = 'Payroll'; - static const civilIdentityNumber = 'civilIdentityNumber'; - static const dateOfBirth = 'dateOfBirth'; - static const maritalStatus = 'maritalStatus '; - static const fullName = 'fullName'; - static const remove = 'remove'; - static const submit = 'submit'; - static const areYouSureYouWantToSubmit = 'areYouSureYouWantToSubmit'; - static const comments = 'comments'; - static const writeComment = 'writeComment'; - static const approversList = 'approversList'; - static const yourRequestHasBeenSubmittedForApprovals = 'yourRequestHasBeenSubmittedForApprovals'; - static const monthlyPaySlip = 'monthlyPaySlip'; - static const particular = 'particular'; - static const earnings = 'earnings'; - static const deductions = 'deductions'; - static const paymentMethodName = 'paymentMethodName'; - static const bankName = 'bankName'; - static const branchCode = 'branchCode'; - static const accountNo = 'accountNo'; - static const summaryOfInformation = 'summaryOfInformation'; - static const totalPayAmount = 'totalPayAmount'; - static const paymentInformation = 'paymentInformation'; - static const performance = 'performance'; - static const performanceEvaluation = 'performanceEvaluation'; - static const performanceEvaluationIn = 'performanceEvaluationIn'; - static const valuationIn = 'valuationIn'; - static const amount = 'amount'; - static const correctCurrentDatails = 'correctCurrentDatails'; - static const selectType = 'selectType'; - static const enterNewInfo = 'enterNewInfo'; - static const endDate = 'endDate'; - static const removeThisMember = 'removeThisMember'; - static const wantUpdateThisMember = 'wantUpdateThisMember '; - static const addNewFamilyMember = 'addNewFamilyMember'; - static const addRow = 'addRow'; - static const pleaseSelect = 'pleaseSelect'; - static const delete = 'delete'; - static const edit = 'edit'; - static const add = 'add'; - static const myProfile = 'myProfile'; - static const mowadhafhi = 'mowadhafhi'; - static const searchAnnouncements = 'searchAnnouncements'; - static const announcements = 'announcements'; - static const swipeRequest = 'swipeRequest'; - static const serviceType = 'serviceType'; - static const departmentName = 'departmentName'; - static const selectDepartment = 'selectDepartment'; - static const relatedSection = 'relatedSection'; - static const selectSection = 'selectSection'; - static const relatedTopic = 'relatedTopic'; - static const selectTopic = 'selectTopic'; - static const supportingDocument = 'supportingDocument'; - static const mowadhafhiRequest = 'mowadhafhiRequest'; - static const ticketReference = 'ticketReference'; - static const section = 'section'; - static const topic = 'topic'; - static const actionBy = 'actionBy'; - static const pending = 'pending'; - static const pendingTransactions = 'pendingTransactions'; - static const selectRequestType = 'selectRequestType'; - static const dateFrom = 'dateFrom'; - static const dateTo = 'dateTo'; - static const requestName = 'requestName'; - static const createdFor = 'createdFor'; - static const requestCreatedSuccessfully = 'requestCreatedSuccessfully'; - static const search = 'search'; - static const wantToReject = 'wantToReject'; - static const requestType = 'requestType'; - static const employeeDigitalID = 'employeeDigitalID'; - static const businessCard = 'businessCard'; - static const viewBusinessCard = 'viewBusinessCard'; - static const logout = 'logout'; - static const checkOut = 'checkOut'; - static const regular = 'regular'; - static const mark = 'mark'; - static const selectMethodOfAttendance = 'selectMethodOfAttendance'; - static const comeNearHMGWifi = 'comeNearHMGWifi'; - static const deliverNotificationToMeRegardless = 'deliverNotificationToMeRegardless'; - static const close = 'close'; - static const respond = 'respond'; - static const vacationRuleAdded = 'vacationRuleAdded'; - static const selectTypeT = 'selectTypeT'; - static const notification = 'notification'; - static const selectNotification = 'selectNotification'; - static const ifAllSelectedYouWillSkip = 'ifAllSelectedYouWillSkip'; - static const applyForVacationRule = 'applyForVacationRule'; - static const step1 = 'step1'; - static const step2 = 'step2'; - static const step3 = 'step3'; - static const message = 'message'; - static const writeAMessage = 'writeAMessage'; - static const notificationReassign = 'notificationReassign'; - static const selectEmployee = 'selectEmployee'; - static const searchEmployeeForReplacement = 'searchEmployeeForReplacement'; - static const searchForEmployee = 'searchForEmployee'; - static const pleaseSpecifyEndTime = 'pleaseSpecifyEndTime'; - static const pleaseSelectNotificationReassign = 'pleaseSelectNotificationReassign'; - static const pleaseSelectEmployeeForReplacement = 'pleaseSelectEmployeeForReplacement'; - static const pleaseSelectAction = 'pleaseSelectAction'; - static const pleaseSelectDate = 'pleaseSelectDate'; - static const todayAttendance = 'todayAttendance'; - static const viewAttendance = 'viewAttendance'; - static const teamMembers = 'teamMembers'; - static const profileDetails = 'profileDetails'; - static const noResultsFound = 'noResultsFound'; - static const searchBy = 'searchBy'; - static const myTeamMembers = 'myTeamMembers'; - static const save = 'save'; - static const TurnNotificationsFor = 'TurnNotificationsFor'; - static const worklistSettings = 'worklistSettings'; - static const absenceType = 'absenceType'; - static const absenceCategory = 'absenceCategory'; - static const days = 'days'; - static const hours = 'hours'; - static const approvalStatus = 'approvalStatus'; - static const absenceStatus = 'absenceStatus'; - static const subordinateLeave = 'subordinateLeave'; - static const numberDays = 'numberDays'; - static const poweredBy = 'poweredBy'; - static const cloudSolutions = 'cloudSolutions'; - static const selectTemplate = 'selectTemplate'; - static const myPostedAds = 'myPostedAds'; - static const browseCategories = 'browseCategories'; - static const searchItems = 'searchItems'; - static const offerAndDiscounts = 'offerAndDiscounts'; - static const offerValid = 'offerValid'; - static const offerExpired = 'offerExpired'; - static const whatAreYouOffering = 'whatAreYouOffering'; - static const selectCategory = 'selectCategory'; - static const inProgress = 'inProgress'; - static const locked = 'locked'; - static const addDetails = 'addDetails'; - static const reviewAndSell = 'reviewAndSell'; - static const itemTitle = 'itemTitle'; - static const itemCondition = 'itemCondition'; - static const used = 'used'; - static const region = 'region'; - static const selectRegion = 'selectRegion'; - static const itemPrice = 'itemPrice'; - static const itemPhotos = 'itemPhotos'; - static const itemInfo = 'itemInfo'; - static const uploadAttachment = 'uploadAttachment'; - static const selectFromGalleryOrOpenCamera = 'selectFromGalleryOrOpenCamera'; - static const openCamera = 'openCamera'; - static const uploadFromGallery = 'uploadFromGallery'; - static const name = 'name'; - static const email = 'email'; - static const noHistoryAvailable = 'noHistoryAvailable'; - static const purchaseRequisition = 'purchaseRequisition'; - static const moveOrder = 'moveOrder'; - static const humanResource = 'humanResource'; - static const purchaseOrder = 'purchaseOrder'; - static const ITGForms = 'ITGForms'; - static const itemCreation = 'itemCreation'; - static const stamp = 'stamp'; - static const addFavoriteList = 'addFavoriteList'; - static const feedbackUserExperience = 'feedbackUserExperience'; - static const rateUI = 'rateUI'; - static const submitSurvey = 'submitSurvey'; - static const typeHere = 'typeHere'; - static const infoDetail = 'infoDetail'; - static const amount_detail = 'amount_detail'; - static const currentBalance = 'currentBalance'; - static const currentLeaveBalance = 'currentLeaveBalance'; - static const calculatedDays = 'calculatedDays'; - static const totalDays = 'totalDays'; - static const usedBalance = 'usedBalance'; - static const infants = 'infants'; - static const child = 'child'; - static const adult = 'adult'; - static const updateMember = 'updateMember'; - static const fieldIsEmpty = 'fieldIsEmpty'; - static const pleaseEnterComments = 'pleaseEnterComments'; - static const skip = 'skip'; - static const typeCurrentPasswordBelow = 'typeCurrentPasswordBelow'; - static const currentPassword = 'currentPassword'; - static const concurrentReports = 'concurrentReports'; - static const profile_reset_password_label = 'profile.reset_password.label'; - static const profile_reset_password_username = 'profile.reset_password.username'; - static const profile_reset_password_password = 'profile.reset_password.password'; - static const profile_reset_password = 'profile.reset_password'; - static const profile_profileCompletionPer = 'profile.profileCompletionPer'; - static const profile_completeProfile = 'profile.completeProfile'; - static const profile_personalInformation = 'profile.personalInformation'; - static const profile_basicDetails = 'profile.basicDetails'; - static const profile_address = 'profile.address'; - static const profile_contactDetails = 'profile.contactDetails'; - static const profile_familyDetails = 'profile.familyDetails'; - static const profile_effectiveDate = 'profile.effectiveDate'; - static const profile_country = 'profile.country'; - static const profile = 'profile'; - static const clicked = 'clicked'; - static const gender_with_arg = 'gender.with_arg'; - static const gender = 'gender'; - static const reset_locale = 'reset_locale'; - static const chat = 'chat'; - static const mychats = 'mychats'; - static const advancedSearch = 'advancedSearch'; - static const openNot = 'openNot'; - static const fyi = 'fyi'; - static const toDo = 'toDo'; - static const all = 'all'; - static const meNot = 'meNot'; - static const view = 'view'; - static const fromUserName = 'fromUserName'; - static const sentDate = 'sentDate'; - static const itemTypeDisplayName = 'itemTypeDisplayName'; - static const none = 'none'; - static const createNewChat = 'createNewChat'; - static const brainMarathon = 'brainMarathon'; - static const contestTopicAbout = 'contestTopicAbout'; - static const gameDate = 'gameDate'; - static const gameTime = 'gameTime'; - static const joinMarathon = 'joinMarathon'; - static const joinDemoMarathon = 'joinDemoMarathon'; - static const minutes = 'minutes'; - static const seconds = 'seconds'; - static const note = 'note'; - static const demoMarathonNoteP1 = 'demoMarathonNoteP1'; - static const demoMarathonNoteP2 = 'demoMarathonNoteP2'; - static const demoMarathonNoteP3 = 'demoMarathonNoteP3'; - static const sponsoredBy = 'sponsoredBy'; - static const question = 'question'; - static const marathoners = 'marathoners'; - static const prize = 'prize'; - static const winnerSelection = 'winnerSelection'; - static const qualifiers = 'qualifiers'; - static const getReadyForContest = 'getReadyForContest'; - static const winnerSelectedRandomly = 'winnerSelectedRandomly'; - static const fingersCrossed = 'fingersCrossed'; - static const congrats = 'congrats'; - static const allQuestionsCorrect = 'allQuestionsCorrect'; - static const otp = 'otp'; - static const verification = 'verification'; - static const resend = 'resend'; - static const codeExpire = 'codeExpire'; - static const typeheretoreply = 'typeheretoreply'; - static const favorite = 'favorite'; - static const searchfromchat = 'searchfromchat'; - static const yourAnswerCorrect = 'yourAnswerCorrect'; - static const youMissedTheQuestion = 'youMissedTheQuestion'; - static const wrongAnswer = 'wrongAnswer'; - static const oops = 'oops'; - static const winner = 'winner'; - static const youWantToLeaveMarathon = 'youWantToLeaveMarathon'; - static const ourSponsor = 'ourSponsor'; - static const startingIn = 'startingIn'; - static const youAreOutOfContest = 'youAreOutOfContest'; - -} diff --git a/lib/main.dart b/lib/main.dart index 4709be1..aa9f933 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:logger/logger.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; import 'package:mohem_flutter_app/models/post_params_model.dart'; @@ -32,11 +33,15 @@ class MyHttpOverrides extends HttpOverrides { } } +bool isTablet = false; + Future main() async { WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); AppState().setPostParamsInitConfig(); HttpOverrides.global = MyHttpOverrides(); + isTablet = MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.shortestSide >= ApiConsts.tabletMinLength; + runApp( EasyLocalization( supportedLocales: const [ diff --git a/lib/models/marathon/winner_model.dart b/lib/models/marathon/winner_model.dart new file mode 100644 index 0000000..5663bf1 --- /dev/null +++ b/lib/models/marathon/winner_model.dart @@ -0,0 +1,17 @@ +class WinnerModel { + String? id; + String? marathoneId; + String? employeeId; + String? nameEn; + String? nameAr; + + WinnerModel({id, marathoneId, employeeId, nameEn, nameAr}); + + WinnerModel.fromJson(Map json) { + id = json['id']; + marathoneId = json['marathoneId']; + employeeId = json['employeeId']; + nameEn = json['nameEn']; + nameAr = json['nameAr']; + } +} diff --git a/lib/ui/marathon/marathon_provider.dart b/lib/ui/marathon/marathon_provider.dart index 1cf8efd..2d778b9 100644 --- a/lib/ui/marathon/marathon_provider.dart +++ b/lib/ui/marathon/marathon_provider.dart @@ -9,6 +9,7 @@ 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/models/marathon/winner_model.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; import 'package:video_player/video_player.dart'; @@ -22,10 +23,10 @@ class MarathonProvider extends ChangeNotifier { QuestionModel currentQuestion = QuestionModel(); List answerStatusesList = []; QuestionCardStatus questionCardStatus = QuestionCardStatus.question; - + List? selectedWinners; int? selectedOptionIndex; String? selectedOptionId; - int totalQualifiers = 0; + int? totalQualifiers; bool _isLoading = false; @@ -110,6 +111,7 @@ class MarathonProvider extends ChangeNotifier { //****************TIMERS********** + int sponsorsSecondsCounter = 0; int totalSponsorVideoSeconds = 0; Timer timerForSponsorVideo = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); @@ -118,6 +120,7 @@ class MarathonProvider extends ChangeNotifier { timerForSponsorVideo = Timer.periodic( oneSec, (Timer timer) async { + sponsorsSecondsCounter++; if (totalSponsorVideoSeconds == 0) { timer.cancel(); notifyListeners(); @@ -134,12 +137,15 @@ class MarathonProvider extends ChangeNotifier { int totalSecondsToWaitForMarathon = 20; Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); - void startTimerToMarathon(BuildContext context) { + void startTimerToWaitForMarathon() { const Duration oneSec = Duration(seconds: 1); timerToWaitForMarathon = Timer.periodic( oneSec, (Timer timer) async { if (totalSecondsToWaitForMarathon == 0) { + callNextQuestionApi(); + timer.cancel(); + return; } else { totalSecondsToWaitForMarathon--; } @@ -163,6 +169,8 @@ class MarathonProvider extends ChangeNotifier { } if (totalCurrentQuestionTime == currentGapTime) { + totalCurrentQuestionTime--; + updateCardStatusToAnswer(); await callSubmitOptionApi().then((bool value) async { @@ -175,6 +183,7 @@ class MarathonProvider extends ChangeNotifier { if (totalCurrentQuestionTime == 0) { updateCardData(); if (currentQuestionNumber == marathonDetailModel.totalQuestions! - 1) { + callGetQualifiersApi(); updateQuestionCardStatus(QuestionCardStatus.findingWinner); timer.cancel(); cancelTimer(); @@ -182,7 +191,9 @@ class MarathonProvider extends ChangeNotifier { } return; } else { - totalCurrentQuestionTime--; + if (totalCurrentQuestionTime != currentGapTime) { + totalCurrentQuestionTime--; + } } notifyListeners(); @@ -214,7 +225,17 @@ class MarathonProvider extends ChangeNotifier { //****************FUNCTIONS********* Future callSubmitOptionApi() async { - return await MarathonApiClient().submitSelectedOption(selectedAnswerId: selectedOptionId); + return await MarathonApiClient().submitSelectedOption(marathonId: marathonDetailModel.id!, questionId: currentQuestion.id, selectedAnswerId: selectedOptionId); + } + + Future callGetQualifiersApi() async { + totalQualifiers = await MarathonApiClient().getQualifiers(marathonId: marathonDetailModel.id!); + notifyListeners(); + } + + Future callGetSelectedWinnersApi() async { + selectedWinners = await MarathonApiClient().getSelectedWinner(marathonId: marathonDetailModel.id!); + notifyListeners(); } // 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 @@ -222,6 +243,7 @@ class MarathonProvider extends ChangeNotifier { Future callNextQuestionApi() async { if (currentQuestionNumber < marathonDetailModel.totalQuestions!) { if (currentQuestionNumber == 0) { + Utils.showLoading(AppRoutes.navigatorKey.currentContext!); currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!))!; if (Utils.isLoading) { Utils.hideLoading(AppRoutes.navigatorKey.currentContext!); @@ -239,8 +261,7 @@ class MarathonProvider extends ChangeNotifier { void updateCardData() { if (currentQuestionNumber > 0) { - print("swiped it away!!"); - swipeCardLeft(); + swiperController.swipeLeft(); } selectedOptionIndex = null; currentQuestionNumber++; @@ -249,6 +270,7 @@ class MarathonProvider extends ChangeNotifier { currentGapTime = currentQuestion.nextQuestGap!; totalMarathoners = currentQuestion.remainingParticipantCount!; questionCardStatus = QuestionCardStatus.question; + notifyListeners(); } void populateQuestionStatusesList() { @@ -316,20 +338,21 @@ class MarathonProvider extends ChangeNotifier { } } - void swipeCardLeft() { - swiperController.swipeLeft(); - notifyListeners(); - } - void resetValues() async { _currentQuestionNumber = 0; cardContentList.clear(); timerForWinnerSelection.cancel(); + timerForSponsorVideo.cancel(); + timerToWaitForMarathon.cancel(); timerForQuestion.cancel(); _isMarathonCompleted = false; + isUserOutOfGame = false; totalCurrentQuestionTime = 0; + sponsorsSecondsCounter = 0; + totalSponsorVideoSeconds = 0; + totalSecondsToWaitForMarathon = 20; + currentGapTime = 0; currentQuestion = QuestionModel(); - notifyListeners(); } @@ -354,40 +377,23 @@ class MarathonProvider extends ChangeNotifier { }); } - Future buildConnectionWithSignalR(BuildContext context) async { - Utils.showLoading(context); + Future onJoinMarathonPressed(BuildContext context) async { try { + Utils.showLoading(context); resetValues(); - // await MarathonApiClient().buildHubConnection(context, marathonDetailModel.sponsors!.first.sponsorPrizes!.first.id!); + int? remainingTime = await MarathonApiClient().joinMarathonAsParticipant(); + if (remainingTime != null) { + totalSecondsToWaitForMarathon = remainingTime; + notifyListeners(); + startTimerToWaitForMarathon(); + Navigator.pushReplacementNamed(context, AppRoutes.marathonWaitingScreen); + } } catch (e) { if (kDebugMode) { - print("error in buildConnectionWithSignalR: ${e.toString()}"); + print("error in onJoinMarathonPressed: ${e.toString()}"); } Utils.hideLoading(context); Utils.confirmDialog(context, e.toString()); } } - - Future onJoinMarathonPressed(BuildContext context) async { - //TODO: here we need to put a check to make sure we should not display sponsor when remaining time to marathon is less than 30 seconds plus video duration e.g. 30 seconds + video duration time - // if (marathonDetailModel.sponsors!.first.video != null && marathonDetailModel.sponsors!.first.video != "") { - if (false) { - await initializeVideoPlayer().then((_) { - startTimerForSponsorVideo(); - Navigator.pushNamed(context, AppRoutes.marathonSponsorVideoScreen); - }); - } else { - 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 e14f8c9..2ae3f64 100644 --- a/lib/ui/marathon/marathon_screen.dart +++ b/lib/ui/marathon/marathon_screen.dart @@ -8,7 +8,7 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/lottie_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'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; @@ -21,6 +21,7 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/marathon_qualifiers_contai import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/question_card_builder.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; import 'package:provider/provider.dart'; class MarathonScreen extends StatelessWidget { @@ -63,22 +64,28 @@ class MarathonScreen extends StatelessWidget { SizedBox( height: 50, child: Stack( - children: [ + children: [ Align( alignment: Alignment.center, child: SvgPicture.asset("assets/images/winner_ribbon.svg", height: 50), ), Align( alignment: Alignment.center, - child: LocaleKeys.winner.tr().toText32(color: MyColors.white, isBold: true).paddingOnly(top: 07), + child: LocaleKeys.winner.tr().toText32(color: MyColors.white, isBold: true, isCentered: true).paddingOnly(top: 07), ) ], ), ), 12.height, - "Muhammad Shrouff".toText22(color: MyColors.grey3AColor), - "837436".toText22(color: MyColors.grey57Color), - 80.height, + if (provider.selectedWinners != null) ...[ + (AppState().isArabic(context) ? provider.selectedWinners!.first.nameEn : provider.selectedWinners!.first.nameEn)!.toText22( + color: MyColors.grey3AColor, + isCentered: true, + ), + 8.height, + provider.selectedWinners!.first.employeeId!.toText22(color: MyColors.grey57Color), + ], + 60.height, if (provider.marathonDetailModel.sponsors != null && provider.marathonDetailModel.sponsors!.isNotEmpty) ...[ Row( mainAxisAlignment: MainAxisAlignment.center, @@ -118,12 +125,12 @@ class MarathonScreen extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - (AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr!) + (AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!) .toText17(isBold: true, color: MyColors.white), AppState().memberInformationList!.eMPLOYEENUMBER!.toText17(isBold: true, color: MyColors.white), ], ), - ).paddingOnly(left: 20, right: 20, top: 12, bottom: 20); + ).paddingOnly(left: 20, right: 20, top: 12, bottom: 10); } @override @@ -135,10 +142,38 @@ class MarathonScreen extends StatelessWidget { context, title: LocaleKeys.brainMarathon.tr(), onHomeTapped: () { - Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); + if (provider.questionCardStatus == QuestionCardStatus.winnerFound) { + provider.resetValues(); + Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + } else { + showDialog( + context: context, + builder: (BuildContext context) => ConfirmDialog( + message: LocaleKeys.youWantToLeaveMarathon.tr(), + onTap: () { + provider.resetValues(); + Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + }, + ), + ); + } }, onBackTapped: () { - Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); + if (provider.questionCardStatus == QuestionCardStatus.winnerFound) { + provider.resetValues(); + Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + } else { + showDialog( + context: context, + builder: (BuildContext context) => ConfirmDialog( + message: LocaleKeys.youWantToLeaveMarathon.tr(), + onTap: () { + provider.resetValues(); + Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + }, + ), + ); + } }, ), body: SingleChildScrollView( @@ -156,7 +191,7 @@ class MarathonScreen extends StatelessWidget { getNameContainer(context), ], QuestionCardBuilder( - onQuestion: (BuildContext context) => QuestionCard(provider: provider), + onQuestion: (BuildContext context) => const QuestionCard(), onCompleted: (BuildContext context) => CustomStatusWidget( asset: Lottie.asset(MyLottieConsts.allQuestions, height: 200), title: LocaleKeys.congrats.tr().toText22(color: MyColors.greenColor), diff --git a/lib/ui/marathon/marathon_sponsor_video_screen.dart b/lib/ui/marathon/marathon_sponsor_video_screen.dart index c81f59b..12d5949 100644 --- a/lib/ui/marathon/marathon_sponsor_video_screen.dart +++ b/lib/ui/marathon/marathon_sponsor_video_screen.dart @@ -25,6 +25,9 @@ class SponsorVideoScreen extends StatelessWidget { return WillPopScope( onWillPop: () { provider.videoController.dispose(); + provider.sponsorsSecondsCounter = 0; + provider.totalSponsorVideoSeconds = 0; + provider.timerForSponsorVideo.cancel(); return Future.value(true); }, child: Scaffold( @@ -52,9 +55,11 @@ class SponsorVideoScreen extends StatelessWidget { child: provider.totalSponsorVideoSeconds == 0 ? InkWell( onTap: () { - Navigator.pop(context); provider.videoController.dispose(); - provider.buildConnectionWithSignalR(AppRoutes.navigatorKey.currentState!.overlay!.context); + provider.sponsorsSecondsCounter = 0; + provider.totalSponsorVideoSeconds = 0; + provider.timerForSponsorVideo.cancel(); + Navigator.pushReplacementNamed(context, AppRoutes.marathonIntroScreen); }, child: const Icon(Icons.close, size: 12), ) @@ -64,24 +69,30 @@ class SponsorVideoScreen extends StatelessWidget { ), ), ).paddingOnly(top: 20, right: 18), - Align( - alignment: Alignment.topLeft, - child: InkWell( - onTap: () { - Navigator.pop(context); - provider.videoController.dispose(); - provider.buildConnectionWithSignalR(AppRoutes.navigatorKey.currentState!.overlay!.context); - }, - child: Container( - decoration: BoxDecoration(color: MyColors.white, borderRadius: BorderRadius.circular(15)), - padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 6), - child: Directionality( - textDirection: ui.TextDirection.ltr, - child: LocaleKeys.skip.tr().toText11(color: MyColors.darkTextColor), - ), - ), - ), - ).paddingOnly(top: 20, left: 18), + + //TODO: WE WILL INCREASE THIS 2 BEFORE GOING LIVE + provider.sponsorsSecondsCounter >= 2 + ? Align( + alignment: Alignment.topLeft, + child: InkWell( + onTap: () { + provider.videoController.dispose(); + provider.sponsorsSecondsCounter = 0; + provider.totalSponsorVideoSeconds = 0; + provider.timerForSponsorVideo.cancel(); + Navigator.pushReplacementNamed(context, AppRoutes.marathonIntroScreen); + }, + child: Container( + decoration: BoxDecoration(color: MyColors.white, borderRadius: BorderRadius.circular(15)), + padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 6), + child: Directionality( + textDirection: ui.TextDirection.ltr, + child: LocaleKeys.skip.tr().toText11(color: MyColors.darkTextColor), + ), + ), + ), + ).paddingOnly(top: 20, left: 18) + : const SizedBox(), ], ), ), diff --git a/lib/ui/marathon/marathon_waiting_screen.dart b/lib/ui/marathon/marathon_waiting_screen.dart index 27f0c08..7191ff2 100644 --- a/lib/ui/marathon/marathon_waiting_screen.dart +++ b/lib/ui/marathon/marathon_waiting_screen.dart @@ -4,12 +4,13 @@ import 'package:lottie/lottie.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/lottie_consts.dart'; -import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; import 'package:provider/provider.dart'; class MarathonWaitingScreen extends StatelessWidget { @@ -18,44 +19,90 @@ class MarathonWaitingScreen extends StatelessWidget { @override Widget build(BuildContext context) { MarathonProvider provider = context.watch(); - return Scaffold( - appBar: AppBarWidget( - context, - title: LocaleKeys.brainMarathon.tr(), - onHomeTapped: () { - Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); - }, - onBackTapped: () { - Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); - }, - ), - body: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - width: double.infinity, - margin: const EdgeInsets.all(21), - decoration: MyDecorations.shadowDecoration, - child: Stack( - children: [ - Align( - child: Lottie.asset(MyLottieConsts.marathonWaiting, height: 200), - ), - Align( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - LocaleKeys.startingIn.tr().toText16(), - "00:${provider.totalSecondsToWaitForMarathon < 10 ? "0${provider.totalSecondsToWaitForMarathon}" : provider.totalSecondsToWaitForMarathon}" - .toText18(color: provider.totalSecondsToWaitForMarathon < 5 ? MyColors.redColor : MyColors.black), - ], + return WillPopScope( + onWillPop: () { + showDialog( + context: context, + builder: (BuildContext context) => ConfirmDialog( + message: LocaleKeys.youWantToLeaveMarathon.tr(), + onTap: () { + provider.resetValues(); + Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + }, + ), + ); + return Future.value(false); + }, + child: Scaffold( + appBar: AppBarWidget( + context, + title: LocaleKeys.brainMarathon.tr(), + onHomeTapped: () { + showDialog( + context: context, + builder: (BuildContext context) => ConfirmDialog( + message: LocaleKeys.youWantToLeaveMarathon.tr(), + onTap: () { + provider.resetValues(); + Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + }, + ), + ); + }, + onBackTapped: () { + showDialog( + context: context, + builder: (BuildContext context) => ConfirmDialog( + message: LocaleKeys.youWantToLeaveMarathon.tr(), + onTap: () { + provider.resetValues(); + Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard)); + }, + ), + ); + }, + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + width: double.infinity, + margin: const EdgeInsets.all(21), + decoration: MyDecorations.shadowDecoration, + child: Stack( + children: [ + Align( + child: Lottie.asset(MyLottieConsts.marathonWaiting, height: 200), + ), + Align( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + LocaleKeys.startingIn.tr().toText16(), + provider.totalSecondsToWaitForMarathon.toString().toText18(color: provider.totalSecondsToWaitForMarathon < 5 ? MyColors.redColor : MyColors.black), + ], + ), + ), + Align( + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + InkWell( + onTap: () { + provider.callNextQuestionApi(); + provider.timerToWaitForMarathon.cancel(); + }, + child: "Join Now".toText16(), + ).paddingOnly(bottom: 20), + ], + ), ), - ), - ], - ), - ).expanded, - ], + ], + ), + ).expanded, + ], + ), ), ); } diff --git a/lib/ui/marathon/marathon_winner_selection.dart b/lib/ui/marathon/marathon_winner_selection.dart deleted file mode 100644 index ed49f04..0000000 --- a/lib/ui/marathon/marathon_winner_selection.dart +++ /dev/null @@ -1,90 +0,0 @@ -import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/material.dart'; -import 'package:lottie/lottie.dart'; -import 'package:mohem_flutter_app/classes/colors.dart'; -import 'package:mohem_flutter_app/classes/lottie_consts.dart'; -import 'package:mohem_flutter_app/config/routes.dart'; -import 'package:mohem_flutter_app/extensions/int_extensions.dart'; -import 'package:mohem_flutter_app/extensions/string_extensions.dart'; -import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; -import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; -import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; -import 'package:mohem_flutter_app/ui/marathon/widgets/custom_status_widget.dart'; -import 'package:mohem_flutter_app/ui/marathon/widgets/marathon_qualifiers_container.dart'; -import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; -import 'package:provider/provider.dart'; - -class MarathonWinnerSelection extends StatelessWidget { - const MarathonWinnerSelection({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - MarathonProvider provider = context.read(); - return Scaffold( - appBar: AppBarWidget(context, title: LocaleKeys.brainMarathon.tr()), - body: SingleChildScrollView( - child: Column( - children: [ - 20.height, - QualifiersContainer(provider: provider,).paddingOnly(left: 21, right: 21), - 12.height, - InkWell( - onTap: () { - Navigator.pushNamed(context, AppRoutes.marathonWinnerScreen); - }, - child: Container( - height: 50, - decoration: BoxDecoration( - color: MyColors.greenColor, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), - ), - ], - ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - "Muhammad Shrouff".toText17(isBold: true, color: MyColors.white), - "837436".toText17(isBold: true, color: MyColors.white), - ], - ), - ), - ).paddingOnly(left: 20, right: 20), - ), - CustomStatusWidget( - asset: Lottie.asset( - MyLottieConsts.winnerLottie, - height: 168, - ), - title: Text( - LocaleKeys.fingersCrossed.tr(), - style: const TextStyle( - height: 27 / 27, - color: MyColors.greenColor, - fontSize: 27, - letterSpacing: -1.08, - fontWeight: FontWeight.w600, - ), - ), - subTitle: Text( - LocaleKeys.winnerSelectedRandomly.tr(), - textAlign: TextAlign.center, - style: const TextStyle( - color: MyColors.darkTextColor, - fontSize: 18, - letterSpacing: -0.72, - fontWeight: FontWeight.w600, - ), - )).paddingOnly(left: 21, right: 21, top: 20, bottom: 20), - ], - ), - ), - ); - } -} diff --git a/lib/ui/marathon/widgets/countdown_timer.dart b/lib/ui/marathon/widgets/countdown_timer.dart index cfa3b1b..3a33697 100644 --- a/lib/ui/marathon/widgets/countdown_timer.dart +++ b/lib/ui/marathon/widgets/countdown_timer.dart @@ -8,6 +8,7 @@ import 'package:flutter_countdown_timer/current_remaining_time.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; class BuildCountdownTimer extends StatelessWidget { @@ -29,9 +30,10 @@ class BuildCountdownTimer extends StatelessWidget { letterSpacing: -0.4, ); - final TextStyle styleDigitHome = const TextStyle( + final TextStyle styleDigitHome = TextStyle( height: 22 / 27, color: MyColors.white, + fontSize: isTablet ? 30 : 15, fontStyle: FontStyle.italic, letterSpacing: -1.44, fontWeight: FontWeight.bold, @@ -53,6 +55,33 @@ class BuildCountdownTimer extends StatelessWidget { fontWeight: FontWeight.bold, ); + Widget buildSeparator() { + return AutoSizeText( + " : ", + maxFontSize: 24, + minFontSize: 20, + style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, + ); + } + + Widget getTimeDigit(String text) { + return AutoSizeText( + text, + maxFontSize: 24, + minFontSize: 20, + style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, + ); + } + + Widget getTimeText(String text) { + return AutoSizeText( + text, + minFontSize: 7, + maxFontSize: 8, + style: screenFlag == 0 ? styleTextHome : styleTextMarathon, + ); + } + Widget buildEmptyWidget() { return Directionality( textDirection: ui.TextDirection.ltr, @@ -63,70 +92,29 @@ class BuildCountdownTimer extends StatelessWidget { children: [ Column( children: [ - // todo @faiz: Make a separate method and pass string , so we can minimize code replication - AutoSizeText( - "00", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ), - AutoSizeText( - LocaleKeys.days.tr(), - minFontSize: 7, - maxFontSize: 8, - style: screenFlag == 0 ? styleTextHome : styleTextMarathon, - ), + getTimeDigit("00"), + getTimeText(LocaleKeys.days.tr()), ], ), buildSeparator(), Column( children: [ - AutoSizeText( - "00", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ), - AutoSizeText( - LocaleKeys.hours.tr(), - minFontSize: 7, - maxFontSize: 8, - style: screenFlag == 0 ? styleTextHome : styleTextMarathon, - ), + getTimeDigit("00"), + getTimeText(LocaleKeys.hours.tr()), ], ), buildSeparator(), Column( children: [ - AutoSizeText( - "00", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ), - AutoSizeText( - LocaleKeys.minutes.tr(), - minFontSize: 7, - maxFontSize: 8, - style: screenFlag == 0 ? styleTextHome : styleTextMarathon, - ), + getTimeDigit("00"), + getTimeText(LocaleKeys.minutes.tr()), ], ), buildSeparator(), Column( children: [ - AutoSizeText( - "00", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ), - AutoSizeText( - LocaleKeys.seconds.tr(), - minFontSize: 7, - maxFontSize: 8, - style: screenFlag == 0 ? styleTextHome : styleTextMarathon, - ), + getTimeDigit("00"), + getTimeText(LocaleKeys.seconds.tr()), ], ), ], @@ -134,15 +122,6 @@ class BuildCountdownTimer extends StatelessWidget { ); } - Widget buildSeparator() { - return AutoSizeText( - " : ", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ); - } - Widget buildCountdownTimer(CurrentRemainingTime? time) { if (time == null) { if (!provider.itsMarathonTime) { @@ -162,98 +141,29 @@ class BuildCountdownTimer extends StatelessWidget { children: [ Column( children: [ - // todo @faiz: Make a separate method and pass value and string , so we can minimize code replication - time.days == null - ? AutoSizeText( - "00", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ) - : AutoSizeText( - time.days! < 10 ? "0${time.days.toString()}" : time.days.toString(), - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ), - AutoSizeText( - LocaleKeys.days.tr(), - minFontSize: 7, - maxFontSize: 8, - style: screenFlag == 0 ? styleTextHome : styleTextMarathon, - ), + time.days == null ? getTimeDigit("00") : getTimeDigit(time.days! < 10 ? "0${time.days.toString()}" : time.days.toString()), + getTimeText(LocaleKeys.days.tr()), ], ), buildSeparator(), Column( children: [ - time.hours == null - ? AutoSizeText( - "00", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ) - : AutoSizeText( - time.hours! < 10 ? "0${time.hours.toString()}" : time.hours.toString(), - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ), - AutoSizeText( - LocaleKeys.hours.tr(), - minFontSize: 7, - maxFontSize: 8, - style: screenFlag == 0 ? styleTextHome : styleTextMarathon, - ), + time.hours == null ? getTimeDigit("00") : getTimeDigit(time.hours! < 10 ? "0${time.hours.toString()}" : time.hours.toString()), + getTimeText(LocaleKeys.hours.tr()), ], ), buildSeparator(), Column( children: [ - time.min == null - ? AutoSizeText( - "00", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ) - : AutoSizeText( - time.min! < 10 ? "0${time.min.toString()}" : time.min.toString(), - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ), - AutoSizeText( - LocaleKeys.minutes.tr(), - minFontSize: 7, - maxFontSize: 8, - style: screenFlag == 0 ? styleTextHome : styleTextMarathon, - ), + time.min == null ? getTimeDigit("00") : getTimeDigit(time.min! < 10 ? "0${time.min.toString()}" : time.min.toString()), + getTimeText(LocaleKeys.minutes.tr()), ], ), buildSeparator(), Column( children: [ - time.sec == null - ? AutoSizeText( - "00", - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ) - : AutoSizeText( - time.sec! < 10 ? "0${time.sec.toString()}" : time.sec.toString(), - maxFontSize: 24, - minFontSize: 20, - style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon, - ), - AutoSizeText( - LocaleKeys.seconds.tr(), - minFontSize: 7, - maxFontSize: 8, - style: screenFlag == 0 ? styleTextHome : styleTextMarathon, - ), + time.sec == null ? getTimeDigit("00") : getTimeDigit(time.sec! < 10 ? "0${time.sec.toString()}" : time.sec.toString()), + getTimeText(LocaleKeys.seconds.tr()), ], ), ], diff --git a/lib/ui/marathon/widgets/marathon_banner.dart b/lib/ui/marathon/widgets/marathon_banner.dart index d805362..2be08a9 100644 --- a/lib/ui/marathon/widgets/marathon_banner.dart +++ b/lib/ui/marathon/widgets/marathon_banner.dart @@ -1,16 +1,18 @@ import 'dart:math' as math; -import 'package:auto_size_text/auto_size_text.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.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/decorations_helper.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'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/countdown_timer.dart'; import 'package:provider/provider.dart'; @@ -26,10 +28,10 @@ class MarathonBanner extends StatelessWidget { return provider.marathonDetailModel.startTime != null ? Container( decoration: MyDecorations.shadowDecoration, - height: MediaQuery.of(context).size.height * 0.11, + height: isTablet ? MediaQuery.of(context).size.height * 0.17 : MediaQuery.of(context).size.height * 0.11, clipBehavior: Clip.antiAlias, child: Stack( - children: [ + children: [ Transform( alignment: Alignment.center, transform: Matrix4.rotationY( @@ -48,8 +50,8 @@ class MarathonBanner extends StatelessWidget { child: Transform.rotate( angle: 10, child: Container( - width: 65, - height: 32, + width: isTablet ? 70 : 65, + height: isTablet ? 40 : 32, color: MyColors.darkDigitColor, ), ), @@ -60,8 +62,8 @@ class MarathonBanner extends StatelessWidget { child: Transform.rotate( angle: 15, child: Container( - width: 65, - height: 32, + width: isTablet ? 70 : 65, + height: isTablet ? 40 : 32, color: MyColors.darkDigitColor, ), ), @@ -70,7 +72,7 @@ class MarathonBanner extends StatelessWidget { width: double.infinity, height: double.infinity, child: Row( - children: [ + children: [ const Expanded( flex: 3, child: SizedBox( @@ -92,28 +94,27 @@ class MarathonBanner extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ AppState().isArabic(context) ? 0.height : 5.height, - AutoSizeText( + Text( LocaleKeys.getReadyForContest.tr(), - minFontSize: 08, - maxFontSize: 11, style: TextStyle( + fontSize: isTablet ? 20 : 11, fontStyle: FontStyle.italic, fontWeight: FontWeight.w600, color: MyColors.white.withOpacity(0.83), letterSpacing: -0.4, ), ), - AutoSizeText( + Text( AppState().isArabic(context) ? provider.marathonDetailModel.titleAr ?? "" : provider.marathonDetailModel.titleEn ?? "", style: TextStyle( fontStyle: FontStyle.italic, - fontSize: 19, + fontSize: isTablet ? 30 : 19, fontWeight: FontWeight.bold, color: MyColors.white.withOpacity(0.83), height: 32 / 22, ), ), - 3.height, + isTablet ? 10.height : 3.height, BuildCountdownTimer( timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch, provider: provider, @@ -135,18 +136,18 @@ class MarathonBanner extends StatelessWidget { ? Align( alignment: Alignment.topRight, child: SizedBox( - height: 20, - width: 35, + height: isTablet ? 30 : 20, + width: isTablet ? 45 : 35, child: Transform.rotate( angle: math.pi / 4.5, child: Text( LocaleKeys.brainMarathon.tr(), textAlign: TextAlign.center, maxLines: 2, - style: const TextStyle( + style: TextStyle( color: MyColors.white, fontWeight: FontWeight.bold, - fontSize: 6, + fontSize: isTablet ? 8 : 6, height: 1.2, ), ), @@ -156,18 +157,18 @@ class MarathonBanner extends StatelessWidget { : Align( alignment: Alignment.topLeft, child: SizedBox( - height: 20, - width: 35, + height: isTablet ? 30 : 20, + width: isTablet ? 45 : 35, child: Transform.rotate( angle: -math.pi / 4.5, child: Text( LocaleKeys.brainMarathon.tr(), textAlign: TextAlign.center, maxLines: 2, - style: const TextStyle( + style: TextStyle( color: MyColors.kWhiteColor, fontWeight: FontWeight.bold, - fontSize: 6, + fontSize: isTablet ? 8 : 6, height: 1.2, ), ), @@ -181,7 +182,7 @@ class MarathonBanner extends StatelessWidget { child: RotatedBox( quarterTurns: 4, child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.whiteColor), - ).paddingAll(15), + ).paddingAll(isTablet ? 20 : 15), ) : Positioned( bottom: 0, @@ -189,12 +190,31 @@ class MarathonBanner extends StatelessWidget { child: RotatedBox( quarterTurns: 2, child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.whiteColor), - ).paddingAll(15), + ).paddingAll(isTablet ? 20 : 15), ), ], - ).onPress( - () => Navigator.pushNamed(context, AppRoutes.marathonIntroScreen), - ), + ).onPress(() async { + int remainingTimeInMinutes = DateTime.parse(provider.marathonDetailModel.startTime!).difference(DateTime.now()).inMinutes; + + if (remainingTimeInMinutes > 2) { + Utils.showLoading(context); + try { + await provider.initializeVideoPlayer().then((_) { + Utils.hideLoading(context); + provider.startTimerForSponsorVideo(); + Navigator.pushNamed(context, AppRoutes.marathonSponsorVideoScreen); + }); + } catch (e, s) { + if (kDebugMode) { + print("Error in VideoPlayer: ${e.toString()}"); + } + Utils.hideLoading(context); + Navigator.pushNamed(context, AppRoutes.marathonIntroScreen); + } + } else { + Navigator.pushNamed(context, AppRoutes.marathonIntroScreen); + } + }), ) : const SizedBox(); } diff --git a/lib/ui/marathon/widgets/marathon_qualifiers_container.dart b/lib/ui/marathon/widgets/marathon_qualifiers_container.dart index 0308027..dc9d7e4 100644 --- a/lib/ui/marathon/widgets/marathon_qualifiers_container.dart +++ b/lib/ui/marathon/widgets/marathon_qualifiers_container.dart @@ -20,6 +20,7 @@ class _QualifiersContainerState extends State { @override void initState() { widget.provider.startTimerForWinnerSelection(); + widget.provider.callGetSelectedWinnersApi(); super.initState(); } @@ -36,13 +37,14 @@ class _QualifiersContainerState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.winnerSelection.tr().toText21(color: MyColors.grey3AColor), - "00:${widget.provider.totalSecondsToWaitForWinner < 10 ? "0${widget.provider.totalSecondsToWaitForWinner}" : widget.provider.totalSecondsToWaitForWinner}".toText18(color: MyColors.redColor), + "00:${widget.provider.totalSecondsToWaitForWinner < 10 ? "0${widget.provider.totalSecondsToWaitForWinner}" : widget.provider.totalSecondsToWaitForWinner}" + .toText18(color: MyColors.redColor), ], ), 10.height, Row( children: [ - widget.provider.totalQualifiers.toString().toText30(color: MyColors.greenColor, isBold: true), + widget.provider.totalQualifiers != null ? widget.provider.totalQualifiers.toString().toText30(color: MyColors.greenColor, isBold: true) : const SizedBox(), 2.width, LocaleKeys.qualifiers.tr().toText16(color: MyColors.greenColor), ], diff --git a/lib/ui/marathon/widgets/question_card.dart b/lib/ui/marathon/widgets/question_card.dart index 4009983..5f419c5 100644 --- a/lib/ui/marathon/widgets/question_card.dart +++ b/lib/ui/marathon/widgets/question_card.dart @@ -1,4 +1,5 @@ import 'package:appinio_swiper/appinio_swiper.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:lottie/lottie.dart'; @@ -6,38 +7,35 @@ import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/lottie_consts.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; 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/marathon/question_model.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:provider/provider.dart'; class QuestionCard extends StatelessWidget { - final MarathonProvider provider; - - const QuestionCard({Key? key, required this.provider}) : super(key: key); + const QuestionCard({Key? key}) : super(key: key); @override Widget build(BuildContext context) { + MarathonProvider provider = context.read(); return CupertinoPageScaffold( child: provider.cardContentList.isEmpty ? Lottie.asset(MyLottieConsts.hourGlassLottie, height: 250).paddingOnly(top: 50) : SizedBox( height: 440, width: double.infinity, - child: Consumer( - builder: (BuildContext context, MarathonProvider provider, _) { - return AppinioSwiper( - duration: const Duration(milliseconds: 400), - padding: EdgeInsets.zero, - isDisabled: true, - controller: provider.swiperController, - unswipe: (int index, AppinioSwiperDirection direction) {}, - onSwipe: (int index, AppinioSwiperDirection direction) {}, - cards: provider.cardContentList, - ); - }, + child: AppinioSwiper( + duration: const Duration(milliseconds: 400), + padding: EdgeInsets.zero, + isDisabled: true, + controller: provider.swiperController, + unswipe: (int index, AppinioSwiperDirection direction) {}, + onSwipe: (int index, AppinioSwiperDirection direction) {}, + cards: provider.cardContentList, ), ), ); @@ -163,7 +161,7 @@ class AnswerTileForText extends StatelessWidget { MarathonProvider provider = context.watch(); return InkWell( onTap: () { - provider.isUserOutOfGame ? null : onAnswerTapped() ; + provider.isUserOutOfGame ? Utils.showToast(LocaleKeys.youAreOutOfContest.tr()) : onAnswerTapped(); }, child: Container( alignment: Alignment.centerLeft,