diff --git a/lib/app/modules/addOrUpdateAlarm/controllers/add_or_update_alarm_controller.dart b/lib/app/modules/addOrUpdateAlarm/controllers/add_or_update_alarm_controller.dart index 8c6086ed..4ab7ac8d 100644 --- a/lib/app/modules/addOrUpdateAlarm/controllers/add_or_update_alarm_controller.dart +++ b/lib/app/modules/addOrUpdateAlarm/controllers/add_or_update_alarm_controller.dart @@ -108,6 +108,10 @@ class AddOrUpdateAlarmController extends GetxController { RxBool isCustomSelected = false.obs; RxBool isPlaying = false.obs; // Observable boolean to track playing state + // to check whether alarm data is updated or not + Map initialValues = {}; + Map changedFields = {}; + void toggleIsPlaying() { isPlaying.toggle(); } @@ -226,6 +230,80 @@ class AddOrUpdateAlarmController extends GetxController { } } + void checkUnsavedChangesAndNavigate(BuildContext context) { + int numberOfChangesMade = + changedFields.entries.where((element) => element.value == true).length; + if (numberOfChangesMade >= 1) { + 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, + ), + ), + ), + ], + ), + ), + ], + ), + ); + } else { + Get.back(); + } + } + Future getLocation() async { if (await _checkAndRequestPermission()) { const timeLimit = Duration(seconds: 10); @@ -693,6 +771,85 @@ class AddOrUpdateAlarmController extends GetxController { repeatDays, ); + // store initial values of the variables + initialValues.addAll({ + 'selectedTime': selectedTime.value, + 'daysRepeating': daysRepeating.value, + 'snoozeDuration': snoozeDuration.value, + 'deleteAfterGoesOff': deleteAfterGoesOff.value, + 'label': label.value, + 'note': note.value, + 'customRingtoneName': customRingtoneName.value, + 'volMin': volMin.value, + 'volMax': volMax.value, + 'gradient': gradient.value, + 'showMotivationalQuote': showMotivationalQuote.value, + 'activityInterval': activityInterval.value, + 'weatherTypes': weatherTypes.value, + 'location': + '${selectedPoint.value.latitude} ${selectedPoint.value.longitude}', + 'shakeTimes': shakeTimes.value, + 'qrValue': qrValue.value, + 'mathsDifficulty': mathsDifficulty.value, + 'mathsSliderValue': mathsSliderValue.value, + 'numMathsQuestions': numMathsQuestions.value, + 'numberOfSteps': numberOfSteps.value, + 'isSharedAlarmEnabled': isSharedAlarmEnabled.value, + 'offsetDuration': offsetDuration.value, + 'isOffsetBefore': isOffsetBefore.value + }); + + addListeners(); + + if (await SecureStorageProvider().retrieveApiKey(ApiKeys.openWeatherMap) != + null) { + weatherApiKeyExists.value = true; + } + + // If there's an argument sent, we are in update mode + } + + void addListeners() { + // Updating UI to show time to alarm + selectedTime.listen((time) { + debugPrint('CHANGED CHANGED CHANGED CHANGED'); + timeToAlarm.value = + Utils.timeUntilAlarm(TimeOfDay.fromDateTime(time), repeatDays); + _compareAndSetChange('selectedTime', time); + }); + + //Updating UI to show repeated days + repeatDays.listen((days) { + daysRepeating.value = Utils.getRepeatDays(days); + _compareAndSetChange('daysRepeating', daysRepeating.value); + }); + + setupListener(snoozeDuration, 'snoozeDuration'); + setupListener(deleteAfterGoesOff, 'deleteAfterGoesOff'); + setupListener(label, 'label'); + setupListener(note, 'note'); + setupListener(customRingtoneName, 'customRingtoneName'); + setupListener(volMin, 'volMin'); + setupListener(volMax, 'volMax'); + setupListener(gradient, 'gradient'); + setupListener(showMotivationalQuote, 'showMotivationalQuote'); + setupListener(activityInterval, 'activityInterval'); + + // Updating UI to show weather types + selectedWeather.listen((weather) { + if (weather.toList().isEmpty) { + isWeatherEnabled.value = false; + } else { + isWeatherEnabled.value = true; + } + weatherTypes.value = Utils.getFormattedWeatherTypes(weather); + _compareAndSetChange('weatherTypes', weatherTypes.value); + // if location based is disabled and weather based is disabled, reset location + if (weatherTypes.value == 'Off' && !isLocationEnabled.value) { + selectedPoint.value = LatLng(0, 0); + } + }); + // Adding to markers list, to display on map // (MarkersLayer takes only List) selectedPoint.listen( @@ -709,38 +866,44 @@ class AddOrUpdateAlarmController extends GetxController { ), ), ); + _compareAndSetChange( + 'location', '${point.latitude} ${point.longitude}'); }, ); - // Updating UI to show time to alarm - - selectedTime.listen((time) { - debugPrint('CHANGED CHANGED CHANGED CHANGED'); - timeToAlarm.value = - Utils.timeUntilAlarm(TimeOfDay.fromDateTime(time), repeatDays); + // reset selectedPoint to default value if isLocationEnabled is false and weather based is off + isLocationEnabled.listen((value) { + if (!value && weatherTypes.value == 'Off') { + selectedPoint.value = LatLng(0, 0); + } }); - //Updating UI to show repeated days - repeatDays.listen((days) { - daysRepeating.value = Utils.getRepeatDays(days); - }); + setupListener(shakeTimes, 'shakeTimes'); + setupListener(qrValue, 'qrValue'); + setupListener(mathsSliderValue, 'mathsSliderValue'); + setupListener(mathsDifficulty, 'mathsDifficulty'); + setupListener(numMathsQuestions, 'numMathsQuestions'); + setupListener(numberOfSteps, 'numberOfSteps'); - // Updating UI to show weather types - selectedWeather.listen((weather) { - if (weather.toList().isEmpty) { - isWeatherEnabled.value = false; - } else { - isWeatherEnabled.value = true; - } - weatherTypes.value = Utils.getFormattedWeatherTypes(weather); + setupListener(isSharedAlarmEnabled, 'isSharedAlarmEnabled'); + setupListener(offsetDuration, 'offsetDuration'); + setupListener(isOffsetBefore, 'isOffsetBefore'); + } + + // adds listener to rxVar variable + void setupListener(Rx rxVar, String fieldName) { + rxVar.listen((value) { + _compareAndSetChange(fieldName, value); }); + } - if (await SecureStorageProvider().retrieveApiKey(ApiKeys.openWeatherMap) != - null) { - weatherApiKeyExists.value = true; + // if initialValues map contains fieldName and newValue is equal to currentValue + // then set changeFields map field to true + void _compareAndSetChange(String fieldName, dynamic currentValue) { + if (initialValues.containsKey(fieldName)) { + bool hasChanged = initialValues[fieldName] != currentValue; + changedFields[fieldName] = hasChanged; } - - // If there's an argument sent, we are in update mode } @override 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..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: diff --git a/pubspec.lock b/pubspec.lock index 0d12a93c..3e22276e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -564,10 +564,10 @@ packages: dependency: "direct main" description: name: get - sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a" + sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e url: "https://pub.dev" source: hosted - version: "4.6.5" + version: "4.6.6" get_storage: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index b6d81f36..86166b9f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: firebase_core: ^2.8.0 screen_state: ^2.0.0 cupertino_icons: ^1.0.2 - get: 4.6.5 + get: 4.6.6 get_storage: ^2.1.1 flutter_time_picker_spinner: ^2.0.0 cloud_firestore: ^4.4.5