diff --git a/lib/constants/app_constants.dart b/lib/constants/app_constants.dart index ed1f8eb..c9a44fe 100644 --- a/lib/constants/app_constants.dart +++ b/lib/constants/app_constants.dart @@ -4,10 +4,16 @@ import 'package:logger/logger.dart'; bool useTestIP = false; Logger logger = Logger(printer: PrettyPrinter(printEmojis: false, colors: true, dateTimeFormat: DateTimeFormat.none)); +// app globals + +bool isNeedToBreakVoiceForArabic = true; +bool isSpeechCompleted = true; + class AppStrings { static String poweredBy = "Powered By"; static String appName = "QLine"; - static String fontName = "Poppins"; + static String fontNamePoppins = "Poppins"; + static String fontNameCairo = "Cairo"; static String noInternetConnection = "No Internet Connection"; static String awaitingArrivalEng = "Awaiting Patients Arrival"; static String awaitingArrivalAr = "في انتظار وصول المرضى"; diff --git a/lib/main.dart b/lib/main.dart index 48a80ff..1214523 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -36,7 +36,7 @@ class MyApp extends StatelessWidget { showSemanticsDebugger: false, title: AppStrings.appName, theme: ThemeData( - fontFamily: AppStrings.fontName, + fontFamily: AppStrings.fontNamePoppins, colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.grey).copyWith( surface: const Color.fromRGBO(255, 255, 255, 1), ), diff --git a/lib/services/text_to_speech_service.dart b/lib/services/text_to_speech_service.dart index 8b2da7f..fd46990 100644 --- a/lib/services/text_to_speech_service.dart +++ b/lib/services/text_to_speech_service.dart @@ -1,12 +1,11 @@ import 'dart:developer'; import 'package:flutter_tts/flutter_tts.dart'; +import 'package:hmg_qline/constants/app_constants.dart'; import 'package:hmg_qline/models/global_config_model.dart'; import 'package:hmg_qline/models/ticket_model.dart'; import 'package:hmg_qline/utilities/enums.dart'; import 'package:hmg_qline/utilities/extensions.dart'; -bool isNeedToBreakVoiceForArabic = true; - abstract class TextToSpeechService { Future speechText({ required TicketDetailsModel ticket, @@ -54,7 +53,7 @@ class TextToSpeechServiceImp implements TextToSpeechService { if (langEnum == LanguageEnum.arabic) { await textToSpeechInstance.setLanguage(LanguageEnum.arabic.enumToString()); textToSpeechInstance.setSpeechRate(0.45); - textToSpeechInstance.setPitch(0.8); + textToSpeechInstance.setPitch(0.9); } else if (langEnum == LanguageEnum.english) { await textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString()); textToSpeechInstance.setSpeechRate(0.37); @@ -101,13 +100,18 @@ class TextToSpeechServiceImp implements TextToSpeechService { } if (isNeedToBreakVoiceForArabic) { + isSpeechCompleted = false; if (preVoice.isNotEmpty) { await textToSpeechInstance.speak("$preVoice "); } textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString()); await textToSpeechInstance.speak(" $patientAlpha .. $patientNumeric .. "); - await textToSpeechInstance.setLanguage(langEnum.enumToString()); - await textToSpeechInstance.speak(" $postVoice $roomNo"); + textToSpeechInstance.setLanguage(langEnum.enumToString()); + await textToSpeechInstance.speak(" $postVoice "); + textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString()); + await textToSpeechInstance.speak(roomNo).whenComplete(() { + isSpeechCompleted = true; + }); } else { await textToSpeechInstance.speak("$preVoice $patientAlpha .. .. $patientNumeric .. .. $postVoice $roomNo"); } diff --git a/lib/view_models/queuing_view_model.dart b/lib/view_models/queuing_view_model.dart index 17affbc..358e067 100644 --- a/lib/view_models/queuing_view_model.dart +++ b/lib/view_models/queuing_view_model.dart @@ -93,12 +93,15 @@ class QueuingViewModel extends ChangeNotifier { } Future onVoiceCompleted() async { - waitAndCallNextTicketIfThere(); + log("isSpeechCompleted::: $isSpeechCompleted"); + if (isSpeechCompleted) { + waitAndCallNextTicketIfThere(); + } } waitAndCallNextTicketIfThere() { GlobalConfigurationsModel globalConfigurationsModel = getIt.get().globalConfigurationsModel; - Timer(Duration(seconds: globalConfigurationsModel.concurrentCallDelaySec ?? 1), () async { + Timer(Duration(seconds: globalConfigurationsModel.concurrentCallDelaySec), () async { if (queueTickets.isNotEmpty) { currentTickets.insert(0, queueTickets.first); if (currentTickets.length > globalConfigurationsModel.screenMaxDisplayPatients) { diff --git a/lib/view_models/screen_config_view_model.dart b/lib/view_models/screen_config_view_model.dart index 9c5df9b..e2b8338 100644 --- a/lib/view_models/screen_config_view_model.dart +++ b/lib/view_models/screen_config_view_model.dart @@ -279,7 +279,7 @@ class ScreenConfigViewModel extends ChangeNotifier { } Future createAutoTickets({required int numOfTicketsToCreate}) async { - int startTicket = 123456920; + int startTicket = 123456980; for (int i = 0; i < numOfTicketsToCreate; i++) { GenericRespModel? response = await screenDetailsRepo.createNextTickets(ticketNumber: startTicket); diff --git a/lib/views/common_widgets/app_footer.dart b/lib/views/common_widgets/app_footer.dart index 1486be6..340757d 100644 --- a/lib/views/common_widgets/app_footer.dart +++ b/lib/views/common_widgets/app_footer.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:hmg_qline/view_models/queuing_view_model.dart'; import 'package:hmg_qline/view_models/screen_config_view_model.dart'; import 'package:marquee/marquee.dart'; import 'package:provider/provider.dart'; @@ -95,7 +94,11 @@ class AppFooter extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 10), child: Marquee( text: screenConfigVM.rssFeedModel.rssFeed ?? "", - style: TextStyle(fontWeight: FontWeight.w500, fontSize: SizeConfig.getWidthMultiplier() * 4), + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: SizeConfig.getWidthMultiplier() * 4, + fontFamily: AppStrings.fontNamePoppins, + ), scrollAxis: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.center, blankSpace: 20.0, diff --git a/lib/views/common_widgets/app_header.dart b/lib/views/common_widgets/app_header.dart index 04874a3..a06f365 100644 --- a/lib/views/common_widgets/app_header.dart +++ b/lib/views/common_widgets/app_header.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:hmg_qline/models/global_config_model.dart'; +import 'package:hmg_qline/utilities/enums.dart'; import 'package:hmg_qline/view_models/screen_config_view_model.dart'; import 'package:provider/provider.dart'; import 'package:hmg_qline/constants/app_constants.dart'; @@ -73,7 +74,11 @@ class AppHeader extends StatelessWidget implements PreferredSizeWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ - AppText(globalConfigurationsModel.currentServeText ?? "", color: Colors.white), + AppText( + globalConfigurationsModel.currentServeText ?? "", + color: Colors.white, + fontFamily: globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, + ), SvgPicture.asset( AppAssets.hmgLogo, height: SizeConfig.getHeightMultiplier() * 0.5, diff --git a/lib/views/common_widgets/app_texts_widget.dart b/lib/views/common_widgets/app_texts_widget.dart index b65d657..13a4d85 100644 --- a/lib/views/common_widgets/app_texts_widget.dart +++ b/lib/views/common_widgets/app_texts_widget.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:hmg_qline/constants/app_constants.dart'; import 'package:hmg_qline/views/view_helpers/size_config.dart'; class AppText extends StatefulWidget { @@ -112,7 +113,7 @@ class AppTextState extends State { ? _getFontStyle()?.copyWith( fontStyle: widget.italic ? FontStyle.italic : null, color: widget.color, - fontFamily: 'Poppins', + fontFamily: widget.fontFamily, fontWeight: widget.fontWeight ?? _getFontWeight(), height: widget.fontHeight, ) @@ -122,7 +123,7 @@ class AppTextState extends State { fontSize: widget.fontSize ?? _getFontSize(), letterSpacing: widget.letterSpacing ?? (widget.variant == "overline" ? 1.5 : null), fontWeight: widget.fontWeight ?? _getFontWeight(), - fontFamily: 'Poppins', + fontFamily: widget.fontFamily, decoration: widget.textDecoration, height: widget.fontHeight), ) diff --git a/lib/views/main_queue_screen/components/priority_tickets.dart b/lib/views/main_queue_screen/components/priority_tickets.dart index a145a69..77c91ae 100644 --- a/lib/views/main_queue_screen/components/priority_tickets.dart +++ b/lib/views/main_queue_screen/components/priority_tickets.dart @@ -29,6 +29,7 @@ class PriorityTickets extends StatelessWidget { textDirection: globalConfigurationsModel.textDirection, message: globalConfigurationsModel.ticketNoText, screenTypeEnum: globalConfigurationsModel.screenTypeEnum, + langTypeEnum: globalConfigurationsModel.screenLanguageEnum, ), if (tickets.length > 1) ...[ // SizedBox(height: SizeConfig.getHeightMultiplier() * 0.8), @@ -47,6 +48,8 @@ class PriorityTickets extends StatelessWidget { textDirection: globalConfigurationsModel.textDirection, message: globalConfigurationsModel.ticketNoText, screenTypeEnum: globalConfigurationsModel.screenTypeEnum, + langTypeEnum: globalConfigurationsModel.screenLanguageEnum, + ), ), ) diff --git a/lib/views/main_queue_screen/components/priority_tickets_sidelist.dart b/lib/views/main_queue_screen/components/priority_tickets_sidelist.dart index 65b79c8..9e68f77 100644 --- a/lib/views/main_queue_screen/components/priority_tickets_sidelist.dart +++ b/lib/views/main_queue_screen/components/priority_tickets_sidelist.dart @@ -51,6 +51,7 @@ class PriorityTicketsSidelist extends StatelessWidget { fontWeight: FontWeight.bold, fontSize: SizeConfig.getWidthMultiplier() * 3.8, textAlign: TextAlign.center, + fontFamily: globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), ], ), @@ -95,6 +96,7 @@ class PriorityTicketsSidelist extends StatelessWidget { fontWeight: FontWeight.bold, fontSize: SizeConfig.getWidthMultiplier() * 3.8, textAlign: TextAlign.center, + fontFamily: globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), ], ), @@ -127,6 +129,7 @@ class PriorityTicketsSidelist extends StatelessWidget { fontWeight: FontWeight.bold, fontSize: SizeConfig.getWidthMultiplier() * 3.5, textAlign: TextAlign.center, + fontFamily: globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), ], ), @@ -172,6 +175,7 @@ class PriorityTicketsSidelist extends StatelessWidget { fontSize: SizeConfig.getWidthMultiplier() * 3.3, fontWeight: FontWeight.w600, fontHeight: 0.5, + fontFamily: globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), ], ), diff --git a/lib/views/main_queue_screen/components/ticket_item.dart b/lib/views/main_queue_screen/components/ticket_item.dart index a4ebc51..3af78e6 100644 --- a/lib/views/main_queue_screen/components/ticket_item.dart +++ b/lib/views/main_queue_screen/components/ticket_item.dart @@ -15,6 +15,7 @@ class TicketItem extends StatelessWidget { final String message; final String roomText; final ScreenTypeEnum screenTypeEnum; + final LanguageEnum langTypeEnum; const TicketItem({ super.key, @@ -26,6 +27,7 @@ class TicketItem extends StatelessWidget { required this.message, required this.roomText, required this.screenTypeEnum, + required this.langTypeEnum, this.blink = false, }); @@ -50,6 +52,7 @@ class TicketItem extends StatelessWidget { letterSpacing: -1, height: 0.5, fontWeight: FontWeight.bold, + fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), beginColor: Colors.black, endColor: blink ? Colors.black.withOpacity(0.1) : Colors.black, @@ -72,6 +75,7 @@ class TicketItem extends StatelessWidget { fontSize: SizeConfig.getWidthMultiplier() * 3.8, fontWeight: FontWeight.w600, fontHeight: 1, + fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), Container( color: Colors.grey.withOpacity(0.5), @@ -86,6 +90,7 @@ class TicketItem extends StatelessWidget { fontSize: SizeConfig.getWidthMultiplier() * 3.8, fontWeight: FontWeight.w600, fontHeight: 1, + fontFamily: langTypeEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), ], ), diff --git a/lib/views/main_queue_screen/main_queue_screen.dart b/lib/views/main_queue_screen/main_queue_screen.dart index 50ac8a1..ddad9ee 100644 --- a/lib/views/main_queue_screen/main_queue_screen.dart +++ b/lib/views/main_queue_screen/main_queue_screen.dart @@ -22,7 +22,8 @@ class MainQueueScreen extends StatelessWidget { return const SizedBox.shrink(); } return Container( - height: (screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) + height: (screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || + screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) ? SizeConfig.getHeightMultiplier() * 2 : SizeConfig.getHeightMultiplier() * 0.9, padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10), @@ -41,11 +42,13 @@ class MainQueueScreen extends StatelessWidget { screenConfigViewModel.globalConfigurationsModel.weatherText, color: Colors.grey, fontSize: SizeConfig.getWidthMultiplier() * 2, + fontFamily: screenConfigViewModel.globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), AppText( "${screenConfigViewModel.globalConfigurationsModel.maxText}: ${screenConfigViewModel.weathersWidgetModel.maxTemp}°C , ${screenConfigViewModel.globalConfigurationsModel.minText}: ${screenConfigViewModel.weathersWidgetModel.minTemp}°C", fontSize: SizeConfig.getWidthMultiplier() * 3, fontHeight: 1, + fontFamily: screenConfigViewModel.globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), ], ), @@ -66,7 +69,8 @@ class MainQueueScreen extends StatelessWidget { } return SizedBox( child: Container( - height: (screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) + height: (screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || + screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) ? SizeConfig.getHeightMultiplier() * 2 : SizeConfig.getHeightMultiplier() * 0.9, padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10), @@ -85,11 +89,13 @@ class MainQueueScreen extends StatelessWidget { screenConfigViewModel.globalConfigurationsModel.nextPrayerText, color: Colors.grey, fontSize: SizeConfig.getWidthMultiplier() * 1.5, + fontFamily: screenConfigViewModel.globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), AppText( screenConfigViewModel.nextPrayerToShowWithTime, fontSize: SizeConfig.getWidthMultiplier() * 3, fontHeight: 1, + fontFamily: screenConfigViewModel.globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), ], ), @@ -105,10 +111,11 @@ class MainQueueScreen extends StatelessWidget { ); } - Widget noPatientInQueue(String text) { + Widget noPatientInQueue({required String text, required String fontName}) { return Center( child: AppText( text, + fontFamily: fontName, textAlign: TextAlign.center, fontSize: SizeConfig.getWidthMultiplier() * 9, ), @@ -132,12 +139,14 @@ class MainQueueScreen extends StatelessWidget { builder: (BuildContext context, ScreenConfigViewModel screenConfigViewModel, QueuingViewModel queuingViewModel, Widget? child) { Widget widget = const SizedBox(); String text = AppStrings.awaitingArrivalEng; + String fontFamily = AppStrings.fontNamePoppins; // queuingViewModel.voiceCallTicket(ticketData: queuingViewModel.currentTickets.first.ticketModel); if (screenConfigViewModel.globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic) { text = AppStrings.awaitingArrivalAr; + fontFamily = AppStrings.fontNameCairo; } if (queuingViewModel.currentTickets.isEmpty) { - widget = noPatientInQueue(text); + widget = noPatientInQueue(text: text, fontName: fontFamily); } else if (screenConfigViewModel.globalConfigurationsModel.screenTypeEnum == ScreenTypeEnum.roomLevelScreen) { widget = PriorityTickets( tickets: [queuingViewModel.currentTickets.first], @@ -165,13 +174,15 @@ class MainQueueScreen extends StatelessWidget { int flex = 1; if (screenConfigVM.currentScreenTypeEnum == ScreenTypeEnum.roomLevelScreen) { - if (screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) { + if (screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || + screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) { flex = 2; } else { flex = 3; } } else { - if (screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) { + if (screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || + screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown) { flex = 2; } else { flex = 1; @@ -219,6 +230,8 @@ class MainQueueScreen extends StatelessWidget { selector: (context, screenConfigViewModel) => screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum, builder: (BuildContext context, ScreenOrientationEnum screenOrientationEnum, Widget? child) { //TODO: For Testing Only + // context.read().createAutoTickets(numOfTicketsToCreate: 20); + // // context.read().voiceCallTicket(ticketData: context.read().currentTickets.first.ticketModel); return RotatedBox( quarterTurns: screenOrientationEnum.getTurnsByOrientation(), diff --git a/pubspec.yaml b/pubspec.yaml index c041237..42341f0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -102,16 +102,12 @@ flutter: weight: 900 - family: Cairo fonts: - - asset: assets/fonts/Cairo/Cairo-Light/Cairo-Light.eot - asset: assets/fonts/Cairo/Cairo-Light/Cairo-Light.otf - asset: assets/fonts/Cairo/Cairo-Light/Cairo-Light.ttf - - asset: assets/fonts/Cairo/Cairo-Light/Cairo-Light.woff weight: 300 - asset: assets/fonts/Cairo/Cairo-Regular/Cairo-Regular.ttf weight: 400 - - asset: assets/fonts/Cairo/Cairo-Bold/Cairo-Bold.eot - asset: assets/fonts/Cairo/Cairo-Bold/Cairo-Bold.otf - asset: assets/fonts/Cairo/Cairo-Bold/Cairo-Bold.ttf - - asset: assets/fonts/Cairo/Cairo-Bold/Cairo-Bold.woff weight: 700