From 12a81dc24229795f7874ede4750718fe9ec1c21c Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sat, 10 Feb 2024 12:46:10 +0530 Subject: [PATCH 1/9] [Feature] Lap(Flag) of TimeInterval added --- .../views/add_or_update_alarm_view.dart | 411 +++------------ .../alarmRing/views/alarm_ring_view.dart | 481 ++++++++++-------- .../controllers/stopwatch_controller.dart | 21 +- .../stopwatch/views/stopwatch_view.dart | 271 ++++++---- lib/main.dart | 15 +- 5 files changed, 544 insertions(+), 655 deletions(-) diff --git a/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart b/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart index a2229623..cfa9ec74 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart'; + import 'package:get/get.dart'; -import 'package:numberpicker/numberpicker.dart'; import 'package:ultimate_alarm_clock/app/data/models/alarm_model.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/controllers/input_time_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/alarm_id_tile.dart'; @@ -151,9 +152,8 @@ class AddOrUpdateAlarmView extends GetView { ), onPressed: () async { Utils.hapticFeedback(); - if (controller.userModel.value != null) { - controller - .offsetDetails[controller.userModel.value!.id] = { + if (controller.userModel != null) { + controller.offsetDetails[controller.userModel!.id] = { 'offsettedTime': Utils.timeOfDayToString( TimeOfDay.fromDateTime( Utils.calculateOffsetAlarmTime( @@ -282,12 +282,9 @@ class AddOrUpdateAlarmView extends GetView { ? const Text('') : Obx( () => Text( - 'Rings in @timeToAlarm'.trParams( - { - 'timeToAlarm': - controller.timeToAlarm.value.toString(), - }, - ), + 'in @timeToAlarm'.trParams({ + 'timeToAlarm': controller.timeToAlarm.value.toString() + }), style: Theme.of(context).textTheme.titleSmall, ), ), @@ -359,313 +356,55 @@ class AddOrUpdateAlarmView extends GetView { : ListView( children: [ Container( - color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - height: height * 0.32, - width: width, - child: Obx( - () { + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + height: height * 0.32, + width: width, + child: Obx(() { return InkWell( onTap: () { Utils.hapticFeedback(); inputTimeController.changeDatePicker(); }, child: inputTimeController.isTimePicker.value - ? Obx( - () => Row( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - NumberPicker( - minValue: settingsController - .is24HrsEnabled.value - ? 0 - : 1, - maxValue: settingsController - .is24HrsEnabled.value - ? 23 - : 12, - value: controller.hours.value, - onChanged: (value) { - Utils.hapticFeedback(); - controller.hours.value = value; - controller.selectedTime.value = - DateTime( - controller - .selectedTime.value.year, - controller - .selectedTime.value.month, - controller.selectedTime.value.day, - inputTimeController - .convert24(value), - controller - .selectedTime.value.minute, - ); - inputTimeController - .inputHrsController.text = - controller.hours.value - .toString(); - inputTimeController - .inputMinutesController - .text = - controller.minutes.value - .toString(); - inputTimeController.changePeriod( - controller.meridiemIndex.value == - 0 - ? 'AM' - : 'PM', - ); - }, - infiniteLoop: true, - itemWidth: width * 0.17, - zeroPad: true, - selectedTextStyle: Theme.of(context) - .textTheme - .displayLarge! - .copyWith( - fontWeight: FontWeight.bold, - color: kprimaryColor, - ), - textStyle: Theme.of(context) - .textTheme - .displayMedium! - .copyWith( - fontSize: 20, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - decoration: BoxDecoration( - border: Border( - top: BorderSide( - width: width * 0.005, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - bottom: BorderSide( - width: width * 0.005, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - ), - ), - Padding( - padding: EdgeInsets.symmetric( - horizontal: width * 0.02, - ), - child: Text( - ':', - style: Theme.of(context) - .textTheme - .displayLarge! - .copyWith( - fontWeight: FontWeight.bold, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - ), - NumberPicker( - minValue: 0, - maxValue: 59, - value: controller.minutes.value, - onChanged: (value) { - Utils.hapticFeedback(); - controller.minutes.value = value; - controller.selectedTime.value = - DateTime( - controller - .selectedTime.value.year, - controller - .selectedTime.value.month, - controller.selectedTime.value.day, - controller - .selectedTime.value.hour, - controller.minutes.value, - ); - inputTimeController - .inputHrsController.text = - controller.hours.value - .toString(); - inputTimeController - .inputMinutesController - .text = - controller.minutes.value - .toString(); - inputTimeController.changePeriod( - controller.meridiemIndex.value == - 0 - ? 'AM' - : 'PM', - ); - }, - infiniteLoop: true, - itemWidth: width * 0.17, - zeroPad: true, - selectedTextStyle: Theme.of(context) - .textTheme - .displayLarge! - .copyWith( - fontWeight: FontWeight.bold, - color: kprimaryColor, - ), - textStyle: Theme.of(context) - .textTheme - .displayMedium! - .copyWith( - fontSize: 20, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - decoration: BoxDecoration( - border: Border( - top: BorderSide( - width: width * 0.005, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - bottom: BorderSide( - width: width * 0.005, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - ), - ), - Visibility( - visible: settingsController - .is24HrsEnabled.value - ? false - : true, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: width * 0.02, - ), - child: Text( - ':', - style: Theme.of(context) - .textTheme - .displayLarge! - .copyWith( - fontWeight: FontWeight.bold, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - ), - ), - Visibility( - visible: settingsController - .is24HrsEnabled.value - ? false - : true, - child: NumberPicker( - minValue: 0, - maxValue: 1, - value: - controller.meridiemIndex.value, - onChanged: (value) { - Utils.hapticFeedback(); - value == 0 - ? controller - .meridiemIndex.value = 0 - : controller - .meridiemIndex.value = 1; - controller.selectedTime.value = - DateTime( - controller - .selectedTime.value.year, - controller - .selectedTime.value.month, - controller - .selectedTime.value.day, - inputTimeController.convert24( - controller.hours.value), - controller.minutes.value, - ); - inputTimeController - .inputHrsController.text = - controller.hours.value - .toString(); - inputTimeController - .inputMinutesController - .text = - controller.minutes.value - .toString(); - inputTimeController.changePeriod( - controller.meridiemIndex - .value == - 0 - ? 'AM' - : 'PM', - ); - }, - textMapper: (numberText) { - return controller - .meridiem[ - int.parse(numberText)] - .value; - }, - itemWidth: width * 0.17, - selectedTextStyle: Theme.of(context) - .textTheme - .displayLarge! - .copyWith( - fontWeight: FontWeight.bold, - color: kprimaryColor, - ), - textStyle: Theme.of(context) - .textTheme - .displayMedium! - .copyWith( - fontSize: 20, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - decoration: BoxDecoration( - border: Border( - top: BorderSide( - width: width * 0.005, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - bottom: BorderSide( - width: width * 0.005, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - ), - ), + ? TimePickerSpinner( + time: controller.selectedTime.value, + isForce2Digits: true, + alignment: Alignment.center, + is24HourMode: + settingsController.is24HrsEnabled.value, + normalTextStyle: Theme.of(context) + .textTheme + .displayMedium! + .copyWith( + fontWeight: FontWeight.normal, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, ), - ], - ), + highlightedTextStyle: Theme.of(context) + .textTheme + .displayMedium, + onTimeChange: (dateTime) { + Utils.hapticFeedback(); + controller.selectedTime.value = dateTime; + inputTimeController.inputHrsController + .text = settingsController + .is24HrsEnabled.value + ? dateTime.hour.toString() + : (dateTime.hour == 0 + ? 12.toString() + : (dateTime.hour > 12 + ? (dateTime.hour - 12) + .toString() + : dateTime.hour.toString())); + inputTimeController.inputMinutesController + .text = dateTime.minute.toString(); + inputTimeController.changePeriod( + dateTime.hour >= 12 ? 'PM' : 'AM'); + }, ) : Row( mainAxisAlignment: MainAxisAlignment.center, @@ -677,27 +416,23 @@ class AddOrUpdateAlarmView extends GetView { inputTimeController.setTime(); }, decoration: const InputDecoration( - hintText: 'HH', - border: InputBorder.none, - ), + hintText: 'HH', + border: InputBorder.none), textAlign: TextAlign.center, controller: inputTimeController .inputHrsController, keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.allow( - RegExp( - '[1,2,3,4,5,6,7,8,9,0]', - ), - ), + RegExp( + '[1,2,3,4,5,6,7,8,9,0]')), LengthLimitingTextInputFormatter(2), LimitRange( - 0, - settingsController - .is24HrsEnabled.value - ? 23 - : 12, - ), + 0, + settingsController + .is24HrsEnabled.value + ? 23 + : 12) ], ), ), @@ -718,21 +453,18 @@ class AddOrUpdateAlarmView extends GetView { inputTimeController.setTime(); }, decoration: const InputDecoration( - hintText: 'MM', - border: InputBorder.none, - ), + hintText: 'MM', + border: InputBorder.none), textAlign: TextAlign.center, controller: inputTimeController .inputMinutesController, keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.allow( - RegExp( - '[1,2,3,4,5,6,7,8,9,0]', - ), - ), + RegExp( + '[1,2,3,4,5,6,7,8,9,0]')), LengthLimitingTextInputFormatter(2), - LimitRange(00, 59), + LimitRange(00, 59) ], ), ), @@ -780,13 +512,12 @@ class AddOrUpdateAlarmView extends GetView { }, child: Container( decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(50.0), - border: Border.all( - color: kprimaryColor, - width: 1.0, - ), - ), + borderRadius: + BorderRadius.circular(50.0), + border: Border.all( + color: kprimaryColor, + width: 1.0, + )), padding: EdgeInsets.all(5.0), child: Icon( Icons.done, @@ -798,9 +529,7 @@ class AddOrUpdateAlarmView extends GetView { ], ), ); - }, - ), - ), + })), RepeatTile( controller: controller, themeController: themeController, diff --git a/lib/app/modules/alarmRing/views/alarm_ring_view.dart b/lib/app/modules/alarmRing/views/alarm_ring_view.dart index d547cf6d..32441702 100644 --- a/lib/app/modules/alarmRing/views/alarm_ring_view.dart +++ b/lib/app/modules/alarmRing/views/alarm_ring_view.dart @@ -1,221 +1,290 @@ +import 'dart:async'; +import 'dart:math'; + import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'package:flutter_fgbg/flutter_fgbg.dart'; +import 'package:flutter_volume_controller/flutter_volume_controller.dart'; import 'package:get/get.dart'; -import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; -import 'package:ultimate_alarm_clock/app/utils/constants.dart'; +import 'package:ultimate_alarm_clock/app/data/models/alarm_model.dart'; + +import 'package:ultimate_alarm_clock/app/data/models/user_model.dart'; + +import 'package:ultimate_alarm_clock/app/data/providers/firestore_provider.dart'; +import 'package:ultimate_alarm_clock/app/data/providers/isar_provider.dart'; +import 'package:ultimate_alarm_clock/app/data/providers/secure_storage_provider.dart'; +import 'package:ultimate_alarm_clock/app/utils/audio_utils.dart'; + import 'package:ultimate_alarm_clock/app/utils/utils.dart'; +import 'package:vibration/vibration.dart'; + +class AlarmControlController extends GetxController { + MethodChannel alarmChannel = MethodChannel('ulticlock'); + RxString note = ''.obs; + Timer? vibrationTimer; + late StreamSubscription _subscription; + TimeOfDay currentTime = TimeOfDay.now(); + late RxBool isSnoozing = false.obs; + RxInt minutes = 1.obs; + RxInt seconds = 0.obs; + RxBool showButton = false.obs; + final Rx currentlyRingingAlarm = Utils.genFakeAlarmModel().obs; + final formattedDate = Utils.getFormattedDate(DateTime.now()).obs; + final timeNow = + Utils.convertTo12HourFormat(Utils.timeOfDayToString(TimeOfDay.now())).obs; + Timer? _currentTimeTimer; + bool isAlarmActive = true; + late double initialVolume; + + getCurrentlyRingingAlarm() async { + UserModel? _userModel = await SecureStorageProvider().retrieveUserModel(); + AlarmModel _alarmRecord = Utils.genFakeAlarmModel(); + AlarmModel isarLatestAlarm = + await IsarDb.getLatestAlarm(_alarmRecord, false); + AlarmModel firestoreLatestAlarm = + await FirestoreDb.getLatestAlarm(_userModel, _alarmRecord, false); + AlarmModel latestAlarm = + Utils.getFirstScheduledAlarm(isarLatestAlarm, firestoreLatestAlarm); + debugPrint('CURRENT RINGING : ${latestAlarm.alarmTime}'); + + return latestAlarm; + } + + getAlarm() async { + UserModel? _userModel = await SecureStorageProvider().retrieveUserModel(); + AlarmModel _alarmRecord = Utils.genFakeAlarmModel(); + AlarmModel isarLatestAlarm = + await IsarDb.getLatestAlarm(_alarmRecord, true); + AlarmModel firestoreLatestAlarm = + await FirestoreDb.getLatestAlarm(_userModel, _alarmRecord, true); + AlarmModel latestAlarm = + Utils.getFirstScheduledAlarm(isarLatestAlarm, firestoreLatestAlarm); + debugPrint('LATEST : ${latestAlarm.alarmTime}'); + + return latestAlarm; + } + + void startSnooze() async { + Vibration.cancel(); + vibrationTimer!.cancel(); + isSnoozing.value = true; + String ringtoneName = currentlyRingingAlarm.value.ringtoneName; + AudioUtils.stopAlarm(ringtoneName: ringtoneName); + + if (_currentTimeTimer!.isActive) { + _currentTimeTimer?.cancel(); + } + + _currentTimeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { + if (minutes.value == 0 && seconds.value == 0) { + timer.cancel(); + vibrationTimer = + Timer.periodic(const Duration(milliseconds: 3500), (Timer timer) { + Vibration.vibrate(pattern: [500, 3000]); + }); + + AudioUtils.playAlarm(alarmRecord: currentlyRingingAlarm.value); + + startTimer(); + } else if (seconds.value == 0) { + minutes.value--; + seconds.value = 59; + } else { + seconds.value--; + } + }); + } + + void startTimer() { + minutes.value = currentlyRingingAlarm.value.snoozeDuration; + isSnoozing.value = false; + _currentTimeTimer = Timer.periodic( + Duration( + milliseconds: Utils.getMillisecondsToAlarm( + DateTime.now(), + DateTime.now().add(const Duration(minutes: 1)), + ), + ), (timer) { + formattedDate.value = Utils.getFormattedDate(DateTime.now()); + timeNow.value = + Utils.convertTo12HourFormat(Utils.timeOfDayToString(TimeOfDay.now())); + }); + } + + Future _fadeInAlarmVolume() async { + await FlutterVolumeController.setVolume( + currentlyRingingAlarm.value.volMin / 10.0, + stream: AudioStream.alarm, + ); + await Future.delayed(const Duration(milliseconds: 2000)); + + double vol = currentlyRingingAlarm.value.volMin / 10.0; + double diff = (currentlyRingingAlarm.value.volMax - + currentlyRingingAlarm.value.volMin) / + 10.0; + int len = currentlyRingingAlarm.value.gradient * 1000; + double steps = (diff / 0.01).abs(); + int stepLen = max(4, (steps > 0) ? len ~/ steps : len); + int lastTick = DateTime.now().millisecondsSinceEpoch; + + Timer.periodic(Duration(milliseconds: stepLen), (Timer t) { + if (!isAlarmActive) { + t.cancel(); + return; + } -import '../controllers/alarm_ring_controller.dart'; + var now = DateTime.now().millisecondsSinceEpoch; + var tick = (now - lastTick) / len; + lastTick = now; + vol += diff * tick; -class AlarmControlView extends GetView { - AlarmControlView({Key? key}) : super(key: key); + vol = max(currentlyRingingAlarm.value.volMin / 10.0, vol); + vol = min(currentlyRingingAlarm.value.volMax / 10.0, vol); + vol = (vol * 100).round() / 100; - ThemeController themeController = Get.find(); + FlutterVolumeController.setVolume( + vol, + stream: AudioStream.alarm, + ); + + if (vol >= currentlyRingingAlarm.value.volMax / 10.0) { + t.cancel(); + } + }); + } @override - Widget build(BuildContext context) { - var width = Get.width; - var height = Get.height; - return PopScope( - canPop: false, - onPopInvoked: (bool didPop) { - if (didPop) { - return; + void onInit() async { + super.onInit(); + initialVolume = await FlutterVolumeController.getVolume( + stream: AudioStream.alarm, + ) as double; + + FlutterVolumeController.updateShowSystemUI(false); + + _fadeInAlarmVolume(); + + if (currentlyRingingAlarm.value.deleteAfterGoesOff == true) { + if (currentlyRingingAlarm.value.isSharedAlarmEnabled) { + FirestoreDb.deleteOneTimeAlarm( + currentlyRingingAlarm.value.ownerId, + currentlyRingingAlarm.value.firestoreId, + ); + } else { + IsarDb.deleteAlarm(currentlyRingingAlarm.value.isarId); + } + } + vibrationTimer = + Timer.periodic(const Duration(milliseconds: 3500), (Timer timer) { + Vibration.vibrate(pattern: [500, 3000]); + }); + + // Preventing app from being minimized! + _subscription = FGBGEvents.stream.listen((event) { + if (event == FGBGType.background) { + alarmChannel.invokeMethod('bringAppToForeground'); + } + }); + + startTimer(); + if (Get.arguments == null) { + currentlyRingingAlarm.value = await getCurrentlyRingingAlarm(); + showButton.value = true; + // If the alarm is set to NEVER repeat, then it will + // be chosen as the alarm to ring by default as + // it would ring the day + if (currentlyRingingAlarm.value.days + .every((element) => element == false)) { + currentlyRingingAlarm.value.isEnabled = false; + + if (currentlyRingingAlarm.value.isSharedAlarmEnabled == false) { + IsarDb.updateAlarm(currentlyRingingAlarm.value); + } else { + FirestoreDb.updateAlarm( + currentlyRingingAlarm.value.ownerId, + currentlyRingingAlarm.value, + ); + } + } else if (currentlyRingingAlarm.value.isOneTime == true) { + // If the alarm has to repeat on one day, but ring just once, we will + // keep seting its days to false until it will never ring + int currentDay = DateTime.now().weekday - 1; + currentlyRingingAlarm.value.days[currentDay] = false; + + if (currentlyRingingAlarm.value.days + .every((element) => element == false)) { + currentlyRingingAlarm.value.isEnabled = false; + } + + if (currentlyRingingAlarm.value.isSharedAlarmEnabled == false) { + IsarDb.updateAlarm(currentlyRingingAlarm.value); + } else { + FirestoreDb.updateAlarm( + currentlyRingingAlarm.value.ownerId, + currentlyRingingAlarm.value, + ); } + } + } else { + currentlyRingingAlarm.value = Get.arguments; + showButton.value = true; + } - Get.snackbar( - 'Note'.tr, - "You can't go back while the alarm is ringing".tr, - backgroundColor: Colors.red, - colorText: Colors.white, + AudioUtils.playAlarm(alarmRecord: currentlyRingingAlarm.value); + + // Setting snooze duration + minutes.value = currentlyRingingAlarm.value.snoozeDuration; + + // Scheduling alarm if it's not in preview mode + if (Get.arguments == null) { + // Finding the alarm to ring + AlarmModel latestAlarm = await getAlarm(); + TimeOfDay latestAlarmTimeOfDay = + Utils.stringToTimeOfDay(latestAlarm.alarmTime); + + // } + // This condition will never satisfy because this will only + // occur if fake model is returned as latest alarm + if (latestAlarm.isEnabled == false) { + debugPrint( + 'STOPPED IF CONDITION with latest = ' + '${latestAlarmTimeOfDay.toString()} and ' + 'current = ${currentTime.toString()}', ); - }, - child: SafeArea( - child: Scaffold( - floatingActionButtonLocation: - FloatingActionButtonLocation.centerDocked, - floatingActionButton: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Padding( - padding: const EdgeInsets.all(18.0), - child: Obx( - () => SizedBox( - height: height * 0.06, - width: width * 0.8, - child: controller.showButton.value - ? TextButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - kprimaryColor, - ), - ), - child: Text( - Utils.isChallengeEnabled( - controller.currentlyRingingAlarm.value, - ) - ? 'Start Challenge'.tr - : 'Dismiss'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - : ksecondaryTextColor, - ), - ), - onPressed: () { - Utils.hapticFeedback(); - if (Utils.isChallengeEnabled( - controller.currentlyRingingAlarm.value, - )) { - Get.toNamed( - '/alarm-challenge', - arguments: - controller.currentlyRingingAlarm.value, - ); - } else { - Get.offNamed( - '/bottom-navigation-bar', - arguments: controller.currentlyRingingAlarm - .value.showMotivationalQuote, - ); - } - }, - ) - : const SizedBox(), - ), - ), - ), - (Get.arguments != null) - ? Padding( - padding: const EdgeInsets.all(8.0), - child: Obx( - () => SizedBox( - height: height * 0.06, - width: width, - child: TextButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.7) - : kprimaryTextColor.withOpacity(0.7), - ), - ), - child: Text( - 'Exit Preview'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - : ksecondaryTextColor, - ), - ), - onPressed: () { - Utils.hapticFeedback(); - Get.offNamed('/bottom-navigation-bar'); - }, - ), - ), - ), - ) - : const SizedBox(), - ], - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Obx( - () => Column( - children: [ - Text( - controller.formattedDate.value, - style: Theme.of(context).textTheme.bodyLarge, - ), - const SizedBox( - height: 10, - width: 0, - ), - Text( - (controller.isSnoozing.value) - ? "${controller.minutes.toString().padLeft(2, '0')}" - // ignore: lines_longer_than_80_chars - ":${controller.seconds.toString().padLeft(2, '0')}" - : '${controller.timeNow[0]} ' - '${controller.timeNow[1]}', - style: Theme.of(context) - .textTheme - .displayLarge! - .copyWith(fontSize: 50), - ), - ], - ), - ), - Obx( - () => Visibility( - visible: - controller.currentlyRingingAlarm.value.note.isNotEmpty, - child: Text( - controller.currentlyRingingAlarm.value.note, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - : kprimaryTextColor, - fontSize: 20, - fontWeight: FontWeight.w100, - fontStyle: FontStyle.italic, - ), - ), - ), - ), - Obx( - () => Visibility( - visible: !controller.isSnoozing.value, - child: Obx( - () => Padding( - padding: Get.arguments != null - ? const EdgeInsets.symmetric(vertical: 90.0) - : EdgeInsets.zero, - child: SizedBox( - height: height * 0.07, - width: width * 0.5, - child: TextButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - ), - ), - child: Text( - 'Snooze'.tr, - style: - Theme.of(context).textTheme.bodyMedium!.copyWith( - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - : kprimaryTextColor, - fontWeight: FontWeight.w600, - ), - ), - onPressed: () { - Utils.hapticFeedback(); - controller.startSnooze(); - }, - ), - ), - ), - ), - ), - ), - ], - ), - ), - ), - ), + + await alarmChannel.invokeMethod('cancelAllScheduledAlarms'); + } else { + int intervaltoAlarm = Utils.getMillisecondsToAlarm( + DateTime.now(), + Utils.timeOfDayToDateTime(latestAlarmTimeOfDay), + ); + + try { + await alarmChannel + .invokeMethod('scheduleAlarm', {'milliSeconds': intervaltoAlarm}); + print("Scheduled..."); + } on PlatformException catch (e) { + print("Failed to schedule alarm: ${e.message}"); + } + } + } + } + + @override + void onClose() async { + super.onClose(); + Vibration.cancel(); + vibrationTimer!.cancel(); + isAlarmActive = false; + String ringtoneName = currentlyRingingAlarm.value.ringtoneName; + AudioUtils.stopAlarm(ringtoneName: ringtoneName); + await FlutterVolumeController.setVolume( + initialVolume, + stream: AudioStream.alarm, ); + _subscription.cancel(); + _currentTimeTimer?.cancel(); } } diff --git a/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart b/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart index 8b1e37f5..3c77695c 100644 --- a/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart +++ b/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart @@ -7,8 +7,9 @@ class StopwatchController extends GetxController { final Stopwatch _stopwatch = Stopwatch(); final RxString _result = '00:00:00'.obs; late Timer timer; - + final RxList _flag= [].obs; String get result => _result.value; + List get flag => _flag; void toggleTimer() { if (isTimerPaused.value) { @@ -17,6 +18,15 @@ class StopwatchController extends GetxController { stopTimer(); } } + + void lap_reset(){ + if(isTimerPaused.value){ + resetTime(); + } + else{ + recordLap(); + } + } void startTimer() { timer = Timer.periodic(const Duration(milliseconds: 30), (Timer t) { @@ -31,16 +41,19 @@ class StopwatchController extends GetxController { _stopwatch.stop(); isTimerPaused.value = true; } - + void resetTime() { stopTimer(); _stopwatch.reset(); _updateResult(); + _flag.clear(); + } + void recordLap() { + _flag.add('${_stopwatch.elapsed.inMinutes.toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds % 60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inMilliseconds % 100).toString().padLeft(2, '0')}'); } void _updateResult() { _result.value = - '${_stopwatch.elapsed.inMinutes.toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds % 60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inMilliseconds % 100).toString().padLeft(2, '0')}'; + '${_stopwatch.elapsed.inMinutes.toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds %60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inMilliseconds % 100).toString().padLeft(2, '0')}'; } - } diff --git a/lib/app/modules/stopwatch/views/stopwatch_view.dart b/lib/app/modules/stopwatch/views/stopwatch_view.dart index b0c893f3..973cf075 100644 --- a/lib/app/modules/stopwatch/views/stopwatch_view.dart +++ b/lib/app/modules/stopwatch/views/stopwatch_view.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +//import 'package:get_storage/get_storage.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/stopwatch/controllers/stopwatch_controller.dart'; import 'package:ultimate_alarm_clock/app/routes/app_pages.dart'; -import 'package:ultimate_alarm_clock/app/utils/end_drawer.dart'; import '../../../utils/constants.dart'; import '../../../utils/utils.dart'; @@ -12,7 +12,7 @@ class StopwatchView extends GetView { ThemeController themeController = Get.find(); @override Widget build(BuildContext context) { - var width = Get.width; + var width = Get.width; var height = Get.height; return Scaffold( appBar: PreferredSize( @@ -21,120 +21,195 @@ class StopwatchView extends GetView { toolbarHeight: height / 7.9, elevation: 0.0, centerTitle: true, - actions: [ - LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return IconButton( - onPressed: () { - Utils.hapticFeedback(); - Scaffold.of(context).openEndDrawer(); - }, - icon: const Icon( - Icons.menu, + ), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Obx(() => Text( + controller.result, + style: const TextStyle( + fontSize: 60.0, fontWeight: FontWeight.bold), + )), + const SizedBox( + height: 20.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + FloatingActionButton( + heroTag: "start", + onPressed: controller.toggleTimer, + child: Obx(() => Icon( + controller.isTimerPaused.value + ? Icons.play_arrow + : Icons.pause, + )), ), - color: themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.75) - : kprimaryTextColor.withOpacity(0.75), - iconSize: 27, - // splashRadius: 0.000001, - ); - }, + FloatingActionButton( + heroTag: "stop", + onPressed:controller.lap_reset, + child: Obx(() => Icon( + controller.isTimerPaused.value + ? Icons.square_rounded + :Icons.flag + )), + ) + ], + ), + SizedBox( + height: 20, ), + Obx( + () => Expanded( + child: ListView.builder( + itemCount: controller.flag.length, + itemBuilder: (context, index) { + final descendingIndex = controller.flag.length -index-1; + return ListTile( + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text('${descendingIndex+1}.'), + const Icon(Icons.flag, + color:Colors.amber ,), + Text(controller.flag[descendingIndex]) + ], + ) + ); + }, + ), + ), + ), ], ), - ), - body: Column( - children: [ - SizedBox( - height: height * 0.3, + ), + endDrawer: Obx( + () => Drawer( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), + bottomLeft: Radius.circular(10), + ), ), - Obx( - () => Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Center( - child: Text( - controller.result.split(':')[0], - style: const TextStyle( - fontSize: 50.0, - fontWeight: FontWeight.bold, + backgroundColor: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Column( + children: [ + DrawerHeader( + decoration: const BoxDecoration(color: kLightSecondaryColor), + child: Center( + child: Row( + children: [ + const Flexible( + flex: 1, + child: CircleAvatar( + radius: 30, + backgroundImage: AssetImage( + 'assets/images/ic_launcher-playstore.png', + ), + ), ), - ), - ), - ), - const Text( - ':', - style: TextStyle( - fontSize: 50.0, - fontWeight: FontWeight.bold, - ), - ), - Expanded( - child: Center( - child: Text( - controller.result.split(':')[1], - style: const TextStyle( - fontSize: 50.0, - fontWeight: FontWeight.bold, + const SizedBox( + width: 10, ), - ), - ), - ), - const Text( - ':', - style: TextStyle( - fontSize: 50.0, - fontWeight: FontWeight.bold, + Flexible( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: width * 0.5, + child: Text( + 'Ultimate Alarm Clock'.tr, + softWrap: true, + style: Theme.of(context) + .textTheme + .displayMedium! + .copyWith( + color: themeController.isLightMode.value + ? kprimaryTextColor + : ksecondaryTextColor, + fontWeight: FontWeight.bold, + ), + ), + ), + SizedBox( + width: width * 0.5, + child: Text( + 'v0.5.0'.tr, + softWrap: true, + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith( + color: themeController.isLightMode.value + ? kprimaryTextColor + : ksecondaryTextColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ], ), ), - Expanded( - child: Center( - child: Text( - controller.result.split(':')[2], - style: const TextStyle( - fontSize: 50.0, - fontWeight: FontWeight.bold, + ), + ListTile( + onTap: () { + Utils.hapticFeedback(); + Get.back(); + Get.toNamed('/settings'); + }, + contentPadding: const EdgeInsets.only(left: 20, right: 44), + title: Text( + 'Settings'.tr, + style: Theme.of(context).textTheme.titleLarge!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.8) + : kprimaryTextColor.withOpacity(0.8), ), - ), - ), ), - ], - ), - ), - const SizedBox( - height: 10.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - FloatingActionButton( - heroTag: "start", - onPressed: controller.toggleTimer, - child: Obx( - () => Icon( - controller.isTimerPaused.value - ? Icons.play_arrow_rounded - : Icons.pause_rounded, - size: 33, - ), + leading: Icon( + Icons.settings, + size: 26, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.8) + : kprimaryTextColor.withOpacity(0.8), ), ), - // Reset button - FloatingActionButton( - heroTag: "stop", - onPressed: controller.resetTime, - child: Icon( - Icons.stop_rounded, - size: 33, + ListTile( + onTap: () { + Utils.hapticFeedback(); + Get.back(); + Get.toNamed(Routes.ABOUT); + }, + contentPadding: const EdgeInsets.only(left: 20, right: 44), + title: Text( + 'About'.tr, + style: Theme.of(context).textTheme.titleLarge!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.8) + : kprimaryTextColor.withOpacity(0.8), + ), + ), + leading: Icon( + Icons.info_outline, + size: 26, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.8) + : kprimaryTextColor.withOpacity(0.8), ), ), ], ), - ], + ), ), - endDrawer: buildEndDrawer(context) ); } } diff --git a/lib/main.dart b/lib/main.dart index f7964007..5b7c7552 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,5 @@ +import 'dart:ffi'; + import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -11,9 +13,9 @@ import 'app/routes/app_pages.dart'; Locale? loc; void main() async { - WidgetsFlutterBinding.ensureInitialized(); + WidgetsFlutterBinding.ensureInitialized();//To clear that flutter is ready to run. - await Firebase.initializeApp(); + await Firebase.initializeApp();//Initialize firebase await Get.putAsync(() => GetStorageProvider().init()); final storage=Get.find(); loc = await storage.readLocale(); @@ -27,11 +29,11 @@ void main() async { audioFocus: AndroidAudioFocus.gainTransient, ), ), - ); + );//For audio players we have to set AudioContext player globally or player specific depends on developer. SystemChrome.setPreferredOrientations([ - DeviceOrientation.portraitUp, - DeviceOrientation.portraitDown, + DeviceOrientation.portraitUp,// to set orientation of mobile app up + DeviceOrientation.portraitDown,// to set orientation of mobile app down ]); SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle(statusBarColor: Colors.transparent), @@ -46,6 +48,7 @@ class UltimateAlarmClockApp extends StatelessWidget { @override Widget build(BuildContext context) { return GetMaterialApp( + theme: kLightThemeData, darkTheme: kThemeData, themeMode: ThemeMode.system, @@ -54,7 +57,7 @@ class UltimateAlarmClockApp extends StatelessWidget { getPages: AppPages.routes, translations: AppTranslations(), locale: loc, - fallbackLocale: Locale('en', 'US'), + fallbackLocale: Locale('en', 'US',), builder: (BuildContext context, Widget? error) { ErrorWidget.builder = (FlutterErrorDetails? error) { return CustomErrorScreen(errorDetails: error!); From 6a8237b77708c137b20136e0280fef1ad7249875 Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sat, 10 Feb 2024 16:33:56 +0530 Subject: [PATCH 2/9] Fixed unneccessary changes --- .../views/add_or_update_alarm_view.dart | 413 +++++++++++++++--- .../controllers/alarm_ring_controller.dart | 12 +- lib/main.dart | 15 +- 3 files changed, 354 insertions(+), 86 deletions(-) diff --git a/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart b/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart index cfa9ec74..c422e190 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart @@ -1,9 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart'; - import 'package:get/get.dart'; +import 'package:numberpicker/numberpicker.dart'; import 'package:ultimate_alarm_clock/app/data/models/alarm_model.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/controllers/input_time_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/alarm_id_tile.dart'; @@ -152,8 +151,9 @@ class AddOrUpdateAlarmView extends GetView { ), onPressed: () async { Utils.hapticFeedback(); - if (controller.userModel != null) { - controller.offsetDetails[controller.userModel!.id] = { + if (controller.userModel.value != null) { + controller + .offsetDetails[controller.userModel.value!.id] = { 'offsettedTime': Utils.timeOfDayToString( TimeOfDay.fromDateTime( Utils.calculateOffsetAlarmTime( @@ -282,9 +282,12 @@ class AddOrUpdateAlarmView extends GetView { ? const Text('') : Obx( () => Text( - 'in @timeToAlarm'.trParams({ - 'timeToAlarm': controller.timeToAlarm.value.toString() - }), + 'Rings in @timeToAlarm'.trParams( + { + 'timeToAlarm': + controller.timeToAlarm.value.toString(), + }, + ), style: Theme.of(context).textTheme.titleSmall, ), ), @@ -356,55 +359,313 @@ class AddOrUpdateAlarmView extends GetView { : ListView( children: [ Container( - color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - height: height * 0.32, - width: width, - child: Obx(() { + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + height: height * 0.32, + width: width, + child: Obx( + () { return InkWell( onTap: () { Utils.hapticFeedback(); inputTimeController.changeDatePicker(); }, child: inputTimeController.isTimePicker.value - ? TimePickerSpinner( - time: controller.selectedTime.value, - isForce2Digits: true, - alignment: Alignment.center, - is24HourMode: - settingsController.is24HrsEnabled.value, - normalTextStyle: Theme.of(context) - .textTheme - .displayMedium! - .copyWith( - fontWeight: FontWeight.normal, - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + ? Obx( + () => Row( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + NumberPicker( + minValue: settingsController + .is24HrsEnabled.value + ? 0 + : 1, + maxValue: settingsController + .is24HrsEnabled.value + ? 23 + : 12, + value: controller.hours.value, + onChanged: (value) { + Utils.hapticFeedback(); + controller.hours.value = value; + controller.selectedTime.value = + DateTime( + controller + .selectedTime.value.year, + controller + .selectedTime.value.month, + controller.selectedTime.value.day, + inputTimeController + .convert24(value), + controller + .selectedTime.value.minute, + ); + inputTimeController + .inputHrsController.text = + controller.hours.value + .toString(); + inputTimeController + .inputMinutesController + .text = + controller.minutes.value + .toString(); + inputTimeController.changePeriod( + controller.meridiemIndex.value == + 0 + ? 'AM' + : 'PM', + ); + }, + infiniteLoop: true, + itemWidth: width * 0.17, + zeroPad: true, + selectedTextStyle: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: kprimaryColor, + ), + textStyle: Theme.of(context) + .textTheme + .displayMedium! + .copyWith( + fontSize: 20, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + decoration: BoxDecoration( + border: Border( + top: BorderSide( + width: width * 0.005, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + bottom: BorderSide( + width: width * 0.005, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: width * 0.02, + ), + child: Text( + ':', + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + ), + NumberPicker( + minValue: 0, + maxValue: 59, + value: controller.minutes.value, + onChanged: (value) { + Utils.hapticFeedback(); + controller.minutes.value = value; + controller.selectedTime.value = + DateTime( + controller + .selectedTime.value.year, + controller + .selectedTime.value.month, + controller.selectedTime.value.day, + controller + .selectedTime.value.hour, + controller.minutes.value, + ); + inputTimeController + .inputHrsController.text = + controller.hours.value + .toString(); + inputTimeController + .inputMinutesController + .text = + controller.minutes.value + .toString(); + inputTimeController.changePeriod( + controller.meridiemIndex.value == + 0 + ? 'AM' + : 'PM', + ); + }, + infiniteLoop: true, + itemWidth: width * 0.17, + zeroPad: true, + selectedTextStyle: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: kprimaryColor, + ), + textStyle: Theme.of(context) + .textTheme + .displayMedium! + .copyWith( + fontSize: 20, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + decoration: BoxDecoration( + border: Border( + top: BorderSide( + width: width * 0.005, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + bottom: BorderSide( + width: width * 0.005, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + ), + ), + Visibility( + visible: settingsController + .is24HrsEnabled.value + ? false + : true, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: width * 0.02, + ), + child: Text( + ':', + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + ), + ), + Visibility( + visible: settingsController + .is24HrsEnabled.value + ? false + : true, + child: NumberPicker( + minValue: 0, + maxValue: 1, + value: + controller.meridiemIndex.value, + onChanged: (value) { + Utils.hapticFeedback(); + value == 0 + ? controller + .meridiemIndex.value = 0 + : controller + .meridiemIndex.value = 1; + controller.selectedTime.value = + DateTime( + controller + .selectedTime.value.year, + controller + .selectedTime.value.month, + controller + .selectedTime.value.day, + inputTimeController.convert24( + controller.hours.value), + controller.minutes.value, + ); + inputTimeController + .inputHrsController.text = + controller.hours.value + .toString(); + inputTimeController + .inputMinutesController + .text = + controller.minutes.value + .toString(); + inputTimeController.changePeriod( + controller.meridiemIndex + .value == + 0 + ? 'AM' + : 'PM', + ); + }, + textMapper: (numberText) { + return controller + .meridiem[ + int.parse(numberText)] + .value; + }, + itemWidth: width * 0.17, + selectedTextStyle: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: kprimaryColor, + ), + textStyle: Theme.of(context) + .textTheme + .displayMedium! + .copyWith( + fontSize: 20, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + decoration: BoxDecoration( + border: Border( + top: BorderSide( + width: width * 0.005, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + bottom: BorderSide( + width: width * 0.005, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + ), + ), ), - highlightedTextStyle: Theme.of(context) - .textTheme - .displayMedium, - onTimeChange: (dateTime) { - Utils.hapticFeedback(); - controller.selectedTime.value = dateTime; - inputTimeController.inputHrsController - .text = settingsController - .is24HrsEnabled.value - ? dateTime.hour.toString() - : (dateTime.hour == 0 - ? 12.toString() - : (dateTime.hour > 12 - ? (dateTime.hour - 12) - .toString() - : dateTime.hour.toString())); - inputTimeController.inputMinutesController - .text = dateTime.minute.toString(); - inputTimeController.changePeriod( - dateTime.hour >= 12 ? 'PM' : 'AM'); - }, + ], + ), ) : Row( mainAxisAlignment: MainAxisAlignment.center, @@ -416,23 +677,27 @@ class AddOrUpdateAlarmView extends GetView { inputTimeController.setTime(); }, decoration: const InputDecoration( - hintText: 'HH', - border: InputBorder.none), + hintText: 'HH', + border: InputBorder.none, + ), textAlign: TextAlign.center, controller: inputTimeController .inputHrsController, keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.allow( - RegExp( - '[1,2,3,4,5,6,7,8,9,0]')), + RegExp( + '[1,2,3,4,5,6,7,8,9,0]', + ), + ), LengthLimitingTextInputFormatter(2), LimitRange( - 0, - settingsController - .is24HrsEnabled.value - ? 23 - : 12) + 0, + settingsController + .is24HrsEnabled.value + ? 23 + : 12, + ), ], ), ), @@ -453,18 +718,21 @@ class AddOrUpdateAlarmView extends GetView { inputTimeController.setTime(); }, decoration: const InputDecoration( - hintText: 'MM', - border: InputBorder.none), + hintText: 'MM', + border: InputBorder.none, + ), textAlign: TextAlign.center, controller: inputTimeController .inputMinutesController, keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.allow( - RegExp( - '[1,2,3,4,5,6,7,8,9,0]')), + RegExp( + '[1,2,3,4,5,6,7,8,9,0]', + ), + ), LengthLimitingTextInputFormatter(2), - LimitRange(00, 59) + LimitRange(00, 59), ], ), ), @@ -512,12 +780,13 @@ class AddOrUpdateAlarmView extends GetView { }, child: Container( decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(50.0), - border: Border.all( - color: kprimaryColor, - width: 1.0, - )), + borderRadius: + BorderRadius.circular(50.0), + border: Border.all( + color: kprimaryColor, + width: 1.0, + ), + ), padding: EdgeInsets.all(5.0), child: Icon( Icons.done, @@ -529,7 +798,9 @@ class AddOrUpdateAlarmView extends GetView { ], ), ); - })), + }, + ), + ), RepeatTile( controller: controller, themeController: themeController, @@ -863,4 +1134,4 @@ class AddOrUpdateAlarmView extends GetView { ), )); } -} +} \ No newline at end of file diff --git a/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart b/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart index c556fe5e..32441702 100644 --- a/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart +++ b/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart @@ -52,7 +52,7 @@ class AlarmControlController extends GetxController { return latestAlarm; } - getNextAlarm() async { + getAlarm() async { UserModel? _userModel = await SecureStorageProvider().retrieveUserModel(); AlarmModel _alarmRecord = Utils.genFakeAlarmModel(); AlarmModel isarLatestAlarm = @@ -193,8 +193,8 @@ class AlarmControlController extends GetxController { currentlyRingingAlarm.value = await getCurrentlyRingingAlarm(); showButton.value = true; // If the alarm is set to NEVER repeat, then it will - // be chosen as the next alarm to ring by default as - // it would ring the next day + // be chosen as the alarm to ring by default as + // it would ring the day if (currentlyRingingAlarm.value.days .every((element) => element == false)) { currentlyRingingAlarm.value.isEnabled = false; @@ -237,10 +237,10 @@ class AlarmControlController extends GetxController { // Setting snooze duration minutes.value = currentlyRingingAlarm.value.snoozeDuration; - // Scheduling next alarm if it's not in preview mode + // Scheduling alarm if it's not in preview mode if (Get.arguments == null) { - // Finding the next alarm to ring - AlarmModel latestAlarm = await getNextAlarm(); + // Finding the alarm to ring + AlarmModel latestAlarm = await getAlarm(); TimeOfDay latestAlarmTimeOfDay = Utils.stringToTimeOfDay(latestAlarm.alarmTime); diff --git a/lib/main.dart b/lib/main.dart index 5b7c7552..f7964007 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,3 @@ -import 'dart:ffi'; - import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -13,9 +11,9 @@ import 'app/routes/app_pages.dart'; Locale? loc; void main() async { - WidgetsFlutterBinding.ensureInitialized();//To clear that flutter is ready to run. + WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp();//Initialize firebase + await Firebase.initializeApp(); await Get.putAsync(() => GetStorageProvider().init()); final storage=Get.find(); loc = await storage.readLocale(); @@ -29,11 +27,11 @@ void main() async { audioFocus: AndroidAudioFocus.gainTransient, ), ), - );//For audio players we have to set AudioContext player globally or player specific depends on developer. + ); SystemChrome.setPreferredOrientations([ - DeviceOrientation.portraitUp,// to set orientation of mobile app up - DeviceOrientation.portraitDown,// to set orientation of mobile app down + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, ]); SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle(statusBarColor: Colors.transparent), @@ -48,7 +46,6 @@ class UltimateAlarmClockApp extends StatelessWidget { @override Widget build(BuildContext context) { return GetMaterialApp( - theme: kLightThemeData, darkTheme: kThemeData, themeMode: ThemeMode.system, @@ -57,7 +54,7 @@ class UltimateAlarmClockApp extends StatelessWidget { getPages: AppPages.routes, translations: AppTranslations(), locale: loc, - fallbackLocale: Locale('en', 'US',), + fallbackLocale: Locale('en', 'US'), builder: (BuildContext context, Widget? error) { ErrorWidget.builder = (FlutterErrorDetails? error) { return CustomErrorScreen(errorDetails: error!); From 79e1c4e51959804033aacabd093554b775adfc18 Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:18:10 +0530 Subject: [PATCH 3/9] Update alarm_ring_controller.dart change unnecessary words --- .../alarmRing/controllers/alarm_ring_controller.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart b/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart index 32441702..c556fe5e 100644 --- a/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart +++ b/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart @@ -52,7 +52,7 @@ class AlarmControlController extends GetxController { return latestAlarm; } - getAlarm() async { + getNextAlarm() async { UserModel? _userModel = await SecureStorageProvider().retrieveUserModel(); AlarmModel _alarmRecord = Utils.genFakeAlarmModel(); AlarmModel isarLatestAlarm = @@ -193,8 +193,8 @@ class AlarmControlController extends GetxController { currentlyRingingAlarm.value = await getCurrentlyRingingAlarm(); showButton.value = true; // If the alarm is set to NEVER repeat, then it will - // be chosen as the alarm to ring by default as - // it would ring the day + // be chosen as the next alarm to ring by default as + // it would ring the next day if (currentlyRingingAlarm.value.days .every((element) => element == false)) { currentlyRingingAlarm.value.isEnabled = false; @@ -237,10 +237,10 @@ class AlarmControlController extends GetxController { // Setting snooze duration minutes.value = currentlyRingingAlarm.value.snoozeDuration; - // Scheduling alarm if it's not in preview mode + // Scheduling next alarm if it's not in preview mode if (Get.arguments == null) { - // Finding the alarm to ring - AlarmModel latestAlarm = await getAlarm(); + // Finding the next alarm to ring + AlarmModel latestAlarm = await getNextAlarm(); TimeOfDay latestAlarmTimeOfDay = Utils.stringToTimeOfDay(latestAlarm.alarmTime); From 03aaa02bf6e629a9d26d10afa426f1a13fd57ef9 Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:23:41 +0530 Subject: [PATCH 4/9] Update alarm_ring_view.dart --- .../alarmRing/views/alarm_ring_view.dart | 481 ++++++++---------- 1 file changed, 206 insertions(+), 275 deletions(-) diff --git a/lib/app/modules/alarmRing/views/alarm_ring_view.dart b/lib/app/modules/alarmRing/views/alarm_ring_view.dart index 32441702..d547cf6d 100644 --- a/lib/app/modules/alarmRing/views/alarm_ring_view.dart +++ b/lib/app/modules/alarmRing/views/alarm_ring_view.dart @@ -1,290 +1,221 @@ -import 'dart:async'; -import 'dart:math'; - import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -import 'package:flutter_fgbg/flutter_fgbg.dart'; -import 'package:flutter_volume_controller/flutter_volume_controller.dart'; import 'package:get/get.dart'; -import 'package:ultimate_alarm_clock/app/data/models/alarm_model.dart'; - -import 'package:ultimate_alarm_clock/app/data/models/user_model.dart'; - -import 'package:ultimate_alarm_clock/app/data/providers/firestore_provider.dart'; -import 'package:ultimate_alarm_clock/app/data/providers/isar_provider.dart'; -import 'package:ultimate_alarm_clock/app/data/providers/secure_storage_provider.dart'; -import 'package:ultimate_alarm_clock/app/utils/audio_utils.dart'; - +import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; +import 'package:ultimate_alarm_clock/app/utils/constants.dart'; import 'package:ultimate_alarm_clock/app/utils/utils.dart'; -import 'package:vibration/vibration.dart'; - -class AlarmControlController extends GetxController { - MethodChannel alarmChannel = MethodChannel('ulticlock'); - RxString note = ''.obs; - Timer? vibrationTimer; - late StreamSubscription _subscription; - TimeOfDay currentTime = TimeOfDay.now(); - late RxBool isSnoozing = false.obs; - RxInt minutes = 1.obs; - RxInt seconds = 0.obs; - RxBool showButton = false.obs; - final Rx currentlyRingingAlarm = Utils.genFakeAlarmModel().obs; - final formattedDate = Utils.getFormattedDate(DateTime.now()).obs; - final timeNow = - Utils.convertTo12HourFormat(Utils.timeOfDayToString(TimeOfDay.now())).obs; - Timer? _currentTimeTimer; - bool isAlarmActive = true; - late double initialVolume; - - getCurrentlyRingingAlarm() async { - UserModel? _userModel = await SecureStorageProvider().retrieveUserModel(); - AlarmModel _alarmRecord = Utils.genFakeAlarmModel(); - AlarmModel isarLatestAlarm = - await IsarDb.getLatestAlarm(_alarmRecord, false); - AlarmModel firestoreLatestAlarm = - await FirestoreDb.getLatestAlarm(_userModel, _alarmRecord, false); - AlarmModel latestAlarm = - Utils.getFirstScheduledAlarm(isarLatestAlarm, firestoreLatestAlarm); - debugPrint('CURRENT RINGING : ${latestAlarm.alarmTime}'); - - return latestAlarm; - } - - getAlarm() async { - UserModel? _userModel = await SecureStorageProvider().retrieveUserModel(); - AlarmModel _alarmRecord = Utils.genFakeAlarmModel(); - AlarmModel isarLatestAlarm = - await IsarDb.getLatestAlarm(_alarmRecord, true); - AlarmModel firestoreLatestAlarm = - await FirestoreDb.getLatestAlarm(_userModel, _alarmRecord, true); - AlarmModel latestAlarm = - Utils.getFirstScheduledAlarm(isarLatestAlarm, firestoreLatestAlarm); - debugPrint('LATEST : ${latestAlarm.alarmTime}'); - - return latestAlarm; - } - - void startSnooze() async { - Vibration.cancel(); - vibrationTimer!.cancel(); - isSnoozing.value = true; - String ringtoneName = currentlyRingingAlarm.value.ringtoneName; - AudioUtils.stopAlarm(ringtoneName: ringtoneName); - - if (_currentTimeTimer!.isActive) { - _currentTimeTimer?.cancel(); - } - - _currentTimeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { - if (minutes.value == 0 && seconds.value == 0) { - timer.cancel(); - vibrationTimer = - Timer.periodic(const Duration(milliseconds: 3500), (Timer timer) { - Vibration.vibrate(pattern: [500, 3000]); - }); - - AudioUtils.playAlarm(alarmRecord: currentlyRingingAlarm.value); - - startTimer(); - } else if (seconds.value == 0) { - minutes.value--; - seconds.value = 59; - } else { - seconds.value--; - } - }); - } - - void startTimer() { - minutes.value = currentlyRingingAlarm.value.snoozeDuration; - isSnoozing.value = false; - _currentTimeTimer = Timer.periodic( - Duration( - milliseconds: Utils.getMillisecondsToAlarm( - DateTime.now(), - DateTime.now().add(const Duration(minutes: 1)), - ), - ), (timer) { - formattedDate.value = Utils.getFormattedDate(DateTime.now()); - timeNow.value = - Utils.convertTo12HourFormat(Utils.timeOfDayToString(TimeOfDay.now())); - }); - } - - Future _fadeInAlarmVolume() async { - await FlutterVolumeController.setVolume( - currentlyRingingAlarm.value.volMin / 10.0, - stream: AudioStream.alarm, - ); - await Future.delayed(const Duration(milliseconds: 2000)); - - double vol = currentlyRingingAlarm.value.volMin / 10.0; - double diff = (currentlyRingingAlarm.value.volMax - - currentlyRingingAlarm.value.volMin) / - 10.0; - int len = currentlyRingingAlarm.value.gradient * 1000; - double steps = (diff / 0.01).abs(); - int stepLen = max(4, (steps > 0) ? len ~/ steps : len); - int lastTick = DateTime.now().millisecondsSinceEpoch; - - Timer.periodic(Duration(milliseconds: stepLen), (Timer t) { - if (!isAlarmActive) { - t.cancel(); - return; - } - var now = DateTime.now().millisecondsSinceEpoch; - var tick = (now - lastTick) / len; - lastTick = now; - vol += diff * tick; +import '../controllers/alarm_ring_controller.dart'; - vol = max(currentlyRingingAlarm.value.volMin / 10.0, vol); - vol = min(currentlyRingingAlarm.value.volMax / 10.0, vol); - vol = (vol * 100).round() / 100; +class AlarmControlView extends GetView { + AlarmControlView({Key? key}) : super(key: key); - FlutterVolumeController.setVolume( - vol, - stream: AudioStream.alarm, - ); - - if (vol >= currentlyRingingAlarm.value.volMax / 10.0) { - t.cancel(); - } - }); - } + ThemeController themeController = Get.find(); @override - void onInit() async { - super.onInit(); - initialVolume = await FlutterVolumeController.getVolume( - stream: AudioStream.alarm, - ) as double; - - FlutterVolumeController.updateShowSystemUI(false); - - _fadeInAlarmVolume(); - - if (currentlyRingingAlarm.value.deleteAfterGoesOff == true) { - if (currentlyRingingAlarm.value.isSharedAlarmEnabled) { - FirestoreDb.deleteOneTimeAlarm( - currentlyRingingAlarm.value.ownerId, - currentlyRingingAlarm.value.firestoreId, - ); - } else { - IsarDb.deleteAlarm(currentlyRingingAlarm.value.isarId); - } - } - vibrationTimer = - Timer.periodic(const Duration(milliseconds: 3500), (Timer timer) { - Vibration.vibrate(pattern: [500, 3000]); - }); - - // Preventing app from being minimized! - _subscription = FGBGEvents.stream.listen((event) { - if (event == FGBGType.background) { - alarmChannel.invokeMethod('bringAppToForeground'); - } - }); - - startTimer(); - if (Get.arguments == null) { - currentlyRingingAlarm.value = await getCurrentlyRingingAlarm(); - showButton.value = true; - // If the alarm is set to NEVER repeat, then it will - // be chosen as the alarm to ring by default as - // it would ring the day - if (currentlyRingingAlarm.value.days - .every((element) => element == false)) { - currentlyRingingAlarm.value.isEnabled = false; - - if (currentlyRingingAlarm.value.isSharedAlarmEnabled == false) { - IsarDb.updateAlarm(currentlyRingingAlarm.value); - } else { - FirestoreDb.updateAlarm( - currentlyRingingAlarm.value.ownerId, - currentlyRingingAlarm.value, - ); - } - } else if (currentlyRingingAlarm.value.isOneTime == true) { - // If the alarm has to repeat on one day, but ring just once, we will - // keep seting its days to false until it will never ring - int currentDay = DateTime.now().weekday - 1; - currentlyRingingAlarm.value.days[currentDay] = false; - - if (currentlyRingingAlarm.value.days - .every((element) => element == false)) { - currentlyRingingAlarm.value.isEnabled = false; - } - - if (currentlyRingingAlarm.value.isSharedAlarmEnabled == false) { - IsarDb.updateAlarm(currentlyRingingAlarm.value); - } else { - FirestoreDb.updateAlarm( - currentlyRingingAlarm.value.ownerId, - currentlyRingingAlarm.value, - ); + Widget build(BuildContext context) { + var width = Get.width; + var height = Get.height; + return PopScope( + canPop: false, + onPopInvoked: (bool didPop) { + if (didPop) { + return; } - } - } else { - currentlyRingingAlarm.value = Get.arguments; - showButton.value = true; - } - AudioUtils.playAlarm(alarmRecord: currentlyRingingAlarm.value); - - // Setting snooze duration - minutes.value = currentlyRingingAlarm.value.snoozeDuration; - - // Scheduling alarm if it's not in preview mode - if (Get.arguments == null) { - // Finding the alarm to ring - AlarmModel latestAlarm = await getAlarm(); - TimeOfDay latestAlarmTimeOfDay = - Utils.stringToTimeOfDay(latestAlarm.alarmTime); - - // } - // This condition will never satisfy because this will only - // occur if fake model is returned as latest alarm - if (latestAlarm.isEnabled == false) { - debugPrint( - 'STOPPED IF CONDITION with latest = ' - '${latestAlarmTimeOfDay.toString()} and ' - 'current = ${currentTime.toString()}', + Get.snackbar( + 'Note'.tr, + "You can't go back while the alarm is ringing".tr, + backgroundColor: Colors.red, + colorText: Colors.white, ); - - await alarmChannel.invokeMethod('cancelAllScheduledAlarms'); - } else { - int intervaltoAlarm = Utils.getMillisecondsToAlarm( - DateTime.now(), - Utils.timeOfDayToDateTime(latestAlarmTimeOfDay), - ); - - try { - await alarmChannel - .invokeMethod('scheduleAlarm', {'milliSeconds': intervaltoAlarm}); - print("Scheduled..."); - } on PlatformException catch (e) { - print("Failed to schedule alarm: ${e.message}"); - } - } - } - } - - @override - void onClose() async { - super.onClose(); - Vibration.cancel(); - vibrationTimer!.cancel(); - isAlarmActive = false; - String ringtoneName = currentlyRingingAlarm.value.ringtoneName; - AudioUtils.stopAlarm(ringtoneName: ringtoneName); - await FlutterVolumeController.setVolume( - initialVolume, - stream: AudioStream.alarm, + }, + child: SafeArea( + child: Scaffold( + floatingActionButtonLocation: + FloatingActionButtonLocation.centerDocked, + floatingActionButton: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.all(18.0), + child: Obx( + () => SizedBox( + height: height * 0.06, + width: width * 0.8, + child: controller.showButton.value + ? TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + kprimaryColor, + ), + ), + child: Text( + Utils.isChallengeEnabled( + controller.currentlyRingingAlarm.value, + ) + ? 'Start Challenge'.tr + : 'Dismiss'.tr, + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () { + Utils.hapticFeedback(); + if (Utils.isChallengeEnabled( + controller.currentlyRingingAlarm.value, + )) { + Get.toNamed( + '/alarm-challenge', + arguments: + controller.currentlyRingingAlarm.value, + ); + } else { + Get.offNamed( + '/bottom-navigation-bar', + arguments: controller.currentlyRingingAlarm + .value.showMotivationalQuote, + ); + } + }, + ) + : const SizedBox(), + ), + ), + ), + (Get.arguments != null) + ? Padding( + padding: const EdgeInsets.all(8.0), + child: Obx( + () => SizedBox( + height: height * 0.06, + width: width, + child: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.7) + : kprimaryTextColor.withOpacity(0.7), + ), + ), + child: Text( + 'Exit Preview'.tr, + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () { + Utils.hapticFeedback(); + Get.offNamed('/bottom-navigation-bar'); + }, + ), + ), + ), + ) + : const SizedBox(), + ], + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Obx( + () => Column( + children: [ + Text( + controller.formattedDate.value, + style: Theme.of(context).textTheme.bodyLarge, + ), + const SizedBox( + height: 10, + width: 0, + ), + Text( + (controller.isSnoozing.value) + ? "${controller.minutes.toString().padLeft(2, '0')}" + // ignore: lines_longer_than_80_chars + ":${controller.seconds.toString().padLeft(2, '0')}" + : '${controller.timeNow[0]} ' + '${controller.timeNow[1]}', + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith(fontSize: 50), + ), + ], + ), + ), + Obx( + () => Visibility( + visible: + controller.currentlyRingingAlarm.value.note.isNotEmpty, + child: Text( + controller.currentlyRingingAlarm.value.note, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + fontSize: 20, + fontWeight: FontWeight.w100, + fontStyle: FontStyle.italic, + ), + ), + ), + ), + Obx( + () => Visibility( + visible: !controller.isSnoozing.value, + child: Obx( + () => Padding( + padding: Get.arguments != null + ? const EdgeInsets.symmetric(vertical: 90.0) + : EdgeInsets.zero, + child: SizedBox( + height: height * 0.07, + width: width * 0.5, + child: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + ), + ), + child: Text( + 'Snooze'.tr, + style: + Theme.of(context).textTheme.bodyMedium!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + fontWeight: FontWeight.w600, + ), + ), + onPressed: () { + Utils.hapticFeedback(); + controller.startSnooze(); + }, + ), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), ); - _subscription.cancel(); - _currentTimeTimer?.cancel(); } } From bd47aec488c8176e752b2eb7f7ccb418005bca70 Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:35:27 +0530 Subject: [PATCH 5/9] Update stopwatch_controller.dart --- .../modules/stopwatch/controllers/stopwatch_controller.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart b/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart index 30012772..6aa4674a 100644 --- a/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart +++ b/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart @@ -54,8 +54,6 @@ class StopwatchController extends GetxController { void _updateResult() { _result.value = - '${_stopwatch.elapsed.inMinutes.toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds %60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inMilliseconds % 100).toString().padLeft(2, '0')}'; - - '${_stopwatch.elapsed.inMinutes.toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds % 60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inMilliseconds % 1000 ~/ 10).toString().padLeft(2, '0')}'; + '${_stopwatch.elapsed.inMinutes.toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds %60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inMilliseconds % 100).toString().padLeft(2, '0')}'; } } From aca5fab317c2f408272613e4b92b468175a77a13 Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:39:14 +0530 Subject: [PATCH 6/9] Update stopwatch_controller.dart without conflicts --- lib/app/modules/stopwatch/controllers/stopwatch_controller.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart b/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart index 6aa4674a..52505464 100644 --- a/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart +++ b/lib/app/modules/stopwatch/controllers/stopwatch_controller.dart @@ -54,6 +54,6 @@ class StopwatchController extends GetxController { void _updateResult() { _result.value = - '${_stopwatch.elapsed.inMinutes.toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds %60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inMilliseconds % 100).toString().padLeft(2, '0')}'; + '${_stopwatch.elapsed.inMinutes.toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds % 60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inMilliseconds % 1000 ~/ 10).toString().padLeft(2, '0')}'; } } From 62730ab899a9fe91d15c4d476ba84c721d77fa2b Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:44:53 +0530 Subject: [PATCH 7/9] Update stopwatch_view.dart --- lib/app/modules/stopwatch/views/stopwatch_view.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/app/modules/stopwatch/views/stopwatch_view.dart b/lib/app/modules/stopwatch/views/stopwatch_view.dart index 973cf075..5bedda80 100644 --- a/lib/app/modules/stopwatch/views/stopwatch_view.dart +++ b/lib/app/modules/stopwatch/views/stopwatch_view.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -//import 'package:get_storage/get_storage.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/stopwatch/controllers/stopwatch_controller.dart'; import 'package:ultimate_alarm_clock/app/routes/app_pages.dart'; @@ -12,7 +11,7 @@ class StopwatchView extends GetView { ThemeController themeController = Get.find(); @override Widget build(BuildContext context) { - var width = Get.width; + var width = Get.width; var height = Get.height; return Scaffold( appBar: PreferredSize( From 44afd0ad77e76d5283e9cf2c67acc56577826e62 Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:46:21 +0530 Subject: [PATCH 8/9] Update stopwatch_view.dart --- lib/app/modules/stopwatch/views/stopwatch_view.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/app/modules/stopwatch/views/stopwatch_view.dart b/lib/app/modules/stopwatch/views/stopwatch_view.dart index 5bedda80..7eb4286a 100644 --- a/lib/app/modules/stopwatch/views/stopwatch_view.dart +++ b/lib/app/modules/stopwatch/views/stopwatch_view.dart @@ -3,6 +3,7 @@ import 'package:get/get.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/stopwatch/controllers/stopwatch_controller.dart'; import 'package:ultimate_alarm_clock/app/routes/app_pages.dart'; +import 'package:ultimate_alarm_clock/app/utils/end_drawer.dart'; import '../../../utils/constants.dart'; import '../../../utils/utils.dart'; From a2159ca6d4b7666e66f8a3b1d8c8736771552e9d Mon Sep 17 00:00:00 2001 From: Vansh Gupta <149355139+codesage01@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:52:12 +0530 Subject: [PATCH 9/9] Update add_or_update_alarm_view.dart --- .../views/add_or_update_alarm_view.dart | 78 +------------------ 1 file changed, 4 insertions(+), 74 deletions(-) diff --git a/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart b/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart index c422e190..935333b3 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -48,79 +50,7 @@ class AddOrUpdateAlarmView extends GetView { if (didPop) { return; } - - Get.defaultDialog( - titlePadding: const EdgeInsets.symmetric( - vertical: 20, - ), - backgroundColor: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - title: 'Discard Changes?'.tr, - titleStyle: Theme.of(context).textTheme.displaySmall, - content: Column( - children: [ - Text( - 'unsavedChanges'.tr, - style: Theme.of(context).textTheme.bodyMedium, - textAlign: TextAlign.center, - ), - Padding( - padding: const EdgeInsets.only( - top: 20, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - TextButton( - onPressed: () { - Get.back(); - }, - style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(kprimaryColor), - ), - child: Text( - 'Cancel'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: kprimaryBackgroundColor, - ), - ), - ), - OutlinedButton( - onPressed: () { - Get.back(closeOverlays: true); - Get.back(); - }, - style: OutlinedButton.styleFrom( - side: BorderSide( - color: themeController.isLightMode.value - ? Colors.red.withOpacity(0.9) - : Colors.red, - width: 1, - ), - ), - child: Text( - 'Leave'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController.isLightMode.value - ? Colors.red.withOpacity(0.9) - : Colors.red, - ), - ), - ), - ], - ), - ), - ], - ), - ); + controller.checkUnsavedChangesAndNavigate(context); }, child: Scaffold( floatingActionButtonLocation: @@ -1134,4 +1064,4 @@ class AddOrUpdateAlarmView extends GetView { ), )); } -} \ No newline at end of file +}