diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index f5f734d..60b88a8 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -489,9 +489,11 @@ "sponsoredBy": "برعاية:", "question": "سؤال", "marathoners": "الماراثون", + "marathoner": "ماراثونر", "prize": "جائزة:", "winnerSelection": "اختيار الفائز", "qualifiers": "تصفيات", + "qualifier": "المؤهل", "getReadyForContest": "استعد للمسابقة القادمة:", "winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.", "fingersCrossed": "تشابك الاصابع!!!", @@ -516,5 +518,6 @@ "winners": "الفائزين!!!", "noUpcoming": "لا يوجد قادم", "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", - "noWinner": "حزين! لم يفز أحد اليوم." + "noWinner": "حزين! لم يفز أحد اليوم.", + "myTeam" : "فريقي" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 7f67e89..10cfbdf 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -478,6 +478,7 @@ "sponsoredBy": "Sponsored By:", "question": "Question", "marathoners": "Marathoners", + "marathoner": "Marathoner", "prize": "Prize:", "advancedSearch": "Advanced Search", "openNot": "Open Notifications", @@ -492,6 +493,7 @@ "none": "None", "winnerSelection": "Winner Selection", "qualifiers": "Qualifiers", + "qualifier": "Qualifier", "getReadyForContest": "Get Ready for the coming contest:", "winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.", "fingersCrossed": "Fingers Crossed!!!", @@ -516,5 +518,6 @@ "winners": "WINNERS!!!", "noUpcoming": "There is no upcoming", "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", - "noWinner": "Sad! No one won today." + "noWinner": "Sad! No one won today.", + "myTeam" : "My Team" } \ 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 28fad0f..5b1dfc8 100644 --- a/lib/api/marathon/marathon_api_client.dart +++ b/lib/api/marathon/marathon_api_client.dart @@ -29,7 +29,6 @@ class MarathonApiClient { (json) { MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); AppState().setMarathonToken = marathonModel.data["token"] ?? ""; - print("marathonToken: ${"AppState(): ${AppState().getMarathonToken}"}"); return marathonModel.data["token"] ?? ""; }, ApiConsts.marathonParticipantLoginUrl, diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 56b0008..6679cbb 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + // static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 271d2e5..27bae71 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -498,9 +498,11 @@ class CodegenLoader extends AssetLoader { "sponsoredBy": "برعاية:", "question": "سؤال", "marathoners": "الماراثون", + "marathoner": "ماراثونر", "prize": "جائزة:", "winnerSelection": "اختيار الفائز", "qualifiers": "تصفيات", + "qualifier": "المؤهل", "getReadyForContest": "استعد للمسابقة القادمة:", "winnerSelectedRandomly": "سيتم اختيار الفائز عشوائياً من بين التصفيات.", "fingersCrossed": "تشابك الاصابع!!!", @@ -1000,6 +1002,7 @@ class CodegenLoader extends AssetLoader { "sponsoredBy": "Sponsored By:", "question": "Question", "marathoners": "Marathoners", + "marathoner": "Marathoner", "prize": "Prize:", "advancedSearch": "Advanced Search", "openNot": "Open Notifications", @@ -1014,6 +1017,7 @@ class CodegenLoader extends AssetLoader { "none": "None", "winnerSelection": "Winner Selection", "qualifiers": "Qualifiers", + "qualifier": "Qualifier", "getReadyForContest": "Get Ready for the coming contest:", "winnerSelectedRandomly": "The winner will be selected randomly among the qualifiers.", "fingersCrossed": "Fingers Crossed!!!", diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 3d02540..035d458 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -475,9 +475,11 @@ abstract class LocaleKeys { static const sponsoredBy = 'sponsoredBy'; static const question = 'question'; static const marathoners = 'marathoners'; + static const marathoner = 'marathoner'; static const prize = 'prize'; static const winnerSelection = 'winnerSelection'; static const qualifiers = 'qualifiers'; + static const qualifier = 'qualifier'; static const getReadyForContest = 'getReadyForContest'; static const winnerSelectedRandomly = 'winnerSelectedRandomly'; static const fingersCrossed = 'fingersCrossed'; @@ -503,5 +505,6 @@ abstract class LocaleKeys { static const noUpcoming = 'noUpcoming'; static const fakeLocation = 'fakeLocation'; static const noWinner = 'noWinner'; + static const myTeam = 'myTeam'; } diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 93fea00..ee28c95 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -61,11 +61,17 @@ class ChatBubble extends StatelessWidget { required SingleUserChatModel data, }) async { if (data.voice != null && data.voice!.existsSync()) { - await data.voiceController!.setFilePath(data!.voice!.path); await data.voiceController!.setLoopMode(LoopMode.off); - Duration? duration = await data.voiceController!.load(); - await data.voiceController!.seek(duration); - await data.voiceController!.play(); + if (Platform.isIOS) { + Duration? duration = await data.voiceController!.setAudioSource(MyCustomStream(data.voice!.readAsBytesSync())); + await data.voiceController!.seek(duration); + data.voiceController!.play(); + } else { + await data.voiceController!.setFilePath(data!.voice!.path); + Duration? duration = await data.voiceController!.load(); + await data.voiceController!.seek(duration); + await data.voiceController!.play(); + } } else { Utils.showLoading(context); Uint8List encodedString = await ChatApiClient().downloadURL(fileName: data.contant!, fileTypeDescription: provider.getFileTypeDescription(data.fileTypeResponse!.fileTypeName ?? "")); @@ -74,13 +80,19 @@ class ChatBubble extends StatelessWidget { File file = File(path!); await file.readAsBytes(); data.voice = file; - Duration? duration = await data.voiceController!.setFilePath(file.path); - await data.voiceController!.setLoopMode(LoopMode.off); - await data.voiceController!.seek(duration); - await data.voiceController!.setVolume(1.0); - await data.voiceController!.load(); - Utils.hideLoading(context); - await data.voiceController!.play(); + if (Platform.isIOS) { + Duration? duration = await data.voiceController!.setAudioSource(MyCustomStream(encodedString)); + await data.voiceController!.seek(duration); + data.voiceController!.play(); + } else { + Duration? duration = await data.voiceController!.setFilePath(file.path); + await data.voiceController!.setLoopMode(LoopMode.off); + await data.voiceController!.seek(duration); + await data.voiceController!.setVolume(1.0); + await data.voiceController!.load(); + Utils.hideLoading(context); + await data.voiceController!.play(); + } } catch (e) { Utils.hideLoading(context); Utils.showToast(e.toString()); @@ -114,7 +126,7 @@ class ChatBubble extends StatelessWidget { Widget currentUser(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: [ if (isReplied) ClipRRect( borderRadius: BorderRadius.circular(5.0), @@ -200,7 +212,7 @@ class ChatBubble extends StatelessWidget { ), ), ], - ).paddingOnly(top: 11, left: 13, right: 13, bottom: 5).objectContainerView(disablePadding: true).paddingOnly(left: MediaQuery.of(context).size.width * 0.3); + ).paddingOnly(top: 11, left: 13, right: 13, bottom: 5).objectContainerView(disablePadding: true, radius: 10).paddingOnly(left: MediaQuery.of(context).size.width * 0.3); } Widget receiptUser(BuildContext context) { @@ -340,6 +352,7 @@ class ChatBubble extends StatelessWidget { Widget currentWaveBubble(BuildContext context, SingleUserChatModel data) { return Container( margin: const EdgeInsets.all(0), + constraints: const BoxConstraints(), decoration: BoxDecoration( border: Border( left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white), @@ -411,7 +424,7 @@ class ChatBubble extends StatelessWidget { child: const CircularProgressIndicator(), ); } else if (playing != true) { - return Icon( + return const Icon( Icons.play_arrow, size: 30, color: MyColors.lightGreenColor, @@ -419,7 +432,7 @@ class ChatBubble extends StatelessWidget { playVoice(context, data: modelData); }); } else if (processingState != ProcessingState.completed) { - return Icon( + return const Icon( Icons.pause, size: 30, color: MyColors.lightGreenColor, @@ -427,7 +440,7 @@ class ChatBubble extends StatelessWidget { pausePlaying(context, data: modelData); }); } else { - return Icon( + return const Icon( Icons.replay, size: 30, color: MyColors.lightGreenColor, @@ -439,3 +452,23 @@ class ChatBubble extends StatelessWidget { ); } } + +// Feed your own stream of bytes into the player +class MyCustomStream extends StreamAudioSource { + final Uint8List bytes; + + MyCustomStream(this.bytes); + + @override + Future request([int? start, int? end]) async { + start ??= 0; + end ??= bytes.length; + return StreamAudioResponse( + sourceLength: bytes.length, + contentLength: end - start, + offset: start, + stream: Stream.value(bytes.sublist(start, end)), + contentType: 'audio/aac', + ); + } +} diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 595dc13..f597fe2 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -275,7 +275,6 @@ class _ChatDetailScreenState extends State { : null, ), onChanged: (String val) { - print(val.length); if (val.isNotEmpty) { m.isTextMsg = true; } else { diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 49908dd..bbb3048 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -83,7 +83,7 @@ class _ChatHomeState extends State { children: [ myTab(LocaleKeys.mychats.tr(), 0), myTab(LocaleKeys.favorite.tr(), 1), - AppState().getempStatusIsManager ? myTab("My Team", 2) : const SizedBox(), + AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 2) : const SizedBox(), ], ), ), diff --git a/lib/ui/leave_balance/leave_balance_screen.dart b/lib/ui/leave_balance/leave_balance_screen.dart index 881828e..9fb925c 100644 --- a/lib/ui/leave_balance/leave_balance_screen.dart +++ b/lib/ui/leave_balance/leave_balance_screen.dart @@ -72,7 +72,7 @@ class _LeaveBalanceState extends State { physics: const BouncingScrollPhysics(), padding: const EdgeInsets.all(21), children: [ - BalancesDashboardWidget(LocaleKeys.currentLeaveBalance.tr(), true, selectedEmp: employeeId), + BalancesDashboardWidget(LocaleKeys.currentLeaveBalance.tr(), true, selectedEmp: employeeId, showLoading: false), 12.height, ListView.separated( physics: const NeverScrollableScrollPhysics(), diff --git a/lib/ui/marathon/marathon_provider.dart b/lib/ui/marathon/marathon_provider.dart index 1b825e8..c1338eb 100644 --- a/lib/ui/marathon/marathon_provider.dart +++ b/lib/ui/marathon/marathon_provider.dart @@ -136,6 +136,8 @@ class MarathonProvider extends ChangeNotifier { notifyListeners(); } + // 9c47d281-c5b5-4b5d-a90a-08dacb8cbdb6 + // MarathonI //****************TIMERS********** int sponsorsSecondsCounter = 0; @@ -208,8 +210,6 @@ class MarathonProvider extends ChangeNotifier { } if (totalCurrentQuestionTime == currentGapTime) { - totalCurrentQuestionTime--; - updateCardStatusToAnswer(); scheduleMicrotask(() async { @@ -222,20 +222,23 @@ class MarathonProvider extends ChangeNotifier { }); } }); - } - if (totalCurrentQuestionTime == 0) { - gapTimeImage = currentQuestion.gapImage; - gapTimeText = currentQuestion.gapText; - gapTimeType = currentQuestion.gapType; - updateCardData(); - if (currentQuestionNumber - 1 == marathonDetailModel.totalQuestions!) { + if (currentQuestionNumber == marathonDetailModel.totalQuestions!) { isGettingQualifiers = true; updateQuestionCardStatus(QuestionCardStatus.findingWinner); timer.cancel(); cancelTimer(); notifyListeners(); } + totalCurrentQuestionTime--; + } + + if (totalCurrentQuestionTime == 0) { + gapTimeImage = currentQuestion.gapImage; + gapTimeText = currentQuestion.gapText; + gapTimeType = currentQuestion.gapType; + updateCardData(); + return; } else { if (totalCurrentQuestionTime != currentGapTime) { diff --git a/lib/ui/marathon/widgets/countdown_timer_detail_screen.dart b/lib/ui/marathon/widgets/countdown_timer_detail_screen.dart index 2f5f727..8cc4f93 100644 --- a/lib/ui/marathon/widgets/countdown_timer_detail_screen.dart +++ b/lib/ui/marathon/widgets/countdown_timer_detail_screen.dart @@ -10,6 +10,7 @@ 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'; +import 'package:mohem_flutter_app/ui/marathon/widgets/marathon_banner.dart'; class CountdownTimerForDetailScreen extends StatelessWidget { final int timeToMarathon; @@ -192,7 +193,8 @@ class CountdownTimerForDetailScreen extends StatelessWidget { @override Widget build(BuildContext context) { return CountdownTimer( - endTime: timeToMarathon, + endTime: dummyTime, + // endTime: timeToMarathon, onEnd: null, widgetBuilder: (BuildContext context, CurrentRemainingTime? time) { return buildCountdownTimer(time); diff --git a/lib/ui/marathon/widgets/marathon_progress_container.dart b/lib/ui/marathon/widgets/marathon_progress_container.dart index 29c9d8c..20763b6 100644 --- a/lib/ui/marathon/widgets/marathon_progress_container.dart +++ b/lib/ui/marathon/widgets/marathon_progress_container.dart @@ -31,7 +31,7 @@ class MarathonProgressContainer extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8), child: "${provider.currentQuestionNumber.toString()} / ${provider.marathonDetailModel.totalQuestions.toString()} ${LocaleKeys.question.tr()}".toText12(color: MyColors.white), ), - "${provider.totalMarathoners} ${LocaleKeys.marathoners.tr()}".toText14(), + "${provider.totalMarathoners} ${provider.totalMarathoners == 1 ? LocaleKeys.marathoner.tr() : LocaleKeys.marathoners.tr()}".toText14(), 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) @@ -46,9 +46,7 @@ class MarathonProgressContainer extends StatelessWidget { children: [ "${provider.currentQuestionNumber == 1 ? 0 : (((provider.currentQuestionNumber - 1) / provider.marathonDetailModel.totalQuestions!) * 100).toInt()}% ${LocaleKeys.completed.tr()}" .toText14(), - provider.isUserOutOfGame - ? LocaleKeys.youAreOutOfContest.tr().toText14(color: MyColors.redColor) - : const SizedBox(), + provider.isUserOutOfGame ? LocaleKeys.youAreOutOfContest.tr().toText14(color: MyColors.redColor) : const SizedBox(), ], ), ], @@ -97,21 +95,28 @@ class MarathonProgressContainer extends StatelessWidget { Widget roundContainer(Color color, bool isNeedLeftBorder) { if (isNeedLeftBorder) { return Row( - children: [ - Divider(thickness: 6, color: color).expanded, + children: [ + Divider( + thickness: 6, + color: color, + ).expanded, Container( + margin: EdgeInsets.zero, + padding: EdgeInsets.zero, width: 10, height: 10, - decoration: BoxDecoration(shape: BoxShape.circle, color: color), + decoration: BoxDecoration(shape: BoxShape.circle, color: color, border: Border.all(color: color, width: 2)), ), ], ).expanded; } return Container( + margin: EdgeInsets.zero, + padding: EdgeInsets.zero, width: 10, height: 10, - decoration: BoxDecoration(shape: BoxShape.circle, color: color), + decoration: BoxDecoration(shape: BoxShape.circle, color: color, border: Border.all(color: color, width: 2)), ); } } diff --git a/lib/ui/marathon/widgets/marathon_qualifiers_container.dart b/lib/ui/marathon/widgets/marathon_qualifiers_container.dart index ed5132e..e3c5d00 100644 --- a/lib/ui/marathon/widgets/marathon_qualifiers_container.dart +++ b/lib/ui/marathon/widgets/marathon_qualifiers_container.dart @@ -57,7 +57,7 @@ class _QualifiersContainerState extends State { children: [ 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), + (widget.provider.totalQualifiers == 1 ? LocaleKeys.qualifier.tr() : LocaleKeys.qualifiers.tr()).toText16(color: MyColors.greenColor), ], ), ], diff --git a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart index d06bfdc..b20674e 100644 --- a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart +++ b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart @@ -136,7 +136,6 @@ class _SearchEmployeeBottomSheetState extends State { @override void dispose() { - print("// TODO: implement dispose"); super.dispose(); provider.chatUsersList = []; provider.pageNo = 1;