From 38d37fd4070b7df28b0e36075e67a8e02126e41e Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 4 Sep 2025 14:10:28 +0300 Subject: [PATCH 1/4] custom tab bar added. --- lib/extensions/string_extensions.dart | 6 +- lib/presentation/home/landing_page.dart | 3 + lib/widgets/custom_tab_bar.dart | 121 ++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 lib/widgets/custom_tab_bar.dart diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index b9d4ba8..d118d08 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -164,6 +164,8 @@ extension EmailValidator on String { bool isCenter = false, int? maxlines, TextAlign? textAlign, + FontWeight? weight, + double? letterSpacing = -0.4, }) => Text( this, @@ -172,8 +174,8 @@ extension EmailValidator on String { style: TextStyle( color: color ?? AppColors.blackColor, fontSize: 16.fSize, - letterSpacing: -0.4, - fontWeight: isBold ? FontWeight.bold : FontWeight.normal, + letterSpacing: letterSpacing, + fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), decoration: isUnderLine ? TextDecoration.underline : null, ), ); diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 7435df9..da3249a 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -19,6 +19,7 @@ import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page. import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/bottom_navigation/bottom_navigation.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart' show CustomTabBar; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; @@ -116,6 +117,8 @@ class _LandingPageState extends State { ), ), SizedBox(height: 12.h), + CustomTabBar(), + SizedBox(height: 12.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/widgets/custom_tab_bar.dart b/lib/widgets/custom_tab_bar.dart new file mode 100644 index 0000000..ae0e6f6 --- /dev/null +++ b/lib/widgets/custom_tab_bar.dart @@ -0,0 +1,121 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/int_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; + +class CustomTabBarModel { + String? image; + String title; + + CustomTabBarModel(this.image, this.title); +} + +class CustomTabBar extends StatefulWidget { + final int initialIndex = 0; + final List tabs; + final Color activeTextColor; + final Color activeBackgroundColor; + final Color? inActiveTextColor; + final Color inActiveBackgroundColor; + final Function(int)? onTabChange; + + CustomTabBar( + {Key? key, + this.tabs = const [], + this.activeTextColor = const Color(0xff2E3039), + this.inActiveTextColor = const Color(0xff898A8D), + this.activeBackgroundColor = const Color(0x142E3039), + this.inActiveBackgroundColor = Colors.white, + this.onTabChange}) + : super(key: key); + + @override + _CustomTabBarState createState() { + return _CustomTabBarState(); + } +} + +class _CustomTabBarState extends State { + List tabs = []; + int selectedIndex = 0; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + void callBackCurrentIndex() { + if (widget.onTabChange != null) widget.onTabChange!(selectedIndex); + } + + @override + Widget build(BuildContext context) { + tabs = [ + CustomTabBarModel(null, "By Visit"), + CustomTabBarModel(null, "By Test"), + CustomTabBarModel(null, "By Value"), + CustomTabBarModel(AppAssets.myFilesBottom, "By Value"), + CustomTabBarModel(null, "By Value"), + ]; + + late Widget parentWidget; + + if (tabs.length > 3) { + parentWidget = ListView.separated( + scrollDirection: Axis.horizontal, + padding: EdgeInsets.zero, + physics: const BouncingScrollPhysics(), + itemBuilder: (cxt, index) => myTab(tabs[index], index), + separatorBuilder: (cxt, index) => 4.width, + itemCount: tabs.length, + ); + } else { + parentWidget = Row( + spacing: 4, + children: [for (int i = 0; i < tabs.length; i++) myTab(tabs[i], i).expanded], + ); + } + + return Container( + height: 62.h, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(11), + ), + child: parentWidget); + } + + Widget myTab(CustomTabBarModel tabBar, int currentIndex) { + bool isSelected = selectedIndex == currentIndex; + return Container( + height: 54.h, + padding: EdgeInsets.only(top: 4, bottom: 4, left: 16, right: 16), + alignment: Alignment.center, + decoration: BoxDecoration( + color: isSelected ? widget.activeBackgroundColor : widget.inActiveBackgroundColor, + borderRadius: BorderRadius.circular(7), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + spacing: 4, + children: [ + if (tabBar.image != null) Utils.buildSvgWithAssets(icon: tabBar.image!, height: 18, width: 18, iconColor: isSelected ? Color(0xff2E3039) : Color(0xff898A8D)), + tabBar.title.toText16(weight: isSelected ? FontWeight.w600 : FontWeight.w500, color: isSelected ? Color(0xff2E3039) : Color(0xff898A8D), letterSpacing: isSelected ? -0.3 : -0.1), + ], + )).onPress(() { + setState(() { + selectedIndex = currentIndex; + }); + callBackCurrentIndex(); + }); + } +} From ac0b7bec446dfe2e348958f35e35f371a23ff5e8 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 4 Sep 2025 14:38:55 +0300 Subject: [PATCH 2/4] custom tab bar added in medical file section. --- assets/images/svg/insurance.svg | 4 +++ assets/images/svg/more.svg | 4 +++ assets/images/svg/requests.svg | 5 ++++ lib/core/app_assets.dart | 3 +++ lib/presentation/home/landing_page.dart | 2 -- .../medical_file/medical_file_page.dart | 13 ++++++++++ lib/widgets/custom_tab_bar.dart | 26 +++++++------------ 7 files changed, 38 insertions(+), 19 deletions(-) create mode 100644 assets/images/svg/insurance.svg create mode 100644 assets/images/svg/more.svg create mode 100644 assets/images/svg/requests.svg diff --git a/assets/images/svg/insurance.svg b/assets/images/svg/insurance.svg new file mode 100644 index 0000000..c8d3c38 --- /dev/null +++ b/assets/images/svg/insurance.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/more.svg b/assets/images/svg/more.svg new file mode 100644 index 0000000..4dbe5fd --- /dev/null +++ b/assets/images/svg/more.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/requests.svg b/assets/images/svg/requests.svg new file mode 100644 index 0000000..7d90098 --- /dev/null +++ b/assets/images/svg/requests.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 7d32262..b071112 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -68,6 +68,9 @@ class AppAssets { static const String doctor_calendar_icon = '$svgBasePath/doctor_calendar_icon.svg'; static const String prescription_remarks_icon = '$svgBasePath/prescription_remarks_icon.svg'; static const String prescription_reminder_icon = '$svgBasePath/prescription_reminder_icon.svg'; + static const String insurance = '$svgBasePath/insurance.svg'; + static const String requests = '$svgBasePath/requests.svg'; + static const String more = '$svgBasePath/more.svg'; //bottom navigation// diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 6594f85..301e8bb 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -117,8 +117,6 @@ class _LandingPageState extends State { ), ), SizedBox(height: 12.h), - CustomTabBar(), - SizedBox(height: 12.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 7fa4fe9..703e0b7 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; class MedicalFilePage extends StatelessWidget { @@ -161,6 +162,18 @@ class MedicalFilePage extends StatelessWidget { ), ), SizedBox(height: 16.h), + CustomTabBar( + activeTextColor: Color(0xffED1C2B), + activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), + tabs: [ + CustomTabBarModel(AppAssets.myFilesBottom, "General"), + CustomTabBarModel(AppAssets.insurance, "Insurance"), + CustomTabBarModel(AppAssets.requests, "Requests"), + CustomTabBarModel(AppAssets.more, "More"), + ], + onTabChange: (index) {}, + ), + SizedBox(height: 16.h), //Insurance Tab Data Container( // height: 150.h, diff --git a/lib/widgets/custom_tab_bar.dart b/lib/widgets/custom_tab_bar.dart index ae0e6f6..b6c8ef3 100644 --- a/lib/widgets/custom_tab_bar.dart +++ b/lib/widgets/custom_tab_bar.dart @@ -18,13 +18,13 @@ class CustomTabBar extends StatefulWidget { final List tabs; final Color activeTextColor; final Color activeBackgroundColor; - final Color? inActiveTextColor; + final Color inActiveTextColor; final Color inActiveBackgroundColor; final Function(int)? onTabChange; CustomTabBar( {Key? key, - this.tabs = const [], + required this.tabs, this.activeTextColor = const Color(0xff2E3039), this.inActiveTextColor = const Color(0xff898A8D), this.activeBackgroundColor = const Color(0x142E3039), @@ -39,7 +39,6 @@ class CustomTabBar extends StatefulWidget { } class _CustomTabBarState extends State { - List tabs = []; int selectedIndex = 0; @override @@ -58,29 +57,21 @@ class _CustomTabBarState extends State { @override Widget build(BuildContext context) { - tabs = [ - CustomTabBarModel(null, "By Visit"), - CustomTabBarModel(null, "By Test"), - CustomTabBarModel(null, "By Value"), - CustomTabBarModel(AppAssets.myFilesBottom, "By Value"), - CustomTabBarModel(null, "By Value"), - ]; - late Widget parentWidget; - if (tabs.length > 3) { + if (widget.tabs.length > 3) { parentWidget = ListView.separated( scrollDirection: Axis.horizontal, padding: EdgeInsets.zero, physics: const BouncingScrollPhysics(), - itemBuilder: (cxt, index) => myTab(tabs[index], index), + itemBuilder: (cxt, index) => myTab(widget.tabs[index], index), separatorBuilder: (cxt, index) => 4.width, - itemCount: tabs.length, + itemCount: widget.tabs.length, ); } else { parentWidget = Row( spacing: 4, - children: [for (int i = 0; i < tabs.length; i++) myTab(tabs[i], i).expanded], + children: [for (int i = 0; i < widget.tabs.length; i++) myTab(widget.tabs[i], i).expanded], ); } @@ -108,8 +99,9 @@ class _CustomTabBarState extends State { mainAxisSize: MainAxisSize.min, spacing: 4, children: [ - if (tabBar.image != null) Utils.buildSvgWithAssets(icon: tabBar.image!, height: 18, width: 18, iconColor: isSelected ? Color(0xff2E3039) : Color(0xff898A8D)), - tabBar.title.toText16(weight: isSelected ? FontWeight.w600 : FontWeight.w500, color: isSelected ? Color(0xff2E3039) : Color(0xff898A8D), letterSpacing: isSelected ? -0.3 : -0.1), + if (tabBar.image != null) Utils.buildSvgWithAssets(icon: tabBar.image!, height: 18, width: 18, iconColor: isSelected ? widget.activeTextColor : widget.inActiveTextColor), + tabBar.title + .toText16(weight: isSelected ? FontWeight.w600 : FontWeight.w500, color: isSelected ? widget.activeTextColor : widget.inActiveTextColor, letterSpacing: isSelected ? -0.3 : -0.1), ], )).onPress(() { setState(() { From d385d0362ffacaf9bb1b305e881dce74ab5dd2c0 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 4 Sep 2025 16:43:29 +0300 Subject: [PATCH 3/4] merge changes --- lib/core/utils/calendar_utils.dart | 93 +++++++++++++++++++ lib/extensions/string_extensions.dart | 13 ++- .../medical_file/medical_file_page.dart | 8 +- .../prescription_detail_page.dart | 1 + lib/services/permission_service.dart | 92 ++++++++++++++++++ pubspec.yaml | 1 + 6 files changed, 197 insertions(+), 11 deletions(-) create mode 100644 lib/services/permission_service.dart diff --git a/lib/core/utils/calendar_utils.dart b/lib/core/utils/calendar_utils.dart index 8786f7f..54b550f 100644 --- a/lib/core/utils/calendar_utils.dart +++ b/lib/core/utils/calendar_utils.dart @@ -4,7 +4,12 @@ import 'dart:io'; import 'dart:ui'; import 'package:device_calendar/device_calendar.dart'; +import 'package:flutter/widgets.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/services/permission_service.dart'; +import 'package:jiffy/jiffy.dart'; import 'package:manage_calendar_events/manage_calendar_events.dart' as ios; +import 'package:permission_handler/permission_handler.dart'; import 'package:timezone/data/latest.dart' as tzl; final DeviceCalendarPlugin deviceCalendarPlugin = DeviceCalendarPlugin(); @@ -44,6 +49,94 @@ class CalendarUtils { // return _completer!.future; // } + Future> requestPermissions() async { + var permissionResults = [Permission.calendarFullAccess].request(); + return permissionResults; + } + + // showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, + // {required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false}) async { + // if (Platform.isAndroid) { + // if (await PermissionService.isCalendarPermissionEnabled()) { + // _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + // onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + // } else { + // // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async { + // // if (await Permission.calendarFullAccess.request().isGranted) { + // // _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + // // onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + // // } + // // }); + // } + // } else { + // if (await Permission.calendarWriteOnly.request().isGranted) { + // if (await Permission.calendarFullAccess.request().isGranted) { + // _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + // onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + // } + // } + // } + // } + + // Future _showReminderDialog(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, + // {required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async { + // return showDialog( + // context: providedContext, + // barrierDismissible: true, // user must tap button! + // builder: (BuildContext context) { + // return Dialog( + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0.0)), + // insetPadding: EdgeInsets.all(21), + // child: ReminderDialog( + // onClick: (int i) async { + // String text = ""; + // if (i == 0) { + // // Before 30 mints + // dateTime = Jiffy.parseFromDateTime(dateTime).subtract(minutes: 30).dateTime; + // text = "30 minutes"; + // // dateTime.add(new Duration(minutes: -30)); + // } else if (i == 1) { + // // Before 1 hour + // // dateTime.add(new Duration(minutes: -60)); + // dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 1).dateTime; + // text = "1 hours"; + // } else if (i == 2) { + // // Before 1 hour and 30 mints + // // dateTime.add(new Duration(minutes: -90)); + // dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 1, minutes: 30).dateTime; + // text = "1 hours 30 minutes"; + // } else if (i == 3) { + // // Before 2 hours + // // dateTime.add(new Duration(minutes: -120)); + // dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 2).dateTime; + // text = "2 hours"; + // } + // if (!isMultiAllowed!) { + // if (onMultiDateSuccess == null) { + // CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + // await calendarUtils.createOrUpdateEvent( + // title: title ?? "TranslationBase.of(providedContext).reminderTitle".needTranslation + " " + doctorName, + // description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, + // scheduleDateTime: dateTime, + // eventId: eventId, location: ''); + // onSuccess(); + // } + // } else { + // onMultiDateSuccess!(i); + // } + // // await _analytics.logEvent( + // // name: name.trim().toLowerCase(), + // // parameters: safeParameters, + // // ); + // // todo @sikander discuss analytics for reminder + // // locator().appointment.appointment_reminder_time(reminde_before: text); + // }, + // ), + // ); + // }, + // ); + // } + static Future getInstance() async { tzl.initializeTimeZones(); if (_completer != null) { diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index d986de1..a2bb6d1 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -13,6 +13,8 @@ extension CapExtension on String { String get allInCaps => this.toUpperCase(); + String get needTranslation => this; + String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : ""; } @@ -230,14 +232,11 @@ extension EmailValidator on String { style: TextStyle(height: height ?? 23 / 26, color: color ?? AppColors.blackColor, fontSize: 26.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), ); - Widget toText28({Color? color, bool isBold = false, double? height, bool isCenter = false}) => Text( - this, - textAlign: isCenter ? TextAlign.center : null, - style: TextStyle(height: height ?? 23 / 28, color: color ?? AppColors.blackColor, fontSize: 28.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), - ); - - + this, + textAlign: isCenter ? TextAlign.center : null, + style: TextStyle(height: height ?? 23 / 28, color: color ?? AppColors.blackColor, fontSize: 28.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), + ); Widget toText32({Color? color, bool isBold = false, bool isCenter = false}) => Text( this, diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 36e4892..ac652cb 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -173,10 +173,10 @@ class MedicalFilePage extends StatelessWidget { activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ - CustomTabBarModel(AppAssets.myFilesBottom, "General"), - CustomTabBarModel(AppAssets.insurance, "Insurance"), - CustomTabBarModel(AppAssets.requests, "Requests"), - CustomTabBarModel(AppAssets.more, "More"), + CustomTabBarModel(AppAssets.myFilesBottom, "General".needTranslation), + CustomTabBarModel(AppAssets.insurance, "Insurance".needTranslation), + CustomTabBarModel(AppAssets.requests, "Requests".needTranslation), + CustomTabBarModel(AppAssets.more, "More".needTranslation), ], onTabChange: (index) {}, ), diff --git a/lib/presentation/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart index 65dc550..1f8e0a2 100644 --- a/lib/presentation/prescriptions/prescription_detail_page.dart +++ b/lib/presentation/prescriptions/prescription_detail_page.dart @@ -313,6 +313,7 @@ class _PrescriptionDetailPageState extends State { SizedBox(width: 12.h), Switch( activeColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: .15), value: prescriptionVM.prescriptionDetailsList[index].hasReminder!, onChanged: (newValue) { setState(() { diff --git a/lib/services/permission_service.dart b/lib/services/permission_service.dart new file mode 100644 index 0000000..6287234 --- /dev/null +++ b/lib/services/permission_service.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; + +import 'package:permission_handler/permission_handler.dart'; + +// import 'package:vibration/vibration.dart'; +import 'package:geolocator/geolocator.dart' as geo; + +class PermissionService { + // final LocalStorage storage = new LocalStorage("permission"); + geo.LocationPermission? locationPermission; + + // AppGlobal appGlobal = new AppGlobal(); + + // setVibrationPermission(flag) async { + // storage.setItem('isVibration', flag); + // } + // + // isVibrationEnabled() { + // return (storage.getItem('isVibration') == null) || + // (storage.getItem('isVibration')) == false + // ? false + // : true; + // } + + // vibrate(callback, context) async { + // if (callback == null) return null; + // if (isVibrationEnabled() == true) { + // // if (await Vibration.hasVibrator() !=null) { + // // Vibration.vibrate(duration: 100); + // // callback(); + // // } + // } else { + // callback(); + // } + // } + + // setTheme(flag) async { + // storage.setItem('isTheme', flag); + // } + // + // isThemeEnabled() { + // return storage.getItem('isTheme'); + // } + + cameraPermission() async { + Map statuses = await [ + Permission.camera, + ].request(); + } + + static isCameraEnabled() async { + return await Permission.camera.isGranted; + } + + static isExternalStorageEnabled() async { + return await Permission.storage.isGranted; + } + + static isHealthDataPermissionEnabled() async { + return await Permission.sensors.isGranted; + } + + static isMicrophonePermissionEnabled() async { + return await Permission.microphone.isGranted; + } + + static isCalendarPermissionEnabled() async { + return await Permission.calendarFullAccess.isGranted; + } + + setCameraLocationPermission(context) async { + Navigator.pop(context); + openAppSettings(); + } + + static isLocationEnabled() async { + var permission = await geo.Geolocator.checkPermission(); + if (permission == geo.LocationPermission.denied) { + return false; + } else { + return true; + } + } + + openSettings() async { + openAppSettings(); + } + + openAccessbility() { + // OpenSettings.openAppSetting(); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index cfb94d4..829970a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -64,6 +64,7 @@ dependencies: equatable: ^2.0.7 google_api_availability: ^5.0.1 firebase_analytics: ^11.5.1 + jiffy: ^6.4.3 web: any flutter_staggered_animations: ^1.1.1 From 2d5f2b1deb378b273ba83ace01f9c270e5137ddd Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 4 Sep 2025 16:46:12 +0300 Subject: [PATCH 4/4] updates --- lib/extensions/string_extensions.dart | 28 +++++++++++++-------------- pubspec.yaml | 1 + 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index a2bb6d1..0f04824 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -30,7 +30,7 @@ extension EmailValidator on String { fontStyle: fontStyle ?? FontStyle.normal, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, - letterSpacing: -0.4, + letterSpacing: -1, ), ); @@ -43,7 +43,7 @@ extension EmailValidator on String { fontStyle: fontStyle ?? FontStyle.normal, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, - letterSpacing: -0.4, + letterSpacing: -1, decoration: isUnderLine ? TextDecoration.underline : null, decorationColor: color ?? AppColors.blackColor), ); @@ -57,7 +57,7 @@ extension EmailValidator on String { fontSize: 11.fSize, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, - letterSpacing: -0.4, + letterSpacing: -1, decoration: isUnderLine ? TextDecoration.underline : null, ), ); @@ -70,7 +70,7 @@ extension EmailValidator on String { fontSize: 12.fSize, fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, - letterSpacing: -0.4, + letterSpacing: -1, height: height, decorationColor: isUnderLine ? AppColors.blackColor : null, decoration: isUnderLine ? TextDecoration.underline : null, @@ -86,7 +86,7 @@ extension EmailValidator on String { fontSize: 12.fSize, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, - letterSpacing: -0.4, + letterSpacing: -1, decoration: isUnderLine ? TextDecoration.underline : null, ), ); @@ -134,7 +134,7 @@ extension EmailValidator on String { fontSize: 13.fSize, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, - letterSpacing: -0.4, + letterSpacing: -1, decoration: isUnderLine ? TextDecoration.underline : null), ); @@ -145,7 +145,7 @@ extension EmailValidator on String { style: TextStyle( color: color ?? AppColors.blackColor, fontSize: 14.fSize, - letterSpacing: -0.4, + letterSpacing: -1, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), decoration: isUnderLine ? TextDecoration.underline : null), ); @@ -157,7 +157,7 @@ extension EmailValidator on String { style: TextStyle( color: color ?? AppColors.blackColor, fontSize: 15.fSize, - letterSpacing: -0.4, + letterSpacing: -1, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), decoration: isUnderLine ? TextDecoration.underline : null), ); @@ -188,7 +188,7 @@ extension EmailValidator on String { Widget toText17({Color? color, bool isBold = false, bool isCenter = false}) => Text( this, textAlign: isCenter ? TextAlign.center : null, - style: TextStyle(color: color ?? AppColors.blackColor, fontSize: 17.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), + style: TextStyle(color: color ?? AppColors.blackColor, fontSize: 17.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), ); Widget toText18({Color? color, bool isBold = false, bool isCenter = false, int? maxlines}) => Text( @@ -211,19 +211,19 @@ extension EmailValidator on String { Widget toText21({Color? color, bool isBold = false, FontWeight? weight, int? maxlines}) => Text( this, maxLines: maxlines, - style: TextStyle(color: color ?? AppColors.blackColor, fontSize: 21.fSize, letterSpacing: -0.4, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal)), + style: TextStyle(color: color ?? AppColors.blackColor, fontSize: 21.fSize, letterSpacing: -1, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal)), ); Widget toText22({Color? color, bool isBold = false, bool isCenter = false}) => Text( this, textAlign: isCenter ? TextAlign.center : null, - style: TextStyle(height: 1, color: color ?? AppColors.blackColor, fontSize: 22.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), + style: TextStyle(height: 1, color: color ?? AppColors.blackColor, fontSize: 22.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), ); Widget toText24({Color? color, bool isBold = false, bool isCenter = false}) => Text( this, textAlign: isCenter ? TextAlign.center : null, - style: TextStyle(height: 23 / 24, color: color ?? AppColors.blackColor, fontSize: 24.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), + style: TextStyle(height: 23 / 24, color: color ?? AppColors.blackColor, fontSize: 24.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), ); Widget toText26({Color? color, bool isBold = false, double? height, bool isCenter = false}) => Text( @@ -241,12 +241,12 @@ extension EmailValidator on String { Widget toText32({Color? color, bool isBold = false, bool isCenter = false}) => Text( this, textAlign: isCenter ? TextAlign.center : null, - style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 32.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), + style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 32.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), ); Widget toText44({Color? color, bool isBold = false}) => Text( this, - style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), + style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), ); Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) { diff --git a/pubspec.yaml b/pubspec.yaml index 0f02a05..6bcaa36 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,6 +65,7 @@ dependencies: google_api_availability: ^5.0.1 firebase_analytics: ^11.5.1 jiffy: ^6.4.3 + hijri_gregorian_calendar: ^0.0.4 web: any flutter_staggered_animations: ^1.1.1