From 1b898d5bdd75f2585fb896df5c7b9e7109428b92 Mon Sep 17 00:00:00 2001 From: krish Date: Fri, 23 Feb 2024 00:59:25 +0530 Subject: [PATCH 01/14] added image picker --- lib/app/data/models/alarm_model.dart | 10 + lib/app/data/models/alarm_model.g.dart | 482 +++++++++++++----- .../add_or_update_alarm_controller.dart | 98 +++- .../views/add_or_update_alarm_view.dart | 3 + .../views/photo_challenge_tile.dart | 0 lib/app/utils/utils.dart | 2 + linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 4 + pubspec.lock | 140 ++++- pubspec.yaml | 2 + .../flutter/generated_plugin_registrant.cc | 6 + windows/flutter/generated_plugins.cmake | 2 + 13 files changed, 624 insertions(+), 130 deletions(-) create mode 100644 lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart diff --git a/lib/app/data/models/alarm_model.dart b/lib/app/data/models/alarm_model.dart index 44e340e2..141978da 100644 --- a/lib/app/data/models/alarm_model.dart +++ b/lib/app/data/models/alarm_model.dart @@ -22,6 +22,7 @@ class AlarmModel { late bool isShakeEnabled; late bool isQrEnabled; late bool isPedometerEnabled; + late bool isPhotochallengeEnabled; late int intervalToAlarm; late bool isActivityEnabled; late String location; @@ -34,6 +35,7 @@ class AlarmModel { late int numMathsQuestions; late int mathsDifficulty; late String qrValue; + late String imageurl; List? sharedUserIds; late String ownerId; late String ownerName; @@ -83,6 +85,8 @@ class AlarmModel { required this.isPedometerEnabled, required this.numberOfSteps, required this.activityInterval, + required this.isPhotochallengeEnabled, + required this.imageurl, this.offsetDetails = const {}, required this.mainAlarmTime, required this.label, @@ -146,6 +150,8 @@ class AlarmModel { numMathsQuestions = documentSnapshot['numMathsQuestions']; isQrEnabled = documentSnapshot['isQrEnabled']; qrValue = documentSnapshot['qrValue']; + isPhotochallengeEnabled = documentSnapshot['isPhotochallengeEnabled']; + imageurl = documentSnapshot['imageurl']; isShakeEnabled = documentSnapshot['isShakeEnabled']; shakeTimes = documentSnapshot['shakeTimes']; isPedometerEnabled = documentSnapshot['isPedometerEnabled']; @@ -190,6 +196,8 @@ class AlarmModel { numMathsQuestions = alarmData['numMathsQuestions']; isQrEnabled = alarmData['isQrEnabled']; qrValue = alarmData['qrValue']; + isPhotochallengeEnabled = alarmData['isPhotochallengeEnabled']; + imageurl = alarmData['imageurl']; isShakeEnabled = alarmData['isShakeEnabled']; shakeTimes = alarmData['shakeTimes']; isPedometerEnabled = alarmData['isPedometerEnabled']; @@ -241,6 +249,8 @@ class AlarmModel { 'numMathsQuestions': alarmRecord.numMathsQuestions, 'isQrEnabled': alarmRecord.isQrEnabled, 'qrValue': alarmRecord.qrValue, + 'isPhotochallengeEnabled': alarmRecord.isPhotochallengeEnabled, + 'imageurl': alarmRecord.imageurl, 'isShakeEnabled': alarmRecord.isShakeEnabled, 'shakeTimes': alarmRecord.shakeTimes, 'isPedometerEnabled': alarmRecord.isPedometerEnabled, diff --git a/lib/app/data/models/alarm_model.g.dart b/lib/app/data/models/alarm_model.g.dart index 452defaa..c8744b39 100644 --- a/lib/app/data/models/alarm_model.g.dart +++ b/lib/app/data/models/alarm_model.g.dart @@ -52,168 +52,178 @@ const AlarmModelSchema = CollectionSchema( name: r'gradient', type: IsarType.long, ), - r'intervalToAlarm': PropertySchema( + r'imageurl': PropertySchema( id: 7, + name: r'imageurl', + type: IsarType.string, + ), + r'intervalToAlarm': PropertySchema( + id: 8, name: r'intervalToAlarm', type: IsarType.long, ), r'isActivityEnabled': PropertySchema( - id: 8, + id: 9, name: r'isActivityEnabled', type: IsarType.bool, ), r'isEnabled': PropertySchema( - id: 9, + id: 10, name: r'isEnabled', type: IsarType.bool, ), r'isLocationEnabled': PropertySchema( - id: 10, + id: 11, name: r'isLocationEnabled', type: IsarType.bool, ), r'isMathsEnabled': PropertySchema( - id: 11, + id: 12, name: r'isMathsEnabled', type: IsarType.bool, ), r'isOneTime': PropertySchema( - id: 12, + id: 13, name: r'isOneTime', type: IsarType.bool, ), r'isPedometerEnabled': PropertySchema( - id: 13, + id: 14, name: r'isPedometerEnabled', type: IsarType.bool, ), + r'isPhotochallengeEnabled': PropertySchema( + id: 15, + name: r'isPhotochallengeEnabled', + type: IsarType.bool, + ), r'isQrEnabled': PropertySchema( - id: 14, + id: 16, name: r'isQrEnabled', type: IsarType.bool, ), r'isShakeEnabled': PropertySchema( - id: 15, + id: 17, name: r'isShakeEnabled', type: IsarType.bool, ), r'isSharedAlarmEnabled': PropertySchema( - id: 16, + id: 18, name: r'isSharedAlarmEnabled', type: IsarType.bool, ), r'isTimer': PropertySchema( - id: 17, + id: 19, name: r'isTimer', type: IsarType.bool, ), r'isWeatherEnabled': PropertySchema( - id: 18, + id: 20, name: r'isWeatherEnabled', type: IsarType.bool, ), r'label': PropertySchema( - id: 19, + id: 21, name: r'label', type: IsarType.string, ), r'lastEditedUserId': PropertySchema( - id: 20, + id: 22, name: r'lastEditedUserId', type: IsarType.string, ), r'location': PropertySchema( - id: 21, + id: 23, name: r'location', type: IsarType.string, ), r'mainAlarmTime': PropertySchema( - id: 22, + id: 24, name: r'mainAlarmTime', type: IsarType.string, ), r'mathsDifficulty': PropertySchema( - id: 23, + id: 25, name: r'mathsDifficulty', type: IsarType.long, ), r'minutesSinceMidnight': PropertySchema( - id: 24, + id: 26, name: r'minutesSinceMidnight', type: IsarType.long, ), r'mutexLock': PropertySchema( - id: 25, + id: 27, name: r'mutexLock', type: IsarType.bool, ), r'note': PropertySchema( - id: 26, + id: 28, name: r'note', type: IsarType.string, ), r'numMathsQuestions': PropertySchema( - id: 27, + id: 29, name: r'numMathsQuestions', type: IsarType.long, ), r'numberOfSteps': PropertySchema( - id: 28, + id: 30, name: r'numberOfSteps', type: IsarType.long, ), r'ownerId': PropertySchema( - id: 29, + id: 31, name: r'ownerId', type: IsarType.string, ), r'ownerName': PropertySchema( - id: 30, + id: 32, name: r'ownerName', type: IsarType.string, ), r'qrValue': PropertySchema( - id: 31, + id: 33, name: r'qrValue', type: IsarType.string, ), r'ringtoneName': PropertySchema( - id: 32, + id: 34, name: r'ringtoneName', type: IsarType.string, ), r'shakeTimes': PropertySchema( - id: 33, + id: 35, name: r'shakeTimes', type: IsarType.long, ), r'sharedUserIds': PropertySchema( - id: 34, + id: 36, name: r'sharedUserIds', type: IsarType.stringList, ), r'showMotivationalQuote': PropertySchema( - id: 35, + id: 37, name: r'showMotivationalQuote', type: IsarType.bool, ), r'snoozeDuration': PropertySchema( - id: 36, + id: 38, name: r'snoozeDuration', type: IsarType.long, ), r'volMax': PropertySchema( - id: 37, + id: 39, name: r'volMax', type: IsarType.double, ), r'volMin': PropertySchema( - id: 38, + id: 40, name: r'volMin', type: IsarType.double, ), r'weatherTypes': PropertySchema( - id: 39, + id: 41, name: r'weatherTypes', type: IsarType.longList, ) @@ -247,6 +257,7 @@ int _alarmModelEstimateSize( bytesCount += 3 + value.length * 3; } } + bytesCount += 3 + object.imageurl.length * 3; bytesCount += 3 + object.label.length * 3; bytesCount += 3 + object.lastEditedUserId.length * 3; bytesCount += 3 + object.location.length * 3; @@ -290,39 +301,41 @@ void _alarmModelSerialize( writer.writeBool(offsets[4], object.deleteAfterGoesOff); writer.writeString(offsets[5], object.firestoreId); writer.writeLong(offsets[6], object.gradient); - writer.writeLong(offsets[7], object.intervalToAlarm); - writer.writeBool(offsets[8], object.isActivityEnabled); - writer.writeBool(offsets[9], object.isEnabled); - writer.writeBool(offsets[10], object.isLocationEnabled); - writer.writeBool(offsets[11], object.isMathsEnabled); - writer.writeBool(offsets[12], object.isOneTime); - writer.writeBool(offsets[13], object.isPedometerEnabled); - writer.writeBool(offsets[14], object.isQrEnabled); - writer.writeBool(offsets[15], object.isShakeEnabled); - writer.writeBool(offsets[16], object.isSharedAlarmEnabled); - writer.writeBool(offsets[17], object.isTimer); - writer.writeBool(offsets[18], object.isWeatherEnabled); - writer.writeString(offsets[19], object.label); - writer.writeString(offsets[20], object.lastEditedUserId); - writer.writeString(offsets[21], object.location); - writer.writeString(offsets[22], object.mainAlarmTime); - writer.writeLong(offsets[23], object.mathsDifficulty); - writer.writeLong(offsets[24], object.minutesSinceMidnight); - writer.writeBool(offsets[25], object.mutexLock); - writer.writeString(offsets[26], object.note); - writer.writeLong(offsets[27], object.numMathsQuestions); - writer.writeLong(offsets[28], object.numberOfSteps); - writer.writeString(offsets[29], object.ownerId); - writer.writeString(offsets[30], object.ownerName); - writer.writeString(offsets[31], object.qrValue); - writer.writeString(offsets[32], object.ringtoneName); - writer.writeLong(offsets[33], object.shakeTimes); - writer.writeStringList(offsets[34], object.sharedUserIds); - writer.writeBool(offsets[35], object.showMotivationalQuote); - writer.writeLong(offsets[36], object.snoozeDuration); - writer.writeDouble(offsets[37], object.volMax); - writer.writeDouble(offsets[38], object.volMin); - writer.writeLongList(offsets[39], object.weatherTypes); + writer.writeString(offsets[7], object.imageurl); + writer.writeLong(offsets[8], object.intervalToAlarm); + writer.writeBool(offsets[9], object.isActivityEnabled); + writer.writeBool(offsets[10], object.isEnabled); + writer.writeBool(offsets[11], object.isLocationEnabled); + writer.writeBool(offsets[12], object.isMathsEnabled); + writer.writeBool(offsets[13], object.isOneTime); + writer.writeBool(offsets[14], object.isPedometerEnabled); + writer.writeBool(offsets[15], object.isPhotochallengeEnabled); + writer.writeBool(offsets[16], object.isQrEnabled); + writer.writeBool(offsets[17], object.isShakeEnabled); + writer.writeBool(offsets[18], object.isSharedAlarmEnabled); + writer.writeBool(offsets[19], object.isTimer); + writer.writeBool(offsets[20], object.isWeatherEnabled); + writer.writeString(offsets[21], object.label); + writer.writeString(offsets[22], object.lastEditedUserId); + writer.writeString(offsets[23], object.location); + writer.writeString(offsets[24], object.mainAlarmTime); + writer.writeLong(offsets[25], object.mathsDifficulty); + writer.writeLong(offsets[26], object.minutesSinceMidnight); + writer.writeBool(offsets[27], object.mutexLock); + writer.writeString(offsets[28], object.note); + writer.writeLong(offsets[29], object.numMathsQuestions); + writer.writeLong(offsets[30], object.numberOfSteps); + writer.writeString(offsets[31], object.ownerId); + writer.writeString(offsets[32], object.ownerName); + writer.writeString(offsets[33], object.qrValue); + writer.writeString(offsets[34], object.ringtoneName); + writer.writeLong(offsets[35], object.shakeTimes); + writer.writeStringList(offsets[36], object.sharedUserIds); + writer.writeBool(offsets[37], object.showMotivationalQuote); + writer.writeLong(offsets[38], object.snoozeDuration); + writer.writeDouble(offsets[39], object.volMax); + writer.writeDouble(offsets[40], object.volMin); + writer.writeLongList(offsets[41], object.weatherTypes); } AlarmModel _alarmModelDeserialize( @@ -338,39 +351,41 @@ AlarmModel _alarmModelDeserialize( days: reader.readBoolList(offsets[3]) ?? [], deleteAfterGoesOff: reader.readBool(offsets[4]), gradient: reader.readLong(offsets[6]), - intervalToAlarm: reader.readLong(offsets[7]), - isActivityEnabled: reader.readBool(offsets[8]), - isEnabled: reader.readBoolOrNull(offsets[9]) ?? true, - isLocationEnabled: reader.readBool(offsets[10]), - isMathsEnabled: reader.readBool(offsets[11]), - isOneTime: reader.readBool(offsets[12]), - isPedometerEnabled: reader.readBool(offsets[13]), - isQrEnabled: reader.readBool(offsets[14]), - isShakeEnabled: reader.readBool(offsets[15]), - isSharedAlarmEnabled: reader.readBool(offsets[16]), - isTimer: reader.readBool(offsets[17]), - isWeatherEnabled: reader.readBool(offsets[18]), - label: reader.readString(offsets[19]), - lastEditedUserId: reader.readString(offsets[20]), - location: reader.readString(offsets[21]), - mainAlarmTime: reader.readStringOrNull(offsets[22]), - mathsDifficulty: reader.readLong(offsets[23]), - minutesSinceMidnight: reader.readLong(offsets[24]), - mutexLock: reader.readBool(offsets[25]), - note: reader.readString(offsets[26]), - numMathsQuestions: reader.readLong(offsets[27]), - numberOfSteps: reader.readLong(offsets[28]), - ownerId: reader.readString(offsets[29]), - ownerName: reader.readString(offsets[30]), - qrValue: reader.readString(offsets[31]), - ringtoneName: reader.readString(offsets[32]), - shakeTimes: reader.readLong(offsets[33]), - sharedUserIds: reader.readStringList(offsets[34]), - showMotivationalQuote: reader.readBool(offsets[35]), - snoozeDuration: reader.readLong(offsets[36]), - volMax: reader.readDouble(offsets[37]), - volMin: reader.readDouble(offsets[38]), - weatherTypes: reader.readLongList(offsets[39]) ?? [], + imageurl: reader.readString(offsets[7]), + intervalToAlarm: reader.readLong(offsets[8]), + isActivityEnabled: reader.readBool(offsets[9]), + isEnabled: reader.readBoolOrNull(offsets[10]) ?? true, + isLocationEnabled: reader.readBool(offsets[11]), + isMathsEnabled: reader.readBool(offsets[12]), + isOneTime: reader.readBool(offsets[13]), + isPedometerEnabled: reader.readBool(offsets[14]), + isPhotochallengeEnabled: reader.readBool(offsets[15]), + isQrEnabled: reader.readBool(offsets[16]), + isShakeEnabled: reader.readBool(offsets[17]), + isSharedAlarmEnabled: reader.readBool(offsets[18]), + isTimer: reader.readBool(offsets[19]), + isWeatherEnabled: reader.readBool(offsets[20]), + label: reader.readString(offsets[21]), + lastEditedUserId: reader.readString(offsets[22]), + location: reader.readString(offsets[23]), + mainAlarmTime: reader.readStringOrNull(offsets[24]), + mathsDifficulty: reader.readLong(offsets[25]), + minutesSinceMidnight: reader.readLong(offsets[26]), + mutexLock: reader.readBool(offsets[27]), + note: reader.readString(offsets[28]), + numMathsQuestions: reader.readLong(offsets[29]), + numberOfSteps: reader.readLong(offsets[30]), + ownerId: reader.readString(offsets[31]), + ownerName: reader.readString(offsets[32]), + qrValue: reader.readString(offsets[33]), + ringtoneName: reader.readString(offsets[34]), + shakeTimes: reader.readLong(offsets[35]), + sharedUserIds: reader.readStringList(offsets[36]), + showMotivationalQuote: reader.readBool(offsets[37]), + snoozeDuration: reader.readLong(offsets[38]), + volMax: reader.readDouble(offsets[39]), + volMin: reader.readDouble(offsets[40]), + weatherTypes: reader.readLongList(offsets[41]) ?? [], ); object.firestoreId = reader.readStringOrNull(offsets[5]); object.isarId = id; @@ -399,13 +414,13 @@ P _alarmModelDeserializeProp

( case 6: return (reader.readLong(offset)) as P; case 7: - return (reader.readLong(offset)) as P; + return (reader.readString(offset)) as P; case 8: - return (reader.readBool(offset)) as P; + return (reader.readLong(offset)) as P; case 9: - return (reader.readBoolOrNull(offset) ?? true) as P; - case 10: return (reader.readBool(offset)) as P; + case 10: + return (reader.readBoolOrNull(offset) ?? true) as P; case 11: return (reader.readBool(offset)) as P; case 12: @@ -423,46 +438,50 @@ P _alarmModelDeserializeProp

( case 18: return (reader.readBool(offset)) as P; case 19: - return (reader.readString(offset)) as P; + return (reader.readBool(offset)) as P; case 20: - return (reader.readString(offset)) as P; + return (reader.readBool(offset)) as P; case 21: return (reader.readString(offset)) as P; case 22: - return (reader.readStringOrNull(offset)) as P; + return (reader.readString(offset)) as P; case 23: - return (reader.readLong(offset)) as P; + return (reader.readString(offset)) as P; case 24: - return (reader.readLong(offset)) as P; + return (reader.readStringOrNull(offset)) as P; case 25: - return (reader.readBool(offset)) as P; + return (reader.readLong(offset)) as P; case 26: - return (reader.readString(offset)) as P; - case 27: return (reader.readLong(offset)) as P; + case 27: + return (reader.readBool(offset)) as P; case 28: - return (reader.readLong(offset)) as P; - case 29: return (reader.readString(offset)) as P; + case 29: + return (reader.readLong(offset)) as P; case 30: - return (reader.readString(offset)) as P; + return (reader.readLong(offset)) as P; case 31: return (reader.readString(offset)) as P; case 32: return (reader.readString(offset)) as P; case 33: - return (reader.readLong(offset)) as P; + return (reader.readString(offset)) as P; case 34: - return (reader.readStringList(offset)) as P; + return (reader.readString(offset)) as P; case 35: - return (reader.readBool(offset)) as P; - case 36: return (reader.readLong(offset)) as P; + case 36: + return (reader.readStringList(offset)) as P; case 37: - return (reader.readDouble(offset)) as P; + return (reader.readBool(offset)) as P; case 38: - return (reader.readDouble(offset)) as P; + return (reader.readLong(offset)) as P; case 39: + return (reader.readDouble(offset)) as P; + case 40: + return (reader.readDouble(offset)) as P; + case 41: return (reader.readLongList(offset) ?? []) as P; default: throw IsarError('Unknown property with id $propertyId'); @@ -1200,6 +1219,140 @@ extension AlarmModelQueryFilter }); } + QueryBuilder imageurlEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'imageurl', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + imageurlGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'imageurl', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder imageurlLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'imageurl', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder imageurlBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'imageurl', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + imageurlStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'imageurl', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder imageurlEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'imageurl', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder imageurlContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'imageurl', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder imageurlMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'imageurl', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + imageurlIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'imageurl', + value: '', + )); + }); + } + + QueryBuilder + imageurlIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'imageurl', + value: '', + )); + }); + } + QueryBuilder intervalToAlarmEqualTo(int value) { return QueryBuilder.apply(this, (query) { @@ -1316,6 +1469,16 @@ extension AlarmModelQueryFilter }); } + QueryBuilder + isPhotochallengeEnabledEqualTo(bool value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'isPhotochallengeEnabled', + value: value, + )); + }); + } + QueryBuilder isQrEnabledEqualTo(bool value) { return QueryBuilder.apply(this, (query) { @@ -3589,6 +3752,18 @@ extension AlarmModelQuerySortBy }); } + QueryBuilder sortByImageurl() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'imageurl', Sort.asc); + }); + } + + QueryBuilder sortByImageurlDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'imageurl', Sort.desc); + }); + } + QueryBuilder sortByIntervalToAlarm() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'intervalToAlarm', Sort.asc); @@ -3679,6 +3854,20 @@ extension AlarmModelQuerySortBy }); } + QueryBuilder + sortByIsPhotochallengeEnabled() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'isPhotochallengeEnabled', Sort.asc); + }); + } + + QueryBuilder + sortByIsPhotochallengeEnabledDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'isPhotochallengeEnabled', Sort.desc); + }); + } + QueryBuilder sortByIsQrEnabled() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'isQrEnabled', Sort.asc); @@ -4057,6 +4246,18 @@ extension AlarmModelQuerySortThenBy }); } + QueryBuilder thenByImageurl() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'imageurl', Sort.asc); + }); + } + + QueryBuilder thenByImageurlDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'imageurl', Sort.desc); + }); + } + QueryBuilder thenByIntervalToAlarm() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'intervalToAlarm', Sort.asc); @@ -4147,6 +4348,20 @@ extension AlarmModelQuerySortThenBy }); } + QueryBuilder + thenByIsPhotochallengeEnabled() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'isPhotochallengeEnabled', Sort.asc); + }); + } + + QueryBuilder + thenByIsPhotochallengeEnabledDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'isPhotochallengeEnabled', Sort.desc); + }); + } + QueryBuilder thenByIsQrEnabled() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'isQrEnabled', Sort.asc); @@ -4508,6 +4723,13 @@ extension AlarmModelQueryWhereDistinct }); } + QueryBuilder distinctByImageurl( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'imageurl', caseSensitive: caseSensitive); + }); + } + QueryBuilder distinctByIntervalToAlarm() { return QueryBuilder.apply(this, (query) { return query.addDistinctBy(r'intervalToAlarm'); @@ -4553,6 +4775,13 @@ extension AlarmModelQueryWhereDistinct }); } + QueryBuilder + distinctByIsPhotochallengeEnabled() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'isPhotochallengeEnabled'); + }); + } + QueryBuilder distinctByIsQrEnabled() { return QueryBuilder.apply(this, (query) { return query.addDistinctBy(r'isQrEnabled'); @@ -4776,6 +5005,12 @@ extension AlarmModelQueryProperty }); } + QueryBuilder imageurlProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'imageurl'); + }); + } + QueryBuilder intervalToAlarmProperty() { return QueryBuilder.apply(this, (query) { return query.addPropertyName(r'intervalToAlarm'); @@ -4819,6 +5054,13 @@ extension AlarmModelQueryProperty }); } + QueryBuilder + isPhotochallengeEnabledProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'isPhotochallengeEnabled'); + }); + } + QueryBuilder isQrEnabledProperty() { return QueryBuilder.apply(this, (query) { return query.addPropertyName(r'isQrEnabled'); 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 8c71b92c..9443724b 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 @@ -5,6 +5,7 @@ import 'package:flutter_map/flutter_map.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:get/get.dart'; import 'package:fl_location/fl_location.dart'; +import 'package:image_picker/image_picker.dart'; import 'package:latlong2/latlong.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:path_provider/path_provider.dart'; @@ -62,6 +63,10 @@ class AddOrUpdateAlarmController extends GetxController { final qrValue = ''.obs; final isQrEnabled = false.obs; + //photochallenge + final imageurl = ''.obs; + final isPhotochallengeEnabled = false.obs; + final mathsSliderValue = 0.0.obs; final mathsDifficulty = Difficulty.Easy.obs; final isMathsEnabled = false.obs; @@ -79,7 +84,7 @@ class AddOrUpdateAlarmController extends GetxController { final RxInt snoozeDuration = 1.obs; var customRingtoneName = 'Default'.obs; var customRingtoneNames = [].obs; - var previousRingtone=''; + var previousRingtone = ''; final noteController = TextEditingController(); final RxString note = ''.obs; final deleteAfterGoesOff = false.obs; @@ -89,6 +94,7 @@ class AddOrUpdateAlarmController extends GetxController { final RxDouble selectedGradientDouble = 0.0.obs; final RxDouble volMin = 0.0.obs; final RxDouble volMax = 10.0.obs; + final picker = ImagePicker(); final RxInt hours = 0.obs, minutes = 0.obs, meridiemIndex = 0.obs; final List meridiem = ['AM'.obs, 'PM'.obs]; @@ -446,7 +452,6 @@ class AddOrUpdateAlarmController extends GetxController { showQRDialog(); } }, - confirm: TextButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(kprimaryColor), @@ -458,7 +463,6 @@ class AddOrUpdateAlarmController extends GetxController { ? kLightPrimaryTextColor : ksecondaryTextColor, ), - ), onPressed: () async { Get.back(); // Close the alert box @@ -506,6 +510,90 @@ class AddOrUpdateAlarmController extends GetxController { ); } + requestPhotoPermission(context) async { + PermissionStatus cameraStatus = await Permission.camera.status; + + if (!cameraStatus.isGranted) { + Get.defaultDialog( + backgroundColor: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + title: 'Camera Permission'.tr, + titleStyle: TextStyle( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : Colors.white, + ), + titlePadding: const EdgeInsets.only( + top: 25, + left: 10, + ), + contentPadding: const EdgeInsets.only(top: 20, left: 20, bottom: 23), + content: Text('Please allow camera access for capturing photo.'.tr), + onCancel: () { + Get.back(); // Close the alert box + }, + onConfirm: () async { + Get.back(); // Close the alert box + PermissionStatus permissionStatus = await Permission.camera.request(); + if (permissionStatus.isGranted) { + // Permission granted, proceed with QR code scanning + pickimage(); + } + }, + confirm: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(kprimaryColor), + ), + child: Text( + 'OK', + style: Theme.of(context).textTheme.displaySmall!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () async { + Get.back(); // Close the alert box + PermissionStatus permissionStatus = + await Permission.camera.request(); + if (permissionStatus.isGranted) { + // Permission granted, proceed with QR code scanning + pickimage(); + } + }, + ), + cancel: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5), + ), + ), + child: Text( + 'Cancel', + style: Theme.of(context).textTheme.displaySmall!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + ), + ), + onPressed: () { + Get.back(); // Close the alert box + }, + ), + ); + } else { + pickimage(); + } + } + + pickimage() async { + final pickedFile = await picker.pickImage(source: ImageSource.gallery); + final imagefile = File(pickedFile!.path); + } + updateAlarm(AlarmModel alarmData) async { // Adding the ID's so it can update depending on the db if (isSharedAlarmEnabled.value == true) { @@ -579,7 +667,7 @@ class AddOrUpdateAlarmController extends GetxController { ); hours.value = selectedTime.value.hour; minutes.value = selectedTime.value.minute; - + if (settingsController.is24HrsEnabled.value == false) { if (selectedTime.value.hour == 0) { hours.value = 12; @@ -798,6 +886,8 @@ class AddOrUpdateAlarmController extends GetxController { isSharedAlarmEnabled: isSharedAlarmEnabled.value, isQrEnabled: isQrEnabled.value, qrValue: qrValue.value, + isPhotochallengeEnabled: isPhotochallengeEnabled.value, + imageurl: imageurl.value, isMathsEnabled: isMathsEnabled.value, numMathsQuestions: numMathsQuestions.value, mathsDifficulty: mathsDifficulty.value.index, 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..f62c9630 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 @@ -224,6 +224,9 @@ class AddOrUpdateAlarmView extends GetView { controller.isSharedAlarmEnabled.value, isQrEnabled: controller.isQrEnabled.value, qrValue: controller.qrValue.value, + isPhotochallengeEnabled: + controller.isPhotochallengeEnabled.value, + imageurl: controller.imageurl.value, isMathsEnabled: controller.isMathsEnabled.value, numMathsQuestions: controller.numMathsQuestions.value, mathsDifficulty: diff --git a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/app/utils/utils.dart b/lib/app/utils/utils.dart index dea1e6c1..60bf170a 100644 --- a/lib/app/utils/utils.dart +++ b/lib/app/utils/utils.dart @@ -371,6 +371,8 @@ class Utils { mathsDifficulty: 0, qrValue: '', isQrEnabled: false, + imageurl: '', + isPhotochallengeEnabled: false, isShakeEnabled: false, shakeTimes: 0, isPedometerEnabled: false, diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 96159719..69bc572f 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include #include @@ -16,6 +17,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin"); audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar); + g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); + file_selector_plugin_register_with_registrar(file_selector_linux_registrar); g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 77f89fdb..c08964ad 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST audioplayers_linux + file_selector_linux flutter_secure_storage_linux flutter_volume_controller isar_flutter_libs diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 5028a563..e2dfa37b 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,7 +9,9 @@ import audio_session import audioplayers_darwin import cloud_firestore import device_info_plus +import file_selector_macos import firebase_core +import firebase_storage import flutter_secure_storage_macos import flutter_volume_controller import google_sign_in_ios @@ -23,7 +25,9 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) FlutterVolumeControllerPlugin.register(with: registry.registrar(forPlugin: "FlutterVolumeControllerPlugin")) FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 5ef61bee..4efe991b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: f5628cd9c92ed11083f425fd1f8f1bc60ecdda458c81d73b143aeda036c35fe7 + sha256: "737321f9be522620ed3794937298fb0027a48a402624fa2500f7532f94aea810" url: "https://pub.dev" source: hosted - version: "1.3.16" + version: "1.3.22" analyzer: dependency: transitive description: @@ -265,6 +265,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e + url: "https://pub.dev" + source: hosted + version: "0.3.3+8" crypto: dependency: transitive description: @@ -353,14 +361,46 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.1" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" + url: "https://pub.dev" + source: hosted + version: "0.9.2+1" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: b15c3da8bd4908b9918111fa486903f5808e388b8d1c559949f584725a6594d6 + url: "https://pub.dev" + source: hosted + version: "0.9.3+3" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.dev" + source: hosted + version: "2.6.2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0 + url: "https://pub.dev" + source: hosted + version: "0.9.3+1" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: "96607c0e829a581c2a483c658f04e8b159964c3bae2730f73297070bc85d40bb" + sha256: "7e049e32a9d347616edb39542cf92cd53fdb4a99fb6af0a0bff327c14cd76445" url: "https://pub.dev" source: hosted - version: "2.24.2" + version: "2.25.4" firebase_core_platform_interface: dependency: transitive description: @@ -373,10 +413,34 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: d585bdf3c656c3f7821ba1bd44da5f13365d22fcecaf5eb75c4295246aaa83c0 + sha256: "57e61d6010e253b36d38191cefd6199d7849152cdcd234b61ca290cdb278a0ba" + url: "https://pub.dev" + source: hosted + version: "2.11.4" + firebase_storage: + dependency: "direct main" + description: + name: firebase_storage + sha256: a07433d3ffe948f7a10086e4b0bd3a940be4ed873cffd24746eed1896b568369 + url: "https://pub.dev" + source: hosted + version: "11.6.6" + firebase_storage_platform_interface: + dependency: transitive + description: + name: firebase_storage_platform_interface + sha256: af99d9fcf058d6f3a591cea899cad054ded7adb21fb1788dfe65c3e223196b15 + url: "https://pub.dev" + source: hosted + version: "5.1.9" + firebase_storage_web: + dependency: transitive + description: + name: firebase_storage_web + sha256: "06a684016de9609928865798dece0f7d34782a15a76f5ac08bd3a8780035b0b2" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "3.7.0" fixnum: dependency: transitive description: @@ -680,6 +744,70 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.4" + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: "26222b01a0c9a2c8fe02fc90b8208bd3325da5ed1f4a2acabf75939031ac0bdd" + url: "https://pub.dev" + source: hosted + version: "1.0.7" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "39f2bfe497e495450c81abcd44b62f56c2a36a37a175da7d137b4454977b51b1" + url: "https://pub.dev" + source: hosted + version: "0.8.9+3" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: e2423c53a68b579a7c37a1eda967b8ae536c3d98518e5db95ca1fe5719a730a3 + url: "https://pub.dev" + source: hosted + version: "3.0.2" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: fadafce49e8569257a0cad56d24438a6fa1f0cbd7ee0af9b631f7492818a4ca3 + url: "https://pub.dev" + source: hosted + version: "0.8.9+1" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b + url: "https://pub.dev" + source: hosted + version: "2.9.3" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" infinite_listview: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b6d81f36..baa5991f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,8 @@ dependencies: uuid: ^4.3.3 pedometer: ^4.0.1 flutter_volume_controller: ^1.3.1 + image_picker: ^1.0.7 + firebase_storage: ^11.6.6 dev_dependencies: flutter_lints: ^2.0.3 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index ba8f0aa7..9f10abe9 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -8,7 +8,9 @@ #include #include +#include #include +#include #include #include #include @@ -20,8 +22,12 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); CloudFirestorePluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); FirebaseCorePluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); + FirebaseStoragePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseStoragePluginCApi")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); FlutterVolumeControllerPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 66c746d7..ecd34d1e 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -5,7 +5,9 @@ list(APPEND FLUTTER_PLUGIN_LIST audioplayers_windows cloud_firestore + file_selector_windows firebase_core + firebase_storage flutter_secure_storage_windows flutter_volume_controller isar_flutter_libs From cbd0a2dc044d37e17849f4b1844bf4667e0fc797 Mon Sep 17 00:00:00 2001 From: krish Date: Fri, 23 Feb 2024 03:00:52 +0530 Subject: [PATCH 02/14] added firebase storage --- .../add_or_update_alarm_controller.dart | 99 +++++++++++++++++-- .../views/add_or_update_alarm_view.dart | 10 ++ .../views/photo_challenge_tile.dart | 93 +++++++++++++++++ .../views/qr_bar_code_tile.dart | 1 + 4 files changed, 197 insertions(+), 6 deletions(-) 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 9443724b..0bc9dc67 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 @@ -1,10 +1,12 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; +import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:get/get.dart'; import 'package:fl_location/fl_location.dart'; +import 'package:get_storage/get_storage.dart'; import 'package:image_picker/image_picker.dart'; import 'package:latlong2/latlong.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; @@ -65,6 +67,7 @@ class AddOrUpdateAlarmController extends GetxController { //photochallenge final imageurl = ''.obs; + final imageFile = File('').obs; final isPhotochallengeEnabled = false.obs; final mathsSliderValue = 0.0.obs; @@ -538,7 +541,7 @@ class AddOrUpdateAlarmController extends GetxController { PermissionStatus permissionStatus = await Permission.camera.request(); if (permissionStatus.isGranted) { // Permission granted, proceed with QR code scanning - pickimage(); + showPhotoDialog(); } }, confirm: TextButton( @@ -559,7 +562,7 @@ class AddOrUpdateAlarmController extends GetxController { await Permission.camera.request(); if (permissionStatus.isGranted) { // Permission granted, proceed with QR code scanning - pickimage(); + showPhotoDialog(); } }, ), @@ -585,13 +588,97 @@ class AddOrUpdateAlarmController extends GetxController { ), ); } else { - pickimage(); + showPhotoDialog(); } } - pickimage() async { - final pickedFile = await picker.pickImage(source: ImageSource.gallery); - final imagefile = File(pickedFile!.path); + Future _uploadImageToStorage(File image) async { + final firebaseStorage = FirebaseStorage.instance; + Reference ref = firebaseStorage.ref().child(alarmID); + + UploadTask tsk = ref.putFile(image); + TaskSnapshot snap = await tsk; + Future dowloadurl = snap.ref.getDownloadURL(); + + return dowloadurl; + } + + showPhotoDialog() async { + if (isPhotochallengeEnabled.value == false) { + final pickedFile = + await ImagePicker().pickImage(source: ImageSource.camera); + if (pickedFile != null) { + imageFile.value = File(pickedFile.path); + imageurl.value = await _uploadImageToStorage(imageFile.value); + isPhotochallengeEnabled.value = true; + } else {} + } else { + Get.defaultDialog( + titlePadding: const EdgeInsets.symmetric(vertical: 20), + backgroundColor: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + title: 'Capture a Photo', + titleStyle: Theme.of(Get.context!).textTheme.displaySmall, + content: Obx( + () => Column( + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 15.0), + child: imageFile.value + .existsSync() // Check if file exists before trying to display + ? Image.file(imageFile.value, fit: BoxFit.cover) + : SizedBox.shrink(), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(kprimaryColor), + ), + child: Text( + 'Save', + style: Theme.of(Get.context!) + .textTheme + .displaySmall! + .copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () { + Get.back(); + }, + ), + TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(kprimaryColor), + ), + child: Text( + 'Retake', + style: Theme.of(Get.context!) + .textTheme + .displaySmall! + .copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () async { + showPhotoDialog(); + isPhotochallengeEnabled.value = false; + }, + ), + ], + ) + ], + ), + ), + ); + } } updateAlarm(AlarmModel alarmData) async { 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 f62c9630..c7c6928a 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 @@ -15,6 +15,7 @@ import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/location import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/maths_challenge_tile.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/note.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/pedometer_challenge_tile.dart'; +import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/quote_tile.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/repeat_once_tile.dart'; @@ -1048,6 +1049,15 @@ class AddOrUpdateAlarmView extends GetView { controller: controller, themeController: themeController, ), + Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + PhotoChallenge( + controller: controller, + themeController: themeController, + ), ], ), ), diff --git a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart index e69de29b..50dea6de 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart @@ -0,0 +1,93 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/controllers/add_or_update_alarm_controller.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'; + +class PhotoChallenge extends StatelessWidget { + const PhotoChallenge({ + super.key, + required this.controller, + required this.themeController, + }); + + final AddOrUpdateAlarmController controller; + final ThemeController themeController; + + @override + Widget build(BuildContext context) { + return ListTile( + title: Row( + children: [ + FittedBox( + alignment: Alignment.centerLeft, + fit: BoxFit.scaleDown, + child: Text( + 'Photo'.tr, + style: TextStyle( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + ), + ), + ), + IconButton( + icon: Icon( + Icons.info_sharp, + size: 21, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.45) + : kprimaryTextColor.withOpacity(0.3), + ), + onPressed: () { + Utils.showModal( + context: context, + title: 'Photo'.tr, + // description: + // 'Scan the QR/Bar code on any object, like a book, and relocate it to a different room. To deactivate the alarm, simply rescan the same QR/Bar code.', + description: 'qrDescription'.tr, + iconData: Icons.qr_code_scanner, + isLightMode: themeController.isLightMode.value, + ); + }, + ), + ], + ), + onTap: () async { + Utils.hapticFeedback(); + + await controller.requestPhotoPermission(context); + }, + trailing: InkWell( + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Obx( + () => Text( + controller.isPhotochallengeEnabled.value == true + ? 'Enabled'.tr + : 'Off'.tr, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: (controller.isPhotochallengeEnabled.value == false) + ? themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor + : themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + ), + ), + ), + Icon( + Icons.chevron_right, + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ], + ), + ), + ); + } +} diff --git a/lib/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart index f3c4147c..898e098e 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart @@ -56,6 +56,7 @@ class QrBarCode extends StatelessWidget { ), onTap: () async { Utils.hapticFeedback(); + await controller.requestQrPermission(context); }, trailing: InkWell( From b827e70caa46362d81320380911e54fa18c9aeb9 Mon Sep 17 00:00:00 2001 From: krish Date: Mon, 26 Feb 2024 12:35:51 +0530 Subject: [PATCH 03/14] added method to store file locally --- .../add_or_update_alarm_controller.dart | 60 +++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) 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 0bc9dc67..ddf36b81 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 @@ -591,9 +591,32 @@ class AddOrUpdateAlarmController extends GetxController { showPhotoDialog(); } } - +// Future saveToDocumentsDirectory({ +// required String filePath, +// }) async { +// try { +// Directory documentsDirectory = await getApplicationDocumentsDirectory(); +// String ringtonesDirectoryPath = '${documentsDirectory.path}/ringtones'; + +// // Create the ringtones directory if it doesn't exist +// Directory(ringtonesDirectoryPath).createSync(recursive: true); + +// // Copy the picked audio files to the ringtones directory +// File pickedFile = File(filePath); +// String newFilePath = +// '$ringtonesDirectoryPath/${pickedFile.uri.pathSegments.last}'; +// pickedFile.copySync(newFilePath); + +// return newFilePath; +// } catch (e) { +// debugPrint(e.toString()); +// return null; +// } +// } Future _uploadImageToStorage(File image) async { - final firebaseStorage = FirebaseStorage.instance; + /* + // Code for storing Photo in firestore + final firebaseStorage = FirebaseStorage.instance; Reference ref = firebaseStorage.ref().child(alarmID); UploadTask tsk = ref.putFile(image); @@ -601,6 +624,33 @@ class AddOrUpdateAlarmController extends GetxController { Future dowloadurl = snap.ref.getDownloadURL(); return dowloadurl; + + + */ + try { + Directory documentsDirectory = await getApplicationDocumentsDirectory(); + String photosDirectoryPath = '${documentsDirectory.path}/photos'; + + // Create the ringtones directory if it doesn't exist + Directory(photosDirectoryPath).createSync(recursive: true); + + // Copy the picked audio files to the ringtones directory + String filePath = image.path; + File pickedFile = File(filePath); + String newFilePath = + '$photosDirectoryPath/$alarmID/${pickedFile.uri.pathSegments.last}'; + + if (imageurl.value == '') { + pickedFile.copySync(newFilePath); + } else { + pickedFile.copySync(imageurl.value); + } + + return newFilePath; + } catch (e) { + debugPrint(e.toString()); + return ''; + } } showPhotoDialog() async { @@ -625,10 +675,10 @@ class AddOrUpdateAlarmController extends GetxController { children: [ Padding( padding: const EdgeInsets.only(bottom: 15.0), - child: imageFile.value - .existsSync() // Check if file exists before trying to display + child: imageFile.value.existsSync() + // Check if file exists before trying to display ? Image.file(imageFile.value, fit: BoxFit.cover) - : SizedBox.shrink(), + : const SizedBox.shrink(), ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, From 1eda08c307201296d0499a3b82b7b2ff6304ae19 Mon Sep 17 00:00:00 2001 From: krish Date: Tue, 27 Feb 2024 12:32:52 +0530 Subject: [PATCH 04/14] Photo sorting error solved --- .../add_or_update_alarm_controller.dart | 63 +++++++++---------- .../views/add_or_update_alarm_view.dart | 1 + .../views/photo_challenge_tile.dart | 2 +- .../home/controllers/home_controller.dart | 30 ++++----- 4 files changed, 43 insertions(+), 53 deletions(-) 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 ddf36b81..137fba95 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 @@ -1,12 +1,11 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; -import 'package:firebase_storage/firebase_storage.dart'; +// import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:get/get.dart'; import 'package:fl_location/fl_location.dart'; -import 'package:get_storage/get_storage.dart'; import 'package:image_picker/image_picker.dart'; import 'package:latlong2/latlong.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; @@ -134,7 +133,7 @@ class AddOrUpdateAlarmController extends GetxController { } void setGradient(int value) { - this.gradient.value = value; + gradient.value = value; } void setIsWeekdaysSelected(bool value) { @@ -591,28 +590,7 @@ class AddOrUpdateAlarmController extends GetxController { showPhotoDialog(); } } -// Future saveToDocumentsDirectory({ -// required String filePath, -// }) async { -// try { -// Directory documentsDirectory = await getApplicationDocumentsDirectory(); -// String ringtonesDirectoryPath = '${documentsDirectory.path}/ringtones'; - -// // Create the ringtones directory if it doesn't exist -// Directory(ringtonesDirectoryPath).createSync(recursive: true); - -// // Copy the picked audio files to the ringtones directory -// File pickedFile = File(filePath); -// String newFilePath = -// '$ringtonesDirectoryPath/${pickedFile.uri.pathSegments.last}'; -// pickedFile.copySync(newFilePath); - -// return newFilePath; -// } catch (e) { -// debugPrint(e.toString()); -// return null; -// } -// } + Future _uploadImageToStorage(File image) async { /* // Code for storing Photo in firestore @@ -637,16 +615,20 @@ class AddOrUpdateAlarmController extends GetxController { // Copy the picked audio files to the ringtones directory String filePath = image.path; File pickedFile = File(filePath); - String newFilePath = - '$photosDirectoryPath/$alarmID/${pickedFile.uri.pathSegments.last}'; + String newFilePath = '$photosDirectoryPath/$alarmID'; if (imageurl.value == '') { pickedFile.copySync(newFilePath); + debugPrint(newFilePath); + return newFilePath; } else { + // Assuming imageurl.value already contains the full path, + // so create directories + pickedFile.copySync(imageurl.value); + debugPrint(imageurl.value); + return imageurl.value; } - - return newFilePath; } catch (e) { debugPrint(e.toString()); return ''; @@ -677,8 +659,13 @@ class AddOrUpdateAlarmController extends GetxController { padding: const EdgeInsets.only(bottom: 15.0), child: imageFile.value.existsSync() // Check if file exists before trying to display - ? Image.file(imageFile.value, fit: BoxFit.cover) - : const SizedBox.shrink(), + ? Image.file( + imageFile.value, + fit: BoxFit.cover, + height: MediaQuery.of(Get.context!).size.height * 0.3, + width: MediaQuery.of(Get.context!).size.width, + ) + : const CircularProgressIndicator(), ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -723,7 +710,7 @@ class AddOrUpdateAlarmController extends GetxController { }, ), ], - ) + ), ], ), ), @@ -752,7 +739,9 @@ class AddOrUpdateAlarmController extends GetxController { } else { // Deleting alarm on firestore to ensure no duplicate entry await FirestoreDb.deleteAlarm( - userModel.value, alarmRecord!.firestoreId!); + userModel.value, + alarmRecord!.firestoreId!, + ); createAlarm(alarmData); } } @@ -775,7 +764,8 @@ class AddOrUpdateAlarmController extends GetxController { lastEditedUserId = userModel.value!.id; } - // listens to the userModel declared in homeController and updates on signup event + // listens to the userModel declared in homeController + //and updates on signup event homeController.userModel.stream.listen((UserModel? user) { userModel.value = user; if (user != null) { @@ -863,6 +853,11 @@ class AddOrUpdateAlarmController extends GetxController { isQrEnabled.value = alarmRecord!.isQrEnabled; qrValue.value = alarmRecord!.qrValue; + isPhotochallengeEnabled.value = alarmRecord!.isPhotochallengeEnabled; + imageurl.value = alarmRecord!.imageurl; + + imageFile.value = File(imageurl.value); + alarmID = alarmRecord!.alarmID; ownerId = alarmRecord!.ownerId; ownerName = alarmRecord!.ownerName; 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 c7c6928a..7ce74c27 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 @@ -1117,6 +1117,7 @@ class AddOrUpdateAlarmView extends GetView { : const SizedBox(), ), ), + AlarmOffset( controller: controller, themeController: themeController, diff --git a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart index 50dea6de..5e477b5a 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart @@ -24,7 +24,7 @@ class PhotoChallenge extends StatelessWidget { alignment: Alignment.centerLeft, fit: BoxFit.scaleDown, child: Text( - 'Photo'.tr, + 'Photo', style: TextStyle( color: themeController.isLightMode.value ? kLightPrimaryTextColor diff --git a/lib/app/modules/home/controllers/home_controller.dart b/lib/app/modules/home/controllers/home_controller.dart index 0e6213df..b123474f 100644 --- a/lib/app/modules/home/controllers/home_controller.dart +++ b/lib/app/modules/home/controllers/home_controller.dart @@ -567,7 +567,8 @@ class HomeController extends GetxController { content: Column( children: [ Text( - 'This action will permanently delete these alarms from your device.'.tr, + 'This action will permanently delete these alarms from your device.' + .tr, style: Theme.of(context).textTheme.bodyMedium, textAlign: TextAlign.center, ), @@ -583,17 +584,13 @@ class HomeController extends GetxController { Get.back(); }, style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(kprimaryColor), + backgroundColor: MaterialStateProperty.all(kprimaryColor), ), child: Text( 'Cancel'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: kprimaryBackgroundColor, - ), + style: Theme.of(context).textTheme.displaySmall!.copyWith( + color: kprimaryBackgroundColor, + ), ), ), OutlinedButton( @@ -613,7 +610,7 @@ class HomeController extends GetxController { Get.offNamedUntil( '/bottom-navigation-bar', - (route) => route.settings.name == '/splash-screen', + (route) => route.settings.name == '/splash-screen', ); }, style: OutlinedButton.styleFrom( @@ -626,14 +623,11 @@ class HomeController extends GetxController { ), child: Text( 'Okay'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController.isLightMode.value - ? Colors.red.withOpacity(0.9) - : Colors.red, - ), + style: Theme.of(context).textTheme.displaySmall!.copyWith( + color: themeController.isLightMode.value + ? Colors.red.withOpacity(0.9) + : Colors.red, + ), ), ), ], From e38b7ea81ea7dc416a990cce9cc2761797500556 Mon Sep 17 00:00:00 2001 From: krish Date: Tue, 27 Feb 2024 12:34:28 +0530 Subject: [PATCH 05/14] removed warning --- .../views/add_or_update_alarm_view.dart | 1836 ++++++++--------- 1 file changed, 902 insertions(+), 934 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 7ce74c27..ff9e9f50 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 @@ -44,426 +44,493 @@ class AddOrUpdateAlarmView extends GetView { var width = Get.width; var height = Get.height; return PopScope( - canPop: false, - onPopInvoked: (bool didPop) { - if (didPop) { - return; - } + canPop: false, + onPopInvoked: (bool didPop) { + 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, - ), - ), - ), - ], - ), + 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: Scaffold( - floatingActionButtonLocation: - FloatingActionButtonLocation.centerDocked, - floatingActionButton: (controller.alarmRecord != null && - controller.mutexLock.value == true) - ? const SizedBox() - : Padding( - padding: const EdgeInsets.all(18.0), - child: SizedBox( - height: height * 0.06, - width: width * 0.8, - child: TextButton( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton( + onPressed: () { + Get.back(); + }, style: ButtonStyle( backgroundColor: MaterialStateProperty.all(kprimaryColor), ), child: Text( - (controller.alarmRecord == null) - ? 'Save'.tr - : 'Update'.tr, + 'Cancel'.tr, style: Theme.of(context).textTheme.displaySmall!.copyWith( - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - : ksecondaryTextColor, + color: kprimaryBackgroundColor, ), ), - onPressed: () async { - Utils.hapticFeedback(); - if (controller.userModel.value != null) { - controller - .offsetDetails[controller.userModel.value!.id] = { - 'offsettedTime': Utils.timeOfDayToString( - TimeOfDay.fromDateTime( - Utils.calculateOffsetAlarmTime( - controller.selectedTime.value, - controller.isOffsetBefore.value, - controller.offsetDuration.value, + ), + 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, ), - ), - ), - 'offsetDuration': controller.offsetDuration.value, - 'isOffsetBefore': controller.isOffsetBefore.value, - }; - } else { - controller.offsetDetails.value = {}; - } - AlarmModel alarmRecord = AlarmModel( - deleteAfterGoesOff: - controller.deleteAfterGoesOff.value, - snoozeDuration: controller.snoozeDuration.value, - volMax: controller.volMax.value, - volMin: controller.volMin.value, - gradient: controller.gradient.value, - offsetDetails: controller.offsetDetails, - label: controller.label.value, - note: controller.note.value, - showMotivationalQuote: - controller.showMotivationalQuote.value, - isOneTime: controller.isOneTime.value, - lastEditedUserId: controller.lastEditedUserId, - mutexLock: controller.mutexLock.value, - alarmID: controller.alarmID, - ownerId: controller.ownerId, - ownerName: controller.ownerName, - activityInterval: - controller.activityInterval.value * 60000, - days: controller.repeatDays.toList(), - alarmTime: Utils.timeOfDayToString( - TimeOfDay.fromDateTime( - controller.selectedTime.value, - ), + ), + ), + ], + ), + ), + ], + ), + ); + }, + child: Scaffold( + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: (controller.alarmRecord != null && + controller.mutexLock.value == true) + ? const SizedBox() + : Padding( + padding: const EdgeInsets.all(18.0), + child: SizedBox( + height: height * 0.06, + width: width * 0.8, + child: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(kprimaryColor), + ), + child: Text( + (controller.alarmRecord == null) + ? 'Save'.tr + : 'Update'.tr, + style: Theme.of(context).textTheme.displaySmall!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, ), - mainAlarmTime: Utils.timeOfDayToString( + ), + onPressed: () async { + Utils.hapticFeedback(); + if (controller.userModel.value != null) { + controller + .offsetDetails[controller.userModel.value!.id] = { + 'offsettedTime': Utils.timeOfDayToString( TimeOfDay.fromDateTime( - controller.selectedTime.value, + Utils.calculateOffsetAlarmTime( + controller.selectedTime.value, + controller.isOffsetBefore.value, + controller.offsetDuration.value, + ), ), ), - intervalToAlarm: Utils.getMillisecondsToAlarm( - DateTime.now(), + 'offsetDuration': controller.offsetDuration.value, + 'isOffsetBefore': controller.isOffsetBefore.value, + }; + } else { + controller.offsetDetails.value = {}; + } + AlarmModel alarmRecord = AlarmModel( + deleteAfterGoesOff: controller.deleteAfterGoesOff.value, + snoozeDuration: controller.snoozeDuration.value, + volMax: controller.volMax.value, + volMin: controller.volMin.value, + gradient: controller.gradient.value, + offsetDetails: controller.offsetDetails, + label: controller.label.value, + note: controller.note.value, + showMotivationalQuote: + controller.showMotivationalQuote.value, + isOneTime: controller.isOneTime.value, + lastEditedUserId: controller.lastEditedUserId, + mutexLock: controller.mutexLock.value, + alarmID: controller.alarmID, + ownerId: controller.ownerId, + ownerName: controller.ownerName, + activityInterval: + controller.activityInterval.value * 60000, + days: controller.repeatDays.toList(), + alarmTime: Utils.timeOfDayToString( + TimeOfDay.fromDateTime( controller.selectedTime.value, ), - isActivityEnabled: controller.isActivityenabled.value, - minutesSinceMidnight: Utils.timeOfDayToInt( - TimeOfDay.fromDateTime( - controller.selectedTime.value, - ), + ), + mainAlarmTime: Utils.timeOfDayToString( + TimeOfDay.fromDateTime( + controller.selectedTime.value, ), - isLocationEnabled: controller.isLocationEnabled.value, - weatherTypes: Utils.getIntFromWeatherTypes( - controller.selectedWeather.toList(), + ), + intervalToAlarm: Utils.getMillisecondsToAlarm( + DateTime.now(), + controller.selectedTime.value, + ), + isActivityEnabled: controller.isActivityenabled.value, + minutesSinceMidnight: Utils.timeOfDayToInt( + TimeOfDay.fromDateTime( + controller.selectedTime.value, ), - isWeatherEnabled: controller.isWeatherEnabled.value, - location: Utils.geoPointToString( - Utils.latLngToGeoPoint( - controller.selectedPoint.value, - ), + ), + isLocationEnabled: controller.isLocationEnabled.value, + weatherTypes: Utils.getIntFromWeatherTypes( + controller.selectedWeather.toList(), + ), + isWeatherEnabled: controller.isWeatherEnabled.value, + location: Utils.geoPointToString( + Utils.latLngToGeoPoint( + controller.selectedPoint.value, ), - isSharedAlarmEnabled: - controller.isSharedAlarmEnabled.value, - isQrEnabled: controller.isQrEnabled.value, - qrValue: controller.qrValue.value, - isPhotochallengeEnabled: - controller.isPhotochallengeEnabled.value, - imageurl: controller.imageurl.value, - isMathsEnabled: controller.isMathsEnabled.value, - numMathsQuestions: controller.numMathsQuestions.value, - mathsDifficulty: - controller.mathsDifficulty.value.index, - isShakeEnabled: controller.isShakeEnabled.value, - shakeTimes: controller.shakeTimes.value, - isPedometerEnabled: - controller.isPedometerEnabled.value, - numberOfSteps: controller.numberOfSteps.value, - ringtoneName: controller.customRingtoneName.value, - isTimer: false, - ); + ), + isSharedAlarmEnabled: + controller.isSharedAlarmEnabled.value, + isQrEnabled: controller.isQrEnabled.value, + qrValue: controller.qrValue.value, + isPhotochallengeEnabled: + controller.isPhotochallengeEnabled.value, + imageurl: controller.imageurl.value, + isMathsEnabled: controller.isMathsEnabled.value, + numMathsQuestions: controller.numMathsQuestions.value, + mathsDifficulty: controller.mathsDifficulty.value.index, + isShakeEnabled: controller.isShakeEnabled.value, + shakeTimes: controller.shakeTimes.value, + isPedometerEnabled: controller.isPedometerEnabled.value, + numberOfSteps: controller.numberOfSteps.value, + ringtoneName: controller.customRingtoneName.value, + isTimer: false, + ); - // Adding offset details to the database if - // its a shared alarm - if (controller.isSharedAlarmEnabled.value) { - alarmRecord.offsetDetails = controller.offsetDetails; - alarmRecord.mainAlarmTime = Utils.timeOfDayToString( - TimeOfDay.fromDateTime( - controller.selectedTime.value, - ), - ); - } + // Adding offset details to the database if + // its a shared alarm + if (controller.isSharedAlarmEnabled.value) { + alarmRecord.offsetDetails = controller.offsetDetails; + alarmRecord.mainAlarmTime = Utils.timeOfDayToString( + TimeOfDay.fromDateTime( + controller.selectedTime.value, + ), + ); + } - try { - if (controller.alarmRecord == null) { - await controller.createAlarm(alarmRecord); - } else { - AlarmModel updatedAlarmModel = - controller.updatedAlarmModel(); - await controller.updateAlarm(updatedAlarmModel); - } - } catch (e) { - debugPrint(e.toString()); + try { + if (controller.alarmRecord == null) { + await controller.createAlarm(alarmRecord); + } else { + AlarmModel updatedAlarmModel = + controller.updatedAlarmModel(); + await controller.updateAlarm(updatedAlarmModel); } + } catch (e) { + debugPrint(e.toString()); + } - await controller.checkOverlayPermissionAndNavigate(); + await controller.checkOverlayPermissionAndNavigate(); + }, + ), + ), + ), + appBar: AppBar( + backgroundColor: (controller.alarmRecord != null && + controller.mutexLock.value == true) + ? themeController.isLightMode.value + ? kLightPrimaryBackgroundColor + : kprimaryBackgroundColor + : themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + elevation: 0.0, + centerTitle: true, + iconTheme: Theme.of(context).iconTheme, + title: (controller.alarmRecord != null && + controller.mutexLock.value == true) + ? const Text('') + : Obx( + () => Text( + 'Rings in @timeToAlarm'.trParams( + { + 'timeToAlarm': controller.timeToAlarm.value.toString(), }, ), + style: Theme.of(context).textTheme.titleSmall, ), ), - appBar: AppBar( - backgroundColor: (controller.alarmRecord != null && - controller.mutexLock.value == true) - ? themeController.isLightMode.value - ? kLightPrimaryBackgroundColor - : kprimaryBackgroundColor - : themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - elevation: 0.0, - centerTitle: true, - iconTheme: Theme.of(context).iconTheme, - title: (controller.alarmRecord != null && - controller.mutexLock.value == true) - ? const Text('') - : Obx( - () => Text( - 'Rings in @timeToAlarm'.trParams( - { - 'timeToAlarm': - controller.timeToAlarm.value.toString(), - }, + ), + body: (controller.alarmRecord != null && + controller.mutexLock.value == true) + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Padding( + padding: const EdgeInsets.all(20.0), + child: Text( + 'Uh-oh!'.tr, + style: + Theme.of(context).textTheme.displayMedium!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - style: Theme.of(context).textTheme.titleSmall, ), - ), - ), - body: (controller.alarmRecord != null && - controller.mutexLock.value == true) - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Padding( - padding: const EdgeInsets.all(20.0), - child: Text( - 'Uh-oh!'.tr, - style: Theme.of(context) - .textTheme - .displayMedium! - .copyWith( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - ), - SvgPicture.asset( - 'assets/images/locked.svg', - height: height * 0.24, - width: width * 0.5, + SvgPicture.asset( + 'assets/images/locked.svg', + height: height * 0.24, + width: width * 0.5, + ), + Padding( + padding: const EdgeInsets.all(20.0), + child: Text( + // 'This alarm is currently being edited!', + 'alarmEditing'.tr, + style: + Theme.of(context).textTheme.displaySmall!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - Padding( - padding: const EdgeInsets.all(20.0), - child: Text( - // 'This alarm is currently being edited!', - 'alarmEditing'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), + ), + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(kprimaryColor), ), - TextButton( - style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(kprimaryColor), - ), - child: Text( - 'Go back'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController.isLightMode.value - ? kLightSecondaryTextColor - : ksecondaryTextColor, - ), - ), - onPressed: () { - Utils.hapticFeedback(); - Get.back(); - }, + child: Text( + 'Go back'.tr, + style: + Theme.of(context).textTheme.displaySmall!.copyWith( + color: themeController.isLightMode.value + ? kLightSecondaryTextColor + : ksecondaryTextColor, + ), ), - ], - ), - ) - : ListView( - children: [ - Container( - 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(); + onPressed: () { + Utils.hapticFeedback(); + Get.back(); + }, + ), + ], + ), + ) + : ListView( + children: [ + Container( + 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 - .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) + .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: 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, ), + ), + ), + 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, ), ), ), - Padding( + ), + Visibility( + visible: settingsController + .is24HrsEnabled.value + ? false + : true, + child: Padding( padding: EdgeInsets.symmetric( horizontal: width * 0.02, ), @@ -481,13 +548,23 @@ class AddOrUpdateAlarmView extends GetView { ), ), ), - NumberPicker( + ), + Visibility( + visible: settingsController + .is24HrsEnabled.value + ? false + : true, + child: NumberPicker( minValue: 0, - maxValue: 59, - value: controller.minutes.value, + maxValue: 1, + value: controller.meridiemIndex.value, onChanged: (value) { Utils.hapticFeedback(); - controller.minutes.value = value; + value == 0 + ? controller + .meridiemIndex.value = 0 + : controller + .meridiemIndex.value = 1; controller.selectedTime.value = DateTime( controller @@ -495,8 +572,9 @@ class AddOrUpdateAlarmView extends GetView { controller .selectedTime.value.month, controller.selectedTime.value.day, - controller - .selectedTime.value.hour, + inputTimeController.convert24( + controller.hours.value, + ), controller.minutes.value, ); inputTimeController @@ -515,9 +593,12 @@ class AddOrUpdateAlarmView extends GetView { : 'PM', ); }, - infiniteLoop: true, + textMapper: (numberText) { + return controller + .meridiem[int.parse(numberText)] + .value; + }, itemWidth: width * 0.17, - zeroPad: true, selectedTextStyle: Theme.of(context) .textTheme .displayLarge! @@ -554,598 +635,485 @@ class AddOrUpdateAlarmView extends GetView { ), ), ), - 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, - ), - ), - ), + ), + ], + ), + ) + : Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 80, + child: TextField( + onChanged: (_) { + inputTimeController.setTime(); + }, + decoration: const InputDecoration( + hintText: 'HH', + border: InputBorder.none, ), - 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, - ), - ), + textAlign: TextAlign.center, + controller: inputTimeController + .inputHrsController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow( + RegExp( + '[1,2,3,4,5,6,7,8,9,0]', ), ), - ), - ], - ), - ) - : Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox( - width: 80, - child: TextField( - onChanged: (_) { - inputTimeController.setTime(); - }, - decoration: const InputDecoration( - hintText: 'HH', - border: InputBorder.none, + LengthLimitingTextInputFormatter(2), + LimitRange( + 0, + settingsController + .is24HrsEnabled.value + ? 23 + : 12, ), - textAlign: TextAlign.center, - controller: inputTimeController - .inputHrsController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.allow( - RegExp( - '[1,2,3,4,5,6,7,8,9,0]', - ), - ), - LengthLimitingTextInputFormatter(2), - LimitRange( - 0, - settingsController - .is24HrsEnabled.value - ? 23 - : 12, - ), - ], - ), + ], ), - SizedBox( - width: 16, - child: Text( - ':', - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .titleMedium, - ), + ), + SizedBox( + width: 16, + child: Text( + ':', + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .titleMedium, ), - SizedBox( - width: 80, - child: TextField( - onChanged: (_) { - inputTimeController.setTime(); - }, - decoration: const InputDecoration( - 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]', - ), - ), - LengthLimitingTextInputFormatter(2), - LimitRange(00, 59), - ], + ), + SizedBox( + width: 80, + child: TextField( + onChanged: (_) { + inputTimeController.setTime(); + }, + decoration: const InputDecoration( + 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]', + ), + ), + LengthLimitingTextInputFormatter(2), + LimitRange(00, 59), + ], ), - const SizedBox( - width: 16, - ), - Visibility( - visible: !settingsController - .is24HrsEnabled.value, - child: DropdownButton( - underline: Container(), - value: inputTimeController.isAM.value - ? 'AM' - : 'PM', - dropdownColor: - themeController.isLightMode.value - ? kLightPrimaryBackgroundColor - : kprimaryBackgroundColor, - items: - ['AM', 'PM'].map((String period) { - return DropdownMenuItem( - value: period, - child: Text(period), - ); - }).toList(), - onChanged: (getPeriod) { - inputTimeController - .changePeriod(getPeriod!); + ), + const SizedBox( + width: 16, + ), + Visibility( + visible: !settingsController + .is24HrsEnabled.value, + child: DropdownButton( + underline: Container(), + value: inputTimeController.isAM.value + ? 'AM' + : 'PM', + dropdownColor: + themeController.isLightMode.value + ? kLightPrimaryBackgroundColor + : kprimaryBackgroundColor, + items: + ['AM', 'PM'].map((String period) { + return DropdownMenuItem( + value: period, + child: Text(period), + ); + }).toList(), + onChanged: (getPeriod) { + inputTimeController + .changePeriod(getPeriod!); - inputTimeController.setTime(); - }, - ), - ), - const SizedBox( - width: 12, + inputTimeController.setTime(); + }, ), - Visibility( - visible: inputTimeController - .isTimePicker.isFalse, - child: InkWell( - onTap: () { - Utils.hapticFeedback(); - inputTimeController - .confirmTimeInput(); - }, - child: Container( - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(50.0), - border: Border.all( - color: kprimaryColor, - width: 1.0, - ), - ), - padding: EdgeInsets.all(5.0), - child: Icon( - Icons.done, + ), + const SizedBox( + width: 12, + ), + Visibility( + visible: inputTimeController + .isTimePicker.isFalse, + child: InkWell( + onTap: () { + Utils.hapticFeedback(); + inputTimeController + .confirmTimeInput(); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(50.0), + border: Border.all( color: kprimaryColor, + width: 1.0, ), ), + padding: const EdgeInsets.all(5.0), + child: const Icon( + Icons.done, + color: kprimaryColor, + ), ), ), - ], - ), - ); - }, - ), - ), - RepeatTile( - controller: controller, - themeController: themeController, + ), + ], + ), + ); + }, ), - Container( + ), + RepeatTile( + controller: controller, + themeController: themeController, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Divider( color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - Obx( - () => (!controller.repeatDays - .every((element) => element == false)) - ? RepeatOnceTile( - controller: controller, - themeController: themeController, - ) - : const SizedBox(), + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, ), - Obx( - () => (!controller.repeatDays - .every((element) => element == false)) - ? Container( + ), + Obx( + () => (!controller.repeatDays + .every((element) => element == false)) + ? RepeatOnceTile( + controller: controller, + themeController: themeController, + ) + : const SizedBox(), + ), + Obx( + () => (!controller.repeatDays + .every((element) => element == false)) + ? Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Divider( color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ) - : const SizedBox(), - ), - SnoozeDurationTile( - controller: controller, - themeController: themeController, - ), - Container( - color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - Obx( - () => (controller.repeatDays - .every((element) => element == false)) - ? DeleteAfterGoesOff( - controller: controller, - themeController: themeController, - ) - : const SizedBox(), - ), - LabelTile( - controller: controller, - themeController: themeController, - ), - Container( + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ) + : const SizedBox(), + ), + SnoozeDurationTile( + controller: controller, + themeController: themeController, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Divider( color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, ), - NoteTile( - controller: controller, - themeController: themeController, - ), - Container( + ), + Obx( + () => (controller.repeatDays + .every((element) => element == false)) + ? DeleteAfterGoesOff( + controller: controller, + themeController: themeController, + ) + : const SizedBox(), + ), + LabelTile( + controller: controller, + themeController: themeController, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Divider( color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, ), - ChooseRingtoneTile( - controller: controller, - themeController: themeController, - height: height, - width: width, - ), - Container( + ), + NoteTile( + controller: controller, + themeController: themeController, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Divider( color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - AscendingVolumeTile( - controller: controller, - themeController: themeController, + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, ), - Container( + ), + ChooseRingtoneTile( + controller: controller, + themeController: themeController, + height: height, + width: width, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Divider( color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - QuoteTile( - controller: controller, - themeController: themeController, + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, ), - Container( + ), + AscendingVolumeTile( + controller: controller, + themeController: themeController, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Divider( color: themeController.isLightMode.value - ? kLightPrimaryBackgroundColor - : ksecondaryTextColor, - height: 10, - width: width, + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, ), - Container( - color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Center( - child: Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Text( - 'Automatic Cancellation'.tr, - style: Theme.of(context) - .textTheme - .titleMedium! - .copyWith( - fontWeight: FontWeight.w500, - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - .withOpacity(0.85) - : kprimaryTextColor.withOpacity(0.85), - ), - ), + ), + QuoteTile( + controller: controller, + themeController: themeController, + ), + Container( + color: themeController.isLightMode.value + ? kLightPrimaryBackgroundColor + : ksecondaryTextColor, + height: 10, + width: width, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Text( + 'Automatic Cancellation'.tr, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + .withOpacity(0.85) + : kprimaryTextColor.withOpacity(0.85), + ), ), ), - ScreenActivityTile( - controller: controller, - themeController: themeController, - ), - Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - WeatherTile( - controller: controller, - themeController: themeController, - ), - Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - LocationTile( - controller: controller, - height: height, - width: width, - themeController: themeController, - ), - ], - ), - ), - Container( - color: themeController.isLightMode.value - ? kLightPrimaryBackgroundColor - : ksecondaryTextColor, - height: 10, - width: width, + ), + ScreenActivityTile( + controller: controller, + themeController: themeController, + ), + Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + WeatherTile( + controller: controller, + themeController: themeController, + ), + Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + LocationTile( + controller: controller, + height: height, + width: width, + themeController: themeController, + ), + ], ), - Container( - color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Center( - child: Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Text( - 'Challenges'.tr, - style: Theme.of( - context, - ).textTheme.titleMedium!.copyWith( - fontWeight: FontWeight.w500, - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - .withOpacity(0.85) - : kprimaryTextColor.withOpacity(0.85), - ), - ), + ), + Container( + color: themeController.isLightMode.value + ? kLightPrimaryBackgroundColor + : ksecondaryTextColor, + height: 10, + width: width, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Text( + 'Challenges'.tr, + style: Theme.of( + context, + ).textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.w500, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + .withOpacity(0.85) + : kprimaryTextColor.withOpacity(0.85), + ), ), ), - ShakeToDismiss( - controller: controller, - themeController: themeController, - ), - Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - QrBarCode( - controller: controller, - themeController: themeController, - ), - Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - MathsChallenge( - controller: controller, - themeController: themeController, - ), - Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - PedometerChallenge( - controller: controller, - themeController: themeController, - ), - Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - PhotoChallenge( - controller: controller, - themeController: themeController, - ), - ], - ), - ), - Container( - color: themeController.isLightMode.value - ? kLightPrimaryBackgroundColor - : ksecondaryTextColor, - height: 10, - width: width, + ), + ShakeToDismiss( + controller: controller, + themeController: themeController, + ), + Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + QrBarCode( + controller: controller, + themeController: themeController, + ), + Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + MathsChallenge( + controller: controller, + themeController: themeController, + ), + Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + PedometerChallenge( + controller: controller, + themeController: themeController, + ), + Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + PhotoChallenge( + controller: controller, + themeController: themeController, + ), + ], ), - Container( - color: themeController.isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Center( - child: Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Text( - 'Shared Alarm'.tr, - style: Theme.of( - context, - ).textTheme.titleMedium!.copyWith( - fontWeight: FontWeight.w500, - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - .withOpacity(0.85) - : kprimaryTextColor.withOpacity(0.85), - ), - ), - ), - ), - SharedAlarm( - controller: controller, - themeController: themeController, - ), - Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - AlarmIDTile( - controller: controller, - width: width, - themeController: themeController, - ), - Obx( - () => Container( - child: (controller.isSharedAlarmEnabled.value) - ? Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ) - : const SizedBox(), + ), + Container( + color: themeController.isLightMode.value + ? kLightPrimaryBackgroundColor + : ksecondaryTextColor, + height: 10, + width: width, + ), + Container( + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Text( + 'Shared Alarm'.tr, + style: Theme.of( + context, + ).textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.w500, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + .withOpacity(0.85) + : kprimaryTextColor.withOpacity(0.85), + ), ), ), - - AlarmOffset( - controller: controller, - themeController: themeController, - ), - Obx( - () => Container( - child: (controller.isSharedAlarmEnabled.value && - controller.alarmRecord != null) - ? Divider( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ) - : const SizedBox(), - ), + ), + SharedAlarm( + controller: controller, + themeController: themeController, + ), + Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + AlarmIDTile( + controller: controller, + width: width, + themeController: themeController, + ), + Obx( + () => Container( + child: (controller.isSharedAlarmEnabled.value) + ? Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ) + : const SizedBox(), ), - SharedUsers( - controller: controller, - themeController: themeController, + ), + AlarmOffset( + controller: controller, + themeController: themeController, + ), + Obx( + () => Container( + child: (controller.isSharedAlarmEnabled.value && + controller.alarmRecord != null) + ? Divider( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ) + : const SizedBox(), ), - ], - ), - ), - SizedBox( - height: height * 0.15, + ), + SharedUsers( + controller: controller, + themeController: themeController, + ), + ], ), - ], - ), - )); + ), + SizedBox( + height: height * 0.15, + ), + ], + ), + ), + ); } } From 2012943a5721f909ad6a117e86db113827cfd15a Mon Sep 17 00:00:00 2001 From: krish Date: Tue, 27 Feb 2024 12:42:16 +0530 Subject: [PATCH 06/14] added upload photo method --- .../modules/addOrUpdateAlarm/views/add_or_update_alarm_view.dart | 1 - 1 file changed, 1 deletion(-) 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 ff9e9f50..9800be28 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 @@ -28,7 +28,6 @@ import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/snooze_d import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/weather_tile.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/settings_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; -import 'package:ultimate_alarm_clock/app/routes/app_pages.dart'; import 'package:ultimate_alarm_clock/app/utils/constants.dart'; import 'package:ultimate_alarm_clock/app/utils/utils.dart'; import '../controllers/add_or_update_alarm_controller.dart'; From 85974f3e730bc651ccddf22ad2fbb51ead70eaa3 Mon Sep 17 00:00:00 2001 From: krish Date: Tue, 27 Feb 2024 13:34:26 +0530 Subject: [PATCH 07/14] added image caching --- .../home/controllers/home_controller.dart | 13 ++++++++++++ lib/app/modules/home/views/home_view.dart | 21 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/app/modules/home/controllers/home_controller.dart b/lib/app/modules/home/controllers/home_controller.dart index 108eb277..8e3f9c5a 100644 --- a/lib/app/modules/home/controllers/home_controller.dart +++ b/lib/app/modules/home/controllers/home_controller.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; import 'package:rxdart/rxdart.dart' as rx; @@ -33,6 +34,7 @@ class HomeController extends GetxController { List latestFirestoreAlarms = []; List latestIsarAlarms = []; List latestSharedAlarms = []; + Map deletedAlarmsMap = {}; final alarmTime = 'No upcoming alarms!'.obs; bool refreshTimer = false; bool isEmpty = true; @@ -408,6 +410,17 @@ class HomeController extends GetxController { } } + Future deleteFileIfExists(String filePath) async { + File file = File(filePath); + + if (await file.exists()) { + await file.delete(); + debugPrint('File deleted successfully.'); + } else { + debugPrint('File does not exist.'); + } + } + // Add all alarms to seleted alarm set void addAllAlarmsToSelectedAlarmSet() { for (int index = 0; index < alarmListPairs.first.length; index++) { diff --git a/lib/app/modules/home/views/home_view.dart b/lib/app/modules/home/views/home_view.dart index e0878d83..2b990764 100644 --- a/lib/app/modules/home/views/home_view.dart +++ b/lib/app/modules/home/views/home_view.dart @@ -1,9 +1,13 @@ // ignore_for_file: lines_longer_than_80_chars +import 'dart:ffi'; +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_expandable_fab/flutter_expandable_fab.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:ultimate_alarm_clock/app/data/models/alarm_model.dart'; import 'package:ultimate_alarm_clock/app/data/providers/firestore_provider.dart'; import 'package:ultimate_alarm_clock/app/data/providers/isar_provider.dart'; @@ -1271,6 +1275,20 @@ class HomeView extends GetView { if (alarm.isSharedAlarmEnabled == true) { await FirestoreDb.deleteAlarm(controller.userModel.value, alarm.firestoreId!); } else { + // Get the temporary directory + Directory tempDir = await getTemporaryDirectory(); + + // Generate a unique filename for the temporary copy + String tempFileName = '${DateTime.now().millisecondsSinceEpoch}.jpg'; + + // Create a temporary file path + String tempFilePath = '${tempDir.path}/$tempFileName'; + // Copy the content of the original file to the temporary file + await File(alarm.imageurl).copy(tempFilePath); + // Store the temporary file path in the map + String alarmid = alarm.alarmID; + controller.deletedAlarmsMap[alarmid] = tempFilePath; + await controller.deleteFileIfExists(alarm.imageurl); await IsarDb.deleteAlarm(alarm.isarId); } @@ -1292,6 +1310,9 @@ class HomeView extends GetView { if (alarm.isSharedAlarmEnabled == true) { await FirestoreDb.addAlarm(controller.userModel.value, alarm); } else { + await File(controller.deletedAlarmsMap[alarm.alarmID]!).copy(alarm.imageurl); + // Remove the alarm from the temporary storage + controller.deletedAlarmsMap.remove(alarm.alarmID); await IsarDb.addAlarm(alarm); } }, From 615bcdd0aac9200a5ebb0a436860c43e217acd29 Mon Sep 17 00:00:00 2001 From: krish Date: Fri, 1 Mar 2024 00:14:14 +0530 Subject: [PATCH 08/14] added photochallenge view and handle cache clearing onapp close --- .../add_or_update_alarm_controller.dart | 6 +- .../views/add_or_update_alarm_view.dart | 7 +- .../alarm_challenge_controller.dart | 43 ++- .../views/alarm_challenge_view.dart | 2 +- .../views/maths_challenge_view.dart | 20 +- .../views/pedometer_challenge_view.dart | 2 +- .../views/photo_challengeview.dart | 270 ++++++++++++++++++ .../views/qr_challenge_view.dart | 2 +- .../views/shake_challenge_view.dart | 2 +- .../home/controllers/home_controller.dart | 16 +- lib/app/modules/home/views/home_view.dart | 66 +++-- pubspec.lock | 14 +- pubspec.yaml | 2 + 13 files changed, 399 insertions(+), 53 deletions(-) create mode 100644 lib/app/modules/alarmChallenge/views/photo_challengeview.dart 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 ddb5c803..ef218009 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 @@ -637,11 +637,13 @@ class AddOrUpdateAlarmController extends GetxController { showPhotoDialog() async { if (isPhotochallengeEnabled.value == false) { - final pickedFile = - await ImagePicker().pickImage(source: ImageSource.camera); + final pickedFile = await picker.pickImage(source: ImageSource.camera); if (pickedFile != null) { imageFile.value = File(pickedFile.path); imageurl.value = await _uploadImageToStorage(imageFile.value); + //clearing image picker cache + await imageFile.value.delete(); + imageFile.value = File(imageurl.value); isPhotochallengeEnabled.value = true; } else {} } else { 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 9800be28..362c29b4 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 @@ -35,9 +35,10 @@ import '../controllers/add_or_update_alarm_controller.dart'; class AddOrUpdateAlarmView extends GetView { AddOrUpdateAlarmView({Key? key}) : super(key: key); - ThemeController themeController = Get.find(); - InputTimeController inputTimeController = Get.put(InputTimeController()); - SettingsController settingsController = Get.find(); + final ThemeController themeController = Get.find(); + final InputTimeController inputTimeController = + Get.put(InputTimeController()); + final SettingsController settingsController = Get.find(); @override Widget build(BuildContext context) { var width = Get.width; diff --git a/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart b/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart index ead36438..1aade294 100644 --- a/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart +++ b/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart @@ -1,7 +1,9 @@ import 'dart:async'; - +import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; +import 'package:image_compare_2/image_compare_2.dart'; +import 'package:image_picker/image_picker.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:pedometer/pedometer.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -24,6 +26,10 @@ class AlarmChallengeController extends GetxController { final qrValue = ''.obs; final isQrOngoing = Status.initialized.obs; + final imageurl = ''.obs; + final isPhotoChallengeOngoing = Status.initialized.obs; + final imagesimilarity = 0.0.obs; + final isMathsOngoing = Status.initialized.obs; final RxInt numMathsQuestions = 0.obs; @@ -86,6 +92,30 @@ class AlarmChallengeController extends GetxController { } } + Future compareImage(String imagePath1, String imagePath2) async { + // Read the images + + // Load images + final image1 = File(imagePath1); + final image2 = File(imagePath2); + + final chiSquaresimilarity = await compareImages( + src1: image1, + src2: image2, + algorithm: ChiSquareDistanceHistogram(), + ); + + final perceptualHashsimilarity = await compareImages( + src1: image1, + src2: image2, + algorithm: PerceptualHash(), + ); + + final result = perceptualHashsimilarity * 0.6 + chiSquaresimilarity * 0.4; + + return result; + } + @override void onInit() async { super.onInit(); @@ -137,6 +167,17 @@ class AlarmChallengeController extends GetxController { }); } + if (alarmRecord.isPhotochallengeEnabled) { + imagesimilarity.listen((url) async { + if (imagesimilarity.value > 0.7) { + isPhotoChallengeOngoing.value = Status.completed; + alarmRecord.isPhotochallengeEnabled = false; + Get.back(); + isChallengesComplete(); + } + }); + } + if (alarmRecord.isMathsEnabled) { newMathsQuestion(); diff --git a/lib/app/modules/alarmChallenge/views/alarm_challenge_view.dart b/lib/app/modules/alarmChallenge/views/alarm_challenge_view.dart index 106f6362..516a5652 100644 --- a/lib/app/modules/alarmChallenge/views/alarm_challenge_view.dart +++ b/lib/app/modules/alarmChallenge/views/alarm_challenge_view.dart @@ -13,7 +13,7 @@ import '../controllers/alarm_challenge_controller.dart'; class AlarmChallengeView extends GetView { AlarmChallengeView({Key? key}) : super(key: key); - ThemeController themeController = Get.find(); + final ThemeController themeController = Get.find(); @override Widget build(BuildContext context) { diff --git a/lib/app/modules/alarmChallenge/views/maths_challenge_view.dart b/lib/app/modules/alarmChallenge/views/maths_challenge_view.dart index bbf9ab06..e303c014 100644 --- a/lib/app/modules/alarmChallenge/views/maths_challenge_view.dart +++ b/lib/app/modules/alarmChallenge/views/maths_challenge_view.dart @@ -8,7 +8,7 @@ import 'package:ultimate_alarm_clock/app/utils/utils.dart'; class MathsChallengeView extends GetView { MathsChallengeView({Key? key}) : super(key: key); - ThemeController themeController = Get.find(); + final ThemeController themeController = Get.find(); @override Widget build(BuildContext context) { @@ -44,13 +44,19 @@ class MathsChallengeView extends GetView { ? Column( children: [ Padding( - padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 30.0), + padding: const EdgeInsets.fromLTRB( + 16.0, 16.0, 16.0, 30.0), child: Obx( - () => Text( - 'Question @noMathQ'.trParams({ - 'noMathQ' : controller.numMathsQuestions.value.toString(), - }), - style: Theme.of(context).textTheme.displayMedium?.copyWith( + () => Text( + 'Question @noMathQ'.trParams({ + 'noMathQ': controller + .numMathsQuestions.value + .toString(), + }), + style: Theme.of(context) + .textTheme + .displayMedium + ?.copyWith( letterSpacing: 1.5, ), ), diff --git a/lib/app/modules/alarmChallenge/views/pedometer_challenge_view.dart b/lib/app/modules/alarmChallenge/views/pedometer_challenge_view.dart index 7a5c35ef..e4678ce7 100644 --- a/lib/app/modules/alarmChallenge/views/pedometer_challenge_view.dart +++ b/lib/app/modules/alarmChallenge/views/pedometer_challenge_view.dart @@ -8,7 +8,7 @@ import 'package:ultimate_alarm_clock/app/utils/utils.dart'; class PedometerChallengeView extends GetView { PedometerChallengeView({Key? key}) : super(key: key); - ThemeController themeController = Get.find(); + final ThemeController themeController = Get.find(); @override Widget build(BuildContext context) { diff --git a/lib/app/modules/alarmChallenge/views/photo_challengeview.dart b/lib/app/modules/alarmChallenge/views/photo_challengeview.dart new file mode 100644 index 00000000..c8ec3705 --- /dev/null +++ b/lib/app/modules/alarmChallenge/views/photo_challengeview.dart @@ -0,0 +1,270 @@ +// ignore_for_file: lines_longer_than_80_chars + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:permission_handler/permission_handler.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 '../controllers/alarm_challenge_controller.dart'; + +class PhotoChallengeView extends GetView { + PhotoChallengeView({Key? key}) : super(key: key); + + final ThemeController themeController = Get.find(); + + @override + Widget build(BuildContext context) { + // ignore: unused_local_variable + var width = Get.width; + var height = Get.height; + + return Scaffold( + appBar: AppBar( + centerTitle: true, + iconTheme: Theme.of(context).iconTheme, + ), + body: GestureDetector( + onTap: () { + Utils.hapticFeedback(); + controller.restartTimer(); + }, + child: Column( + children: [ + Obx( + () => LinearProgressIndicator( + minHeight: 2, + value: controller.progress.value, + backgroundColor: Colors.grey, + valueColor: const AlwaysStoppedAnimation(kprimaryColor), + ), + ), + Expanded( + child: Center( + child: SingleChildScrollView( + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 25.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Match the Photo'.tr, + style: Theme.of(context) + .textTheme + .displayMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.7) + : kprimaryTextColor.withOpacity(0.7), + ), + ), + SizedBox( + height: height * 0.08, + ), + Obx( + () => Column( + children: [ + (controller.isPhotoChallengeOngoing.value == + Status.initialized) + ? Column( + children: [ + Padding( + padding: const EdgeInsets.only( + bottom: 15.0, + ), + child: File( + controller.alarmRecord.imageurl, + ).existsSync() + // Check if file exists before trying to display + ? Image.file( + File( + controller + .alarmRecord.imageurl, + ), + fit: BoxFit.cover, + height: MediaQuery.of( + Get.context!, + ).size.height * + 0.3, + width: MediaQuery.of( + Get.context!, + ).size.width, + ) + : const CircularProgressIndicator(), + ), + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all( + kprimaryColor, + ), + ), + child: Text( + 'Take Photo', + style: Theme.of(Get.context!) + .textTheme + .displaySmall! + .copyWith( + color: themeController + .isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () async { + PermissionStatus cameraStatus = + await Permission + .camera.status; + if (cameraStatus.isGranted) { + final pickedFile = + await ImagePicker() + .pickImage( + source: ImageSource.camera, + ); + if (pickedFile != null) { + final imageFile = + File(pickedFile.path); + controller.imageurl.value = + imageFile.path; + + await controller.compareImage( + controller.imageurl.value, + controller + .alarmRecord.imageurl, + ); + + if (controller.imagesimilarity + .value > + 0.7) { + controller + .isPhotoChallengeOngoing + .value = Status.completed; + } else { + controller + .isPhotoChallengeOngoing + .value = Status.ongoing; + } + + await imageFile.delete(); + } else {} + // Process the image as needed + } else {} + }, + ), + ], + ) + : SizedBox( + height: 300, + width: 300, + child: Center( + child: (controller + .imagesimilarity.value > + 0.7) + ? Icon( + Icons.done, + size: height * 0.2, + color: themeController + .isLightMode.value + ? kLightPrimaryTextColor + .withOpacity(0.7) + : kprimaryTextColor + .withOpacity(0.7), + ) + : Column( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Icon( + Icons.close, + size: height * 0.2, + color: themeController + .isLightMode.value + ? kLightPrimaryTextColor + .withOpacity(0.7) + : kprimaryTextColor + .withOpacity( + 0.7, + ), + ), + Text( + 'Wrong Photo Captured'.tr, + style: Theme.of( + context, + ) + .textTheme + .bodyMedium! + .copyWith( + fontWeight: + FontWeight.w500, + color: themeController + .isLightMode + .value + ? kLightPrimaryTextColor + .withOpacity( + 0.7, + ) + : kprimaryTextColor + .withOpacity( + 0.7, + ), + ), + ), + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty + .all( + kprimaryColor, + ), + ), + child: Text( + 'Retake'.tr, + style: Theme.of( + context, + ) + .textTheme + .displaySmall! + .copyWith( + color: themeController + .isLightMode + .value + ? kLightSecondaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () async { + Utils.hapticFeedback(); + + controller + .isPhotoChallengeOngoing + .value = + Status.initialized; + }, + ), + ], + ), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/app/modules/alarmChallenge/views/qr_challenge_view.dart b/lib/app/modules/alarmChallenge/views/qr_challenge_view.dart index fd73a452..98cdb5d5 100644 --- a/lib/app/modules/alarmChallenge/views/qr_challenge_view.dart +++ b/lib/app/modules/alarmChallenge/views/qr_challenge_view.dart @@ -12,7 +12,7 @@ import '../controllers/alarm_challenge_controller.dart'; class QRChallengeView extends GetView { QRChallengeView({Key? key}) : super(key: key); - ThemeController themeController = Get.find(); + final ThemeController themeController = Get.find(); @override Widget build(BuildContext context) { diff --git a/lib/app/modules/alarmChallenge/views/shake_challenge_view.dart b/lib/app/modules/alarmChallenge/views/shake_challenge_view.dart index d4f6778d..0dcc3cf3 100644 --- a/lib/app/modules/alarmChallenge/views/shake_challenge_view.dart +++ b/lib/app/modules/alarmChallenge/views/shake_challenge_view.dart @@ -10,7 +10,7 @@ import '../controllers/alarm_challenge_controller.dart'; class ShakeChallengeView extends GetView { ShakeChallengeView({Key? key}) : super(key: key); - ThemeController themeController = Get.find(); + final ThemeController themeController = Get.find(); @override Widget build(BuildContext context) { diff --git a/lib/app/modules/home/controllers/home_controller.dart b/lib/app/modules/home/controllers/home_controller.dart index 8e3f9c5a..aaa1ef2b 100644 --- a/lib/app/modules/home/controllers/home_controller.dart +++ b/lib/app/modules/home/controllers/home_controller.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:rxdart/rxdart.dart' as rx; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; @@ -393,21 +394,26 @@ class HomeController extends GetxController { try { await alarmChannel .invokeMethod('scheduleAlarm', {'milliSeconds': intervaltoAlarm}); - print("Scheduled..."); + debugPrint('Scheduled...'); } on PlatformException catch (e) { - print("Failed to schedule alarm: ${e.message}"); + debugPrint('Failed to schedule alarm: ${e.message}'); } } } } @override - void onClose() { - super.onClose(); - + void onClose() async { + //Deleting file cache stored in temporary directory + for (var filepath in deletedAlarmsMap.values) { + await deleteFileIfExists(filepath); + } + deletedAlarmsMap.clear(); if (delayToSchedule != null) { delayToSchedule!.cancel(); } + + super.onClose(); } Future deleteFileIfExists(String filePath) async { diff --git a/lib/app/modules/home/views/home_view.dart b/lib/app/modules/home/views/home_view.dart index 2b990764..d8b83cd6 100644 --- a/lib/app/modules/home/views/home_view.dart +++ b/lib/app/modules/home/views/home_view.dart @@ -1,6 +1,6 @@ // ignore_for_file: lines_longer_than_80_chars -import 'dart:ffi'; +// import 'dart:ffi'; import 'dart:io'; import 'package:flutter/material.dart'; @@ -14,7 +14,7 @@ import 'package:ultimate_alarm_clock/app/data/providers/isar_provider.dart'; import 'package:ultimate_alarm_clock/app/modules/home/views/toggle_button.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/settings_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; -import 'package:ultimate_alarm_clock/app/routes/app_pages.dart'; +// import 'package:ultimate_alarm_clock/app/routes/app_pages.dart'; import 'package:ultimate_alarm_clock/app/utils/audio_utils.dart'; import 'package:ultimate_alarm_clock/app/utils/constants.dart'; import 'package:ultimate_alarm_clock/app/utils/end_drawer.dart'; @@ -287,8 +287,8 @@ class HomeView extends GetView { : ExpandableFab( initialOpen: false, key: controller.floatingButtonKeyLoggedOut, - child: Icon(Icons.add), - children: [], + child: const Icon(Icons.add), + children: const [], onOpen: () { controller.floatingButtonKeyLoggedOut.currentState! .toggle(); @@ -585,7 +585,7 @@ class HomeView extends GetView { ), ); }), - Spacer(), + const Spacer(), Row( children: [ // All alarm select button @@ -641,10 +641,12 @@ class HomeView extends GetView { .value ? kLightPrimaryTextColor .withOpacity( - 0.75) + 0.75, + ) : kprimaryTextColor .withOpacity( - 0.75), + 0.75, + ), iconSize: 27 * controller .scalingFactor @@ -655,7 +657,7 @@ class HomeView extends GetView { ), ], ), - ) + ), ], ), ), @@ -762,17 +764,19 @@ class HomeView extends GetView { direction: DismissDirection.startToEnd, onDismissed: (direction) async { await controller.swipeToDeleteAlarm( - controller.userModel.value, - alarm); + controller.userModel.value, + alarm, + ); }, key: ValueKey(alarms[index]), background: Container( color: Colors .red, // Set the background color to red - padding: EdgeInsets.symmetric( - horizontal: 20), + padding: const EdgeInsets.symmetric( + horizontal: 20, + ), alignment: Alignment.center, - child: Icon( + child: const Icon( Icons.delete, color: Colors.white, ), @@ -1275,20 +1279,24 @@ class HomeView extends GetView { if (alarm.isSharedAlarmEnabled == true) { await FirestoreDb.deleteAlarm(controller.userModel.value, alarm.firestoreId!); } else { - // Get the temporary directory - Directory tempDir = await getTemporaryDirectory(); + if (await File(alarm.imageurl).exists()) { + // Get the temporary directory + + Directory tempDir = await getTemporaryDirectory(); + + // Generate a unique filename for the temporary copy + String tempFileName = '${DateTime.now().millisecondsSinceEpoch}.jpg'; - // Generate a unique filename for the temporary copy - String tempFileName = '${DateTime.now().millisecondsSinceEpoch}.jpg'; + // Create a temporary file path + String tempFilePath = '${tempDir.path}/$tempFileName'; + // Copy the content of the original file to the temporary file + await File(alarm.imageurl).copy(tempFilePath); + // Store the temporary file path in the map + String alarmid = alarm.alarmID; + controller.deletedAlarmsMap[alarmid] = tempFilePath; + await controller.deleteFileIfExists(alarm.imageurl); + } - // Create a temporary file path - String tempFilePath = '${tempDir.path}/$tempFileName'; - // Copy the content of the original file to the temporary file - await File(alarm.imageurl).copy(tempFilePath); - // Store the temporary file path in the map - String alarmid = alarm.alarmID; - controller.deletedAlarmsMap[alarmid] = tempFilePath; - await controller.deleteFileIfExists(alarm.imageurl); await IsarDb.deleteAlarm(alarm.isarId); } @@ -1310,9 +1318,11 @@ class HomeView extends GetView { if (alarm.isSharedAlarmEnabled == true) { await FirestoreDb.addAlarm(controller.userModel.value, alarm); } else { - await File(controller.deletedAlarmsMap[alarm.alarmID]!).copy(alarm.imageurl); - // Remove the alarm from the temporary storage - controller.deletedAlarmsMap.remove(alarm.alarmID); + if (controller.deletedAlarmsMap[alarm.alarmID] != null && await File(controller.deletedAlarmsMap[alarm.alarmID]!).exists()) { + await File(controller.deletedAlarmsMap[alarm.alarmID]!).copy(alarm.imageurl); + // Remove the alarm from the temporary storage + controller.deletedAlarmsMap.remove(alarm.alarmID); + } await IsarDb.addAlarm(alarm); } }, diff --git a/pubspec.lock b/pubspec.lock index 4efe991b..cbd772ce 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -737,13 +737,21 @@ packages: source: hosted version: "4.0.2" image: - dependency: transitive + dependency: "direct main" description: name: image - sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d" + sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e" + url: "https://pub.dev" + source: hosted + version: "4.1.7" + image_compare_2: + dependency: "direct main" + description: + name: image_compare_2 + sha256: "50ff6f6a793f61fc5b19e9ad7bf1bb9507e57b73ec689332eed11c1473954807" url: "https://pub.dev" source: hosted - version: "4.1.4" + version: "1.1.7" image_picker: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index baa5991f..cf7d8a9a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,6 +17,8 @@ dependencies: intl: ^0.18.0 latlong2: ^0.8.1 flutter_map: ^4.0.0 + image: ^4.1.7 + image_compare_2: ^1.1.7 fl_location: ^2.0.0+1 flutter_fgbg: ^0.3.0 flutter_svg: ^2.0.4 From e9e96eea35c4acd4ae7aaf0887454635975ed586 Mon Sep 17 00:00:00 2001 From: krish Date: Mon, 18 Mar 2024 19:58:28 +0530 Subject: [PATCH 09/14] completed Logic of photo challlenge --- .../add_or_update_alarm_controller.dart | 42 ++++++----- .../alarm_challenge_controller.dart | 18 ++--- .../views/alarm_challenge_view.dart | 69 +++++++++++++++++++ .../views/maths_challenge_view.dart | 1 + .../views/photo_challengeview.dart | 31 +++++---- .../alarmRing/views/alarm_ring_view.dart | 18 ++--- lib/app/utils/utils.dart | 4 +- 7 files changed, 132 insertions(+), 51 deletions(-) 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 ef218009..996b72f4 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 @@ -639,10 +639,11 @@ class AddOrUpdateAlarmController extends GetxController { if (isPhotochallengeEnabled.value == false) { final pickedFile = await picker.pickImage(source: ImageSource.camera); if (pickedFile != null) { - imageFile.value = File(pickedFile.path); - imageurl.value = await _uploadImageToStorage(imageFile.value); - //clearing image picker cache - await imageFile.value.delete(); + File imagepickedfile = File(pickedFile.path); + imageurl.value = await _uploadImageToStorage(imagepickedfile); + + //clear image chache + await imagepickedfile.delete(); imageFile.value = File(imageurl.value); isPhotochallengeEnabled.value = true; } else {} @@ -658,17 +659,13 @@ class AddOrUpdateAlarmController extends GetxController { () => Column( children: [ Padding( - padding: const EdgeInsets.only(bottom: 15.0), - child: imageFile.value.existsSync() - // Check if file exists before trying to display - ? Image.file( - imageFile.value, - fit: BoxFit.cover, - height: MediaQuery.of(Get.context!).size.height * 0.3, - width: MediaQuery.of(Get.context!).size.width, - ) - : const CircularProgressIndicator(), - ), + padding: const EdgeInsets.only(bottom: 15.0), + child: Image.file( + File(imageurl.value), + fit: BoxFit.cover, + height: MediaQuery.of(Get.context!).size.height * 0.3, + width: MediaQuery.of(Get.context!).size.width, + )), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -707,8 +704,19 @@ class AddOrUpdateAlarmController extends GetxController { ), ), onPressed: () async { - showPhotoDialog(); - isPhotochallengeEnabled.value = false; + // showPhotoDialog(); + final pickedFile = + await picker.pickImage(source: ImageSource.camera); + if (pickedFile != null) { + File imagepickedfile = File(pickedFile.path); + + imageurl.value = + await _uploadImageToStorage(imagepickedfile); + + //clear image chache + await imagepickedfile.delete(); + isPhotochallengeEnabled.value = true; + } else {} }, ), ], diff --git a/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart b/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart index 1aade294..cad0f28b 100644 --- a/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart +++ b/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart @@ -99,20 +99,14 @@ class AlarmChallengeController extends GetxController { final image1 = File(imagePath1); final image2 = File(imagePath2); - final chiSquaresimilarity = await compareImages( + final similarity = await compareImages( src1: image1, src2: image2, - algorithm: ChiSquareDistanceHistogram(), + algorithm: IntersectionHistogram(), ); - final perceptualHashsimilarity = await compareImages( - src1: image1, - src2: image2, - algorithm: PerceptualHash(), - ); - - final result = perceptualHashsimilarity * 0.6 + chiSquaresimilarity * 0.4; - + final result = similarity; + Get.log('${result}'); return result; } @@ -168,8 +162,8 @@ class AlarmChallengeController extends GetxController { } if (alarmRecord.isPhotochallengeEnabled) { - imagesimilarity.listen((url) async { - if (imagesimilarity.value > 0.7) { + imagesimilarity.listen((value) async { + if (value <= 0.36) { isPhotoChallengeOngoing.value = Status.completed; alarmRecord.isPhotochallengeEnabled = false; Get.back(); diff --git a/lib/app/modules/alarmChallenge/views/alarm_challenge_view.dart b/lib/app/modules/alarmChallenge/views/alarm_challenge_view.dart index 516a5652..b6ad4e7d 100644 --- a/lib/app/modules/alarmChallenge/views/alarm_challenge_view.dart +++ b/lib/app/modules/alarmChallenge/views/alarm_challenge_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:ultimate_alarm_clock/app/modules/alarmChallenge/views/maths_challenge_view.dart'; import 'package:ultimate_alarm_clock/app/modules/alarmChallenge/views/pedometer_challenge_view.dart'; +import 'package:ultimate_alarm_clock/app/modules/alarmChallenge/views/photo_challengeview.dart'; import 'package:ultimate_alarm_clock/app/modules/alarmChallenge/views/qr_challenge_view.dart'; import 'package:ultimate_alarm_clock/app/modules/alarmChallenge/views/shake_challenge_view.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; @@ -325,6 +326,74 @@ class AlarmChallengeView extends GetView { height: 20, width: 0, ), + if (controller.alarmRecord.isPhotochallengeEnabled) + InkWell( + onTap: () { + Utils.hapticFeedback(); + if (controller.isPhotoChallengeOngoing.value != + Status.completed && + controller + .alarmRecord.isPhotochallengeEnabled) { + Get.to(() => PhotoChallengeView()); + } + }, + child: Container( + width: width * 0.91, + height: height * 0.1, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all( + Radius.circular(18), + ), + color: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + Icon( + Icons.qr_code_scanner, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + .withOpacity(0.8) + : kprimaryTextColor.withOpacity(0.8), + size: 28, + ), + Text( + 'Photo Challenge', + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith( + color: themeController + .isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + ), + ), + Obx( + () => Icon( + controller.isPhotoChallengeOngoing + .value == + Status.completed + ? Icons.done + : Icons.arrow_forward_ios_sharp, + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + .withOpacity(0.4) + : kprimaryTextColor + .withOpacity(0.2), + ), + ), + ], + ), + ), + ), + const SizedBox( + height: 20, + width: 0, + ), ], ), ), diff --git a/lib/app/modules/alarmChallenge/views/maths_challenge_view.dart b/lib/app/modules/alarmChallenge/views/maths_challenge_view.dart index e303c014..6b6cb858 100644 --- a/lib/app/modules/alarmChallenge/views/maths_challenge_view.dart +++ b/lib/app/modules/alarmChallenge/views/maths_challenge_view.dart @@ -209,6 +209,7 @@ class MathsChallengeView extends GetView { return ElevatedButton( onPressed: () { Utils.hapticFeedback(); + if (controller.mathsAnswer.toString() == controller.displayValue.value) { controller.numMathsQuestions.value -= 1; diff --git a/lib/app/modules/alarmChallenge/views/photo_challengeview.dart b/lib/app/modules/alarmChallenge/views/photo_challengeview.dart index c8ec3705..5fba4612 100644 --- a/lib/app/modules/alarmChallenge/views/photo_challengeview.dart +++ b/lib/app/modules/alarmChallenge/views/photo_challengeview.dart @@ -53,7 +53,7 @@ class PhotoChallengeView extends GetView { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - 'Match the Photo'.tr, + 'Match the Photo', style: Theme.of(context) .textTheme .displayMedium! @@ -93,8 +93,9 @@ class PhotoChallengeView extends GetView { ).size.height * 0.3, width: MediaQuery.of( - Get.context!, - ).size.width, + Get.context!, + ).size.width * + 0.81, ) : const CircularProgressIndicator(), ), @@ -133,15 +134,19 @@ class PhotoChallengeView extends GetView { controller.imageurl.value = imageFile.path; - await controller.compareImage( - controller.imageurl.value, + controller.imagesimilarity + .value = + await controller + .compareImage( controller .alarmRecord.imageurl, + controller.imageurl.value, ); - + Get.log( + '${controller.imagesimilarity.value}'); if (controller.imagesimilarity - .value > - 0.7) { + .value <= + 0.36) { controller .isPhotoChallengeOngoing .value = Status.completed; @@ -151,7 +156,7 @@ class PhotoChallengeView extends GetView { .value = Status.ongoing; } - await imageFile.delete(); + // await imageFile.delete(); } else {} // Process the image as needed } else {} @@ -164,8 +169,8 @@ class PhotoChallengeView extends GetView { width: 300, child: Center( child: (controller - .imagesimilarity.value > - 0.7) + .imagesimilarity.value <= + 0.36) ? Icon( Icons.done, size: height * 0.2, @@ -194,7 +199,7 @@ class PhotoChallengeView extends GetView { ), ), Text( - 'Wrong Photo Captured'.tr, + 'Wrong Photo Captured', style: Theme.of( context, ) @@ -225,7 +230,7 @@ class PhotoChallengeView extends GetView { ), ), child: Text( - 'Retake'.tr, + 'Retake', style: Theme.of( context, ) diff --git a/lib/app/modules/alarmRing/views/alarm_ring_view.dart b/lib/app/modules/alarmRing/views/alarm_ring_view.dart index d547cf6d..2515111a 100644 --- a/lib/app/modules/alarmRing/views/alarm_ring_view.dart +++ b/lib/app/modules/alarmRing/views/alarm_ring_view.dart @@ -10,7 +10,7 @@ import '../controllers/alarm_ring_controller.dart'; class AlarmControlView extends GetView { AlarmControlView({Key? key}) : super(key: key); - ThemeController themeController = Get.find(); + final ThemeController themeController = Get.find(); @override Widget build(BuildContext context) { @@ -193,13 +193,15 @@ class AlarmControlView extends GetView { ), child: Text( 'Snooze'.tr, - style: - Theme.of(context).textTheme.bodyMedium!.copyWith( - color: themeController.isLightMode.value - ? kLightPrimaryTextColor - : kprimaryTextColor, - fontWeight: FontWeight.w600, - ), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + fontWeight: FontWeight.w600, + ), ), onPressed: () { Utils.hapticFeedback(); diff --git a/lib/app/utils/utils.dart b/lib/app/utils/utils.dart index 60bf170a..41b0fdc8 100644 --- a/lib/app/utils/utils.dart +++ b/lib/app/utils/utils.dart @@ -511,9 +511,11 @@ class Utils { if (alarmRecord.isMathsEnabled || alarmRecord.isQrEnabled || alarmRecord.isShakeEnabled || - alarmRecord.isPedometerEnabled) { + alarmRecord.isPedometerEnabled || + alarmRecord.isPhotochallengeEnabled) { return true; } + return false; } From 642b186ee363c0c709a14df0d4160f1c56710e8f Mon Sep 17 00:00:00 2001 From: krish Date: Wed, 20 Mar 2024 19:21:49 +0530 Subject: [PATCH 10/14] resolved merge conflict --- .../views/customize_undo_duration.dart | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 lib/app/modules/settings/views/customize_undo_duration.dart diff --git a/lib/app/modules/settings/views/customize_undo_duration.dart b/lib/app/modules/settings/views/customize_undo_duration.dart new file mode 100644 index 00000000..7262b997 --- /dev/null +++ b/lib/app/modules/settings/views/customize_undo_duration.dart @@ -0,0 +1,137 @@ + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get/get_core/src/get_main.dart'; +import 'package:ultimate_alarm_clock/app/modules/home/controllers/home_controller.dart'; + +import '../../../utils/constants.dart'; +import '../../../utils/utils.dart'; +import '../controllers/theme_controller.dart'; +import 'package:ultimate_alarm_clock/app/modules/settings/controllers/settings_controller.dart'; + +class CustomizeUndoDuration extends StatelessWidget{ + HomeController homeController = Get.find(); + CustomizeUndoDuration({ + super.key , + required this.themeController, + required this.height, + required this.width, + }); + final ThemeController themeController; + final double width; + final double height; + + @override + Widget build(BuildContext context) { + int duration; + return InkWell( + onTap: () { + Utils.hapticFeedback(); + duration = homeController.duration.value; + Get.defaultDialog( + onWillPop: () async { + Get.back(); + // Resetting the value to its initial state + homeController.duration.value = duration; + return true; + }, + titlePadding: const EdgeInsets.symmetric(vertical: 20, horizontal: 5), + backgroundColor: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + title: 'Customize Undo Duration'.tr, + titleStyle: Theme.of(context).textTheme.displaySmall, + content: Obx( + () => Column( + children: [ + Text( + '${homeController.duration.value} seconds'.tr, + style: Theme.of(context).textTheme.displaySmall, + ), + Slider( + value: homeController.selecteddurationDouble.value, + onChanged: (double value) { + homeController.selecteddurationDouble.value = value; + homeController.duration.value = value.toInt(); + + }, + min: 0.0, + max: 20.0, + divisions: 20, + label: homeController.duration.value.toString(), + ), + // Replace the volMin Slider with RangeSlider + + ElevatedButton( + onPressed: () { + Get.back(); + }, + style: ElevatedButton.styleFrom( + backgroundColor: kprimaryColor, + ), + child: Text( + 'Apply Duration'.tr, + style: TextStyle( + color: themeController.isLightMode.value + ? kLightSecondaryTextColor + : ksecondaryTextColor, + ), + ), + ), + ], + ), + ), + ); + }, + child: Container( + width: width * 0.91, + height: height * 0.09, + decoration: Utils.getCustomTileBoxDecoration( + isLightMode: themeController.isLightMode.value, + ), + child: Center( + child: Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: ListTile( + tileColor: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + title: Text( + 'Undo Duration'.tr, + style: TextStyle( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + fontSize: 15 + ), + ), + trailing: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Obx( + () => Text( + '${homeController.duration.value.round().toInt()} seconds', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + fontSize: 13 + ), + ), + ), + Icon( + Icons.chevron_right, + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ], + ), + ), + ), + ) + ) + ); + } + +} \ No newline at end of file From 1d06b861933296af137229b78a47bb36d2802926 Mon Sep 17 00:00:00 2001 From: krish Date: Wed, 20 Mar 2024 19:22:24 +0530 Subject: [PATCH 11/14] resolved merge conflict --- .gitignore | 9 + ios/Flutter/AppFrameworkInfo.plist | 2 +- ios/Podfile | 14 +- ios/Podfile.lock | 293 ++-- ios/Runner.xcodeproj/project.pbxproj | 30 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- ios/Runner/Info.plist | 4 +- .../add_or_update_alarm_controller.dart | 289 +++- .../controllers/input_time_controller.dart | 33 +- .../views/add_or_update_alarm_view.dart | 2 + .../views/choose_ringtone_tile.dart | 10 +- .../addOrUpdateAlarm/views/repeat_tile.dart | 45 +- .../addOrUpdateAlarm/views/weather_tile.dart | 117 +- .../alarm_challenge_controller.dart | 2 +- .../controllers/alarm_ring_controller.dart | 4 + .../alarmRing/views/alarm_ring_view.dart | 46 +- .../bottom_navigation_bar_binding.dart | 2 + .../bottom_navigation_bar_controller.dart | 20 +- .../views/bottom_navigation_bar_view.dart | 59 +- .../home/controllers/home_controller.dart | 12 +- lib/app/modules/home/views/home_view.dart | 1387 +++++++++-------- .../modules/settings/views/settings_view.dart | 9 + .../modules/settings/views/weather_api.dart | 9 +- .../modules/timer/bindings/timer_binding.dart | 2 + .../timer/controllers/timer_controller.dart | 11 +- lib/app/modules/timer/views/timer_view.dart | 691 +++++--- lib/app/utils/audio_utils.dart | 10 +- lib/app/utils/constants.dart | 24 + lib/app/utils/language.dart | 5 + .../utils/languages/french_translations.dart | 4 + .../utils/languages/german_translations.dart | 4 + .../utils/languages/russian_translations.dart | 4 + .../utils/languages/spanish_translations.dart | 4 + pubspec.lock | 4 +- pubspec.yaml | 2 +- 35 files changed, 1957 insertions(+), 1208 deletions(-) diff --git a/.gitignore b/.gitignore index 24476c5d..a0ba6efd 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,12 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +# Generated Files for macOS, Linux, and Windows +/linux/flutter/generated_plugin_registrant.cc +/linux/flutter/generated_plugin_registrant.h +/linux/flutter/generated_plugins.cmake +/macos/Flutter/GeneratedPluginRegistrant.swift +/windows/flutter/generated_plugin_registrant.cc +/windows/flutter/generated_plugin_registrant.h +/windows/flutter/generated_plugins.cmake diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 9625e105..7c569640 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/ios/Podfile b/ios/Podfile index 88359b22..5002e643 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '11.0' +platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -37,5 +37,17 @@ end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) + + target.build_configurations.each do |config| + # You can remove unused permissions here + # for more infomation: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h + # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ + '$(inherited)', + + ## dart: PermissionGroup.notification + 'PERMISSION_NOTIFICATIONS=1', + ] + end end end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f87d916b..d811272e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -628,42 +628,86 @@ PODS: - abseil/base/base_internal - abseil/base/config - abseil/meta/type_traits - - app_minimizer (0.0.1): - - Flutter - - AppAuth (1.6.1): - - AppAuth/Core (= 1.6.1) - - AppAuth/ExternalUserAgent (= 1.6.1) - - AppAuth/Core (1.6.1) - - AppAuth/ExternalUserAgent (1.6.1): + - AppAuth (1.6.2): + - AppAuth/Core (= 1.6.2) + - AppAuth/ExternalUserAgent (= 1.6.2) + - AppAuth/Core (1.6.2) + - AppAuth/ExternalUserAgent (1.6.2): - AppAuth/Core + - audio_session (0.0.1): + - Flutter + - audioplayers_darwin (0.0.1): + - Flutter - BoringSSL-GRPC (0.0.24): - BoringSSL-GRPC/Implementation (= 0.0.24) - BoringSSL-GRPC/Interface (= 0.0.24) - BoringSSL-GRPC/Implementation (0.0.24): - BoringSSL-GRPC/Interface (= 0.0.24) - BoringSSL-GRPC/Interface (0.0.24) - - cloud_firestore (4.8.2): - - Firebase/Firestore (= 10.10.0) + - cloud_firestore (4.14.0): + - Firebase/Firestore (= 10.18.0) - firebase_core - Flutter - nanopb (< 2.30910.0, >= 2.30908.0) - device_info_plus (0.0.1): - Flutter - - Firebase/CoreOnly (10.10.0): - - FirebaseCore (= 10.10.0) - - Firebase/Firestore (10.10.0): + - DKImagePickerController/Core (4.3.4): + - DKImagePickerController/ImageDataManager + - DKImagePickerController/Resource + - DKImagePickerController/ImageDataManager (4.3.4) + - DKImagePickerController/PhotoGallery (4.3.4): + - DKImagePickerController/Core + - DKPhotoGallery + - DKImagePickerController/Resource (4.3.4) + - DKPhotoGallery (0.0.17): + - DKPhotoGallery/Core (= 0.0.17) + - DKPhotoGallery/Model (= 0.0.17) + - DKPhotoGallery/Preview (= 0.0.17) + - DKPhotoGallery/Resource (= 0.0.17) + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Core (0.0.17): + - DKPhotoGallery/Model + - DKPhotoGallery/Preview + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Model (0.0.17): + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Preview (0.0.17): + - DKPhotoGallery/Model + - DKPhotoGallery/Resource + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Resource (0.0.17): + - SDWebImage + - SwiftyGif + - file_picker (0.0.1): + - DKImagePickerController/PhotoGallery + - Flutter + - Firebase/CoreOnly (10.18.0): + - FirebaseCore (= 10.18.0) + - Firebase/Firestore (10.18.0): - Firebase/CoreOnly - - FirebaseFirestore (~> 10.10.0) - - firebase_core (2.14.0): - - Firebase/CoreOnly (= 10.10.0) + - FirebaseFirestore (~> 10.18.0) + - firebase_core (2.24.2): + - Firebase/CoreOnly (= 10.18.0) - Flutter - - FirebaseCore (10.10.0): + - FirebaseAppCheckInterop (10.22.0) + - FirebaseCore (10.18.0): - FirebaseCoreInternal (~> 10.0) - - GoogleUtilities/Environment (~> 7.8) - - GoogleUtilities/Logger (~> 7.8) - - FirebaseCoreInternal (10.11.0): + - GoogleUtilities/Environment (~> 7.12) + - GoogleUtilities/Logger (~> 7.12) + - FirebaseCoreExtension (10.22.0): + - FirebaseCore (~> 10.0) + - FirebaseCoreInternal (10.22.0): - "GoogleUtilities/NSData+zlib (~> 7.8)" - - FirebaseFirestore (10.10.0): + - FirebaseFirestore (10.18.0): + - FirebaseCore (~> 10.0) + - FirebaseCoreExtension (~> 10.0) + - FirebaseFirestoreInternal (~> 10.17) + - FirebaseSharedSwift (~> 10.0) + - FirebaseFirestoreInternal (10.22.0): - abseil/algorithm (~> 1.20220623.0) - abseil/base (~> 1.20220623.0) - abseil/container/flat_hash_map (~> 1.20220623.0) @@ -672,25 +716,31 @@ PODS: - abseil/strings/strings (~> 1.20220623.0) - abseil/time (~> 1.20220623.0) - abseil/types (~> 1.20220623.0) + - FirebaseAppCheckInterop (~> 10.17) - FirebaseCore (~> 10.0) - - "gRPC-C++ (~> 1.50.1)" + - "gRPC-C++ (~> 1.49.1)" - leveldb-library (~> 1.22) - - nanopb (< 2.30910.0, >= 2.30908.0) + - nanopb (< 2.30911.0, >= 2.30908.0) + - FirebaseSharedSwift (10.22.0) - fl_location (0.0.1): - Flutter - Flutter (1.0.0) - flutter_fgbg (0.0.1): - Flutter - - flutter_foreground_task (0.0.1): - - Flutter - - flutter_ringtone_player (0.0.1): + - flutter_native_splash (0.0.1): - Flutter - flutter_secure_storage (6.0.0): - Flutter + - flutter_volume_controller (0.0.1): + - Flutter + - fluttertoast (0.0.2): + - Flutter + - Toast - google_sign_in_ios (0.0.1): - Flutter - - GoogleSignIn (~> 6.2) - - GoogleDataTransport (9.2.3): + - FlutterMacOS + - GoogleSignIn (~> 7.0) + - GoogleDataTransport (9.4.0): - GoogleUtilities/Environment (~> 7.7) - nanopb (< 2.30910.0, >= 2.30908.0) - PromisesObjC (< 3.0, >= 1.2) @@ -699,10 +749,10 @@ PODS: - MLKitBarcodeScanning (~> 3.0.0) - GoogleMLKit/MLKitCore (4.0.0): - MLKitCommon (~> 9.0.0) - - GoogleSignIn (6.2.4): + - GoogleSignIn (7.0.0): - AppAuth (~> 1.5) - - GTMAppAuth (~> 1.3) - - GTMSessionFetcher/Core (< 3.0, >= 1.1) + - GTMAppAuth (< 3.0, >= 1.3) + - GTMSessionFetcher/Core (< 4.0, >= 1.1) - GoogleToolboxForMac/DebugUtils (2.3.2): - GoogleToolboxForMac/Defines (= 2.3.2) - GoogleToolboxForMac/Defines (2.3.2) @@ -715,19 +765,24 @@ PODS: - GoogleToolboxForMac/Defines (= 2.3.2) - "GoogleToolboxForMac/NSString+URLArguments (= 2.3.2)" - "GoogleToolboxForMac/NSString+URLArguments (2.3.2)" - - GoogleUtilities/Environment (7.11.1): + - GoogleUtilities/Environment (7.13.0): + - GoogleUtilities/Privacy - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/Logger (7.11.1): + - GoogleUtilities/Logger (7.13.0): - GoogleUtilities/Environment - - "GoogleUtilities/NSData+zlib (7.11.1)" - - GoogleUtilities/UserDefaults (7.11.1): + - GoogleUtilities/Privacy + - "GoogleUtilities/NSData+zlib (7.13.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (7.13.0) + - GoogleUtilities/UserDefaults (7.13.0): - GoogleUtilities/Logger + - GoogleUtilities/Privacy - GoogleUtilitiesComponents (1.1.0): - GoogleUtilities/Logger - - "gRPC-C++ (1.50.1)": - - "gRPC-C++/Implementation (= 1.50.1)" - - "gRPC-C++/Interface (= 1.50.1)" - - "gRPC-C++/Implementation (1.50.1)": + - "gRPC-C++ (1.49.1)": + - "gRPC-C++/Implementation (= 1.49.1)" + - "gRPC-C++/Interface (= 1.49.1)" + - "gRPC-C++/Implementation (1.49.1)": - abseil/base/base (= 1.20220623.0) - abseil/base/core_headers (= 1.20220623.0) - abseil/cleanup/cleanup (= 1.20220623.0) @@ -752,13 +807,13 @@ PODS: - abseil/types/span (= 1.20220623.0) - abseil/types/variant (= 1.20220623.0) - abseil/utility/utility (= 1.20220623.0) - - "gRPC-C++/Interface (= 1.50.1)" - - gRPC-Core (= 1.50.1) - - "gRPC-C++/Interface (1.50.1)" - - gRPC-Core (1.50.1): - - gRPC-Core/Implementation (= 1.50.1) - - gRPC-Core/Interface (= 1.50.1) - - gRPC-Core/Implementation (1.50.1): + - "gRPC-C++/Interface (= 1.49.1)" + - gRPC-Core (= 1.49.1) + - "gRPC-C++/Interface (1.49.1)" + - gRPC-Core (1.49.1): + - gRPC-Core/Implementation (= 1.49.1) + - gRPC-Core/Interface (= 1.49.1) + - gRPC-Core/Implementation (1.49.1): - abseil/base/base (= 1.20220623.0) - abseil/base/core_headers (= 1.20220623.0) - abseil/container/flat_hash_map (= 1.20220623.0) @@ -783,15 +838,15 @@ PODS: - abseil/types/variant (= 1.20220623.0) - abseil/utility/utility (= 1.20220623.0) - BoringSSL-GRPC (= 0.0.24) - - gRPC-Core/Interface (= 1.50.1) - - gRPC-Core/Interface (1.50.1) - - GTMAppAuth (1.3.1): + - gRPC-Core/Interface (= 1.49.1) + - gRPC-Core/Interface (1.49.1) + - GTMAppAuth (2.0.0): - AppAuth/Core (~> 1.6) - - GTMSessionFetcher/Core (< 3.0, >= 1.5) + - GTMSessionFetcher/Core (< 4.0, >= 1.5) - GTMSessionFetcher/Core (2.3.0) - isar_flutter_libs (1.0.0): - Flutter - - leveldb-library (1.22.2) + - leveldb-library (1.22.4) - MLImage (1.0.0-beta4) - MLKitBarcodeScanning (3.0.0): - MLKitCommon (~> 9.0) @@ -810,51 +865,58 @@ PODS: - GTMSessionFetcher/Core (< 3.0, >= 1.1) - MLImage (= 1.0.0-beta4) - MLKitCommon (~> 9.0) - - mobile_scanner (3.2.0): + - mobile_scanner (3.5.5): - Flutter - GoogleMLKit/BarcodeScanning (~> 4.0.0) - - nanopb (2.30909.0): - - nanopb/decode (= 2.30909.0) - - nanopb/encode (= 2.30909.0) - - nanopb/decode (2.30909.0) - - nanopb/encode (2.30909.0) + - nanopb (2.30909.1): + - nanopb/decode (= 2.30909.1) + - nanopb/encode (= 2.30909.1) + - nanopb/decode (2.30909.1) + - nanopb/encode (2.30909.1) - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS + - pedometer (0.0.1): + - Flutter - permission_handler_apple (9.1.1): - Flutter - - PromisesObjC (2.2.0) + - PromisesObjC (2.4.0) - screen_state (0.0.1): - Flutter + - SDWebImage (5.19.0): + - SDWebImage/Core (= 5.19.0) + - SDWebImage/Core (5.19.0) - sensors_plus (0.0.1): - Flutter - - shared_preferences_foundation (0.0.1): - - Flutter - - FlutterMacOS + - SwiftyGif (5.4.4) + - Toast (4.1.0) - url_launcher_ios (0.0.1): - Flutter - vibration (1.7.5): - Flutter DEPENDENCIES: - - app_minimizer (from `.symlinks/plugins/app_minimizer/ios`) + - audio_session (from `.symlinks/plugins/audio_session/ios`) + - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`) - cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) + - file_picker (from `.symlinks/plugins/file_picker/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - fl_location (from `.symlinks/plugins/fl_location/ios`) - Flutter (from `Flutter`) - flutter_fgbg (from `.symlinks/plugins/flutter_fgbg/ios`) - - flutter_foreground_task (from `.symlinks/plugins/flutter_foreground_task/ios`) - - flutter_ringtone_player (from `.symlinks/plugins/flutter_ringtone_player/ios`) + - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`) + - flutter_volume_controller (from `.symlinks/plugins/flutter_volume_controller/ios`) + - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) + - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`) - isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`) - mobile_scanner (from `.symlinks/plugins/mobile_scanner/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) + - pedometer (from `.symlinks/plugins/pedometer/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - screen_state (from `.symlinks/plugins/screen_state/ios`) - sensors_plus (from `.symlinks/plugins/sensors_plus/ios`) - - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - vibration (from `.symlinks/plugins/vibration/ios`) @@ -863,10 +925,16 @@ SPEC REPOS: - abseil - AppAuth - BoringSSL-GRPC + - DKImagePickerController + - DKPhotoGallery - Firebase + - FirebaseAppCheckInterop - FirebaseCore + - FirebaseCoreExtension - FirebaseCoreInternal - FirebaseFirestore + - FirebaseFirestoreInternal + - FirebaseSharedSwift - GoogleDataTransport - GoogleMLKit - GoogleSignIn @@ -884,14 +952,21 @@ SPEC REPOS: - MLKitVision - nanopb - PromisesObjC + - SDWebImage + - SwiftyGif + - Toast EXTERNAL SOURCES: - app_minimizer: - :path: ".symlinks/plugins/app_minimizer/ios" + audio_session: + :path: ".symlinks/plugins/audio_session/ios" + audioplayers_darwin: + :path: ".symlinks/plugins/audioplayers_darwin/ios" cloud_firestore: :path: ".symlinks/plugins/cloud_firestore/ios" device_info_plus: :path: ".symlinks/plugins/device_info_plus/ios" + file_picker: + :path: ".symlinks/plugins/file_picker/ios" firebase_core: :path: ".symlinks/plugins/firebase_core/ios" fl_location: @@ -900,28 +975,30 @@ EXTERNAL SOURCES: :path: Flutter flutter_fgbg: :path: ".symlinks/plugins/flutter_fgbg/ios" - flutter_foreground_task: - :path: ".symlinks/plugins/flutter_foreground_task/ios" - flutter_ringtone_player: - :path: ".symlinks/plugins/flutter_ringtone_player/ios" + flutter_native_splash: + :path: ".symlinks/plugins/flutter_native_splash/ios" flutter_secure_storage: :path: ".symlinks/plugins/flutter_secure_storage/ios" + flutter_volume_controller: + :path: ".symlinks/plugins/flutter_volume_controller/ios" + fluttertoast: + :path: ".symlinks/plugins/fluttertoast/ios" google_sign_in_ios: - :path: ".symlinks/plugins/google_sign_in_ios/ios" + :path: ".symlinks/plugins/google_sign_in_ios/darwin" isar_flutter_libs: :path: ".symlinks/plugins/isar_flutter_libs/ios" mobile_scanner: :path: ".symlinks/plugins/mobile_scanner/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" + pedometer: + :path: ".symlinks/plugins/pedometer/ios" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" screen_state: :path: ".symlinks/plugins/screen_state/ios" sensors_plus: :path: ".symlinks/plugins/sensors_plus/ios" - shared_preferences_foundation: - :path: ".symlinks/plugins/shared_preferences_foundation/darwin" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" vibration: @@ -929,50 +1006,62 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: abseil: 926fb7a82dc6d2b8e1f2ed7f3a718bce691d1e46 - app_minimizer: a7e8bf2b20361723f210b079a8ab00230942ff6d - AppAuth: e48b432bb4ba88b10cb2bcc50d7f3af21e78b9c2 + AppAuth: 3bb1d1cd9340bd09f5ed189fb00b1cc28e1e8570 + audio_session: 4f3e461722055d21515cf3261b64c973c062f345 + audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 BoringSSL-GRPC: 3175b25143e648463a56daeaaa499c6cb86dad33 - cloud_firestore: 818ebb1a8235177a0dcf7005c14aed5408b8342c - device_info_plus: 7545d84d8d1b896cb16a4ff98c19f07ec4b298ea - Firebase: facd334e557a979bd03a0b58d90fd56b52b8aba0 - firebase_core: 85b6664038311940ad60584eaabc73103c61f5de - FirebaseCore: d027ff503d37edb78db98429b11f580a24a7df2a - FirebaseCoreInternal: 9e46c82a14a3b3a25be4e1e151ce6d21536b89c0 - FirebaseFirestore: b3bb12a497c9d13e80ec3158dbb75ded03592e8d + cloud_firestore: 73eece22ce25a0565238c283ee9990f1618d8063 + device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 + DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac + DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 + file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de + Firebase: 414ad272f8d02dfbf12662a9d43f4bba9bec2a06 + firebase_core: 0af4a2b24f62071f9bf283691c0ee41556dcb3f5 + FirebaseAppCheckInterop: 58db3e9494751399cf3e7b7e3e705cff71099153 + FirebaseCore: 2322423314d92f946219c8791674d2f3345b598f + FirebaseCoreExtension: 6394c00b887d0bebadbc7049c464aa0cbddc5d41 + FirebaseCoreInternal: bca337352024b18424a61e478460547d46c4c753 + FirebaseFirestore: 171bcbb57a1a348dd171a0d5e382c03ef85a77bb + FirebaseFirestoreInternal: 86fe6fc8ca156309cb4842d2d7b2f15c669a64a0 + FirebaseSharedSwift: 48076404e6e52372290d15a07d2ed1d2f1754023 fl_location: 68b4a6c4aad2a453493ff66f196e0748280cf43e - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_fgbg: 31c0d1140a131daea2d342121808f6aa0dcd879d - flutter_foreground_task: 21ef182ab0a29a3005cc72cd70e5f45cb7f7f817 - flutter_ringtone_player: 15eba85187230b87b2512f0e1b92225618bc03e7 + flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be - google_sign_in_ios: 1256ff9d941db546373826966720b0c24804bcdd - GoogleDataTransport: f0308f5905a745f94fb91fea9c6cbaf3831cb1bd + flutter_volume_controller: e4d5832f08008180f76e30faf671ffd5a425e529 + fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265 + google_sign_in_ios: 1bfaf6607b44cd1b24c4d4bc39719870440f9ce1 + GoogleDataTransport: bed3a36c04c8552479fbb9b76326e0fc69bddcb2 GoogleMLKit: 2bd0dc6253c4d4f227aad460f69215a504b2980e - GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a + GoogleSignIn: b232380cf495a429b8095d3178a8d5855b42e842 GoogleToolboxForMac: 8bef7c7c5cf7291c687cf5354f39f9db6399ad34 - GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749 + GoogleUtilities: d053d902a8edaa9904e1bd00c37535385b8ed152 GoogleUtilitiesComponents: 679b2c881db3b615a2777504623df6122dd20afe - "gRPC-C++": 0968bace703459fd3e5dcb0b2bed4c573dbff046 - gRPC-Core: 17108291d84332196d3c8466b48f016fc17d816d - GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd + "gRPC-C++": 2df8cba576898bdacd29f0266d5236fa0e26ba6a + gRPC-Core: a21a60aefc08c68c247b439a9ef97174b0c54f96 + GTMAppAuth: 99fb010047ba3973b7026e45393f51f27ab965ae GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2 isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073 - leveldb-library: f03246171cce0484482ec291f88b6d563699ee06 + leveldb-library: 06a69cc7582d64b29424a63e085e683cc188230a MLImage: 7bb7c4264164ade9bf64f679b40fb29c8f33ee9b MLKitBarcodeScanning: 04e264482c5f3810cb89ebc134ef6b61e67db505 MLKitCommon: c1b791c3e667091918d91bda4bba69a91011e390 MLKitVision: 8baa5f46ee3352614169b85250574fde38c36f49 - mobile_scanner: 47056db0c04027ea5f41a716385542da28574662 - nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 - path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 + mobile_scanner: 202ab6f652e40a9add68b10de4c4fb2a745c4348 + nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + pedometer: 381969883680ade42559782cc41a3bbd453d8234 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 - PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 screen_state: a7ae251997e97f3f001839df09b57313b0ddef18 + SDWebImage: 981fd7e860af070920f249fd092420006014c3eb sensors_plus: 5717760720f7e6acd96fdbd75b7428f5ad755ec2 - shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c - url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 + SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f + Toast: ec33c32b8688982cecc6348adeae667c1b9938da + url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812 vibration: 7d883d141656a1c1a6d8d238616b2042a51a1241 -PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 +PODFILE CHECKSUM: b0d4019d63a06aa0d701044dbc594a28e1b1d370 -COCOAPODS: 1.12.0 +COCOAPODS: 1.15.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 75c1f8ae..1f30e52b 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -124,7 +124,6 @@ EE7366E14E5A260606CB06CD /* Pods-Runner.release.xcconfig */, B33171C6E207358295CC5A05 /* Pods-Runner.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -143,6 +142,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 66B6F9F61F03F5B8E2EEE6AC /* [CP] Embed Pods Frameworks */, + 9BDD1910BFDD1BE8CE6A1772 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -159,7 +159,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -250,6 +250,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + 9BDD1910BFDD1BE8CE6A1772 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; F7AF27F2B7862160C6BE8F5A /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -347,7 +364,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -363,6 +380,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = A36HPZ86P4; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -424,7 +442,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -473,7 +491,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -491,6 +509,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = A36HPZ86P4; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -513,6 +532,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = A36HPZ86P4; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a3..5e31d3d3 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ - + + PermissionGroupNotification + This app needs notification permissions to show notifications. NSCameraUsageDescription This app needs camera access to scan QR codes NSPhotoLibraryUsageDescription 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 996b72f4..8568b813 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 @@ -61,7 +61,8 @@ class AddOrUpdateAlarmController extends GetxController { facing: CameraFacing.back, torchEnabled: false, ); - final qrValue = ''.obs; + final qrValue = ''.obs; // qrvalue stored in alarm + final detectedQrValue = ''.obs; // QR value detected by camera final isQrEnabled = false.obs; //photochallenge @@ -116,6 +117,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(); } @@ -145,7 +150,7 @@ class AddOrUpdateAlarmController extends GetxController { } void setIsCustomSelected(bool value) { - isCustomSelected.value = true; + isCustomSelected.value = value; if (value == true) { isWeekdaysSelected.value = false; isDailySelected.value = false; @@ -197,24 +202,28 @@ class AddOrUpdateAlarmController extends GetxController { onPressed: () async { Get.back(); - // Request overlay permission - if (!(await Permission.systemAlertWindow.isGranted)) { - final status = await Permission.systemAlertWindow.request(); - if (!status.isGranted) { - debugPrint('SYSTEM_ALERT_WINDOW permission denied!'); - return; + if (Platform.isAndroid) { + // Request overlay permission + if (!(await Permission.systemAlertWindow.isGranted)) { + final status = await Permission.systemAlertWindow.request(); + if (!status.isGranted) { + debugPrint('SYSTEM_ALERT_WINDOW permission denied!'); + return; + } } - } - if (!(await Permission.ignoreBatteryOptimizations.isGranted)) { - bool requested = await Permission.ignoreBatteryOptimizations - .request() - .isGranted; - if (!requested) { - debugPrint('IGNORE_BATTERY_OPTIMIZATION permission denied!'); - return; + if (!(await Permission.ignoreBatteryOptimizations.isGranted)) { + bool requested = await Permission.ignoreBatteryOptimizations + .request() + .isGranted; + if (!requested) { + debugPrint( + 'IGNORE_BATTERY_OPTIMIZATION permission denied!'); + return; + } } } + // Request notification permission if (!await Permission.notification.isGranted) { final status = await Permission.notification.request(); @@ -234,6 +243,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); @@ -336,7 +419,7 @@ class AddOrUpdateAlarmController extends GetxController { } showQRDialog() { - restartQRCodeController(); + restartQRCodeController(false); Get.defaultDialog( titlePadding: const EdgeInsets.symmetric(vertical: 20), backgroundColor: themeController.isLightMode.value @@ -347,7 +430,7 @@ class AddOrUpdateAlarmController extends GetxController { content: Obx( () => Column( children: [ - isQrEnabled.value == false + detectedQrValue.value.isEmpty ? SizedBox( height: 300, width: 300, @@ -357,18 +440,17 @@ class AddOrUpdateAlarmController extends GetxController { onDetect: (capture) { final List barcodes = capture.barcodes; for (final barcode in barcodes) { - qrValue.value = barcode.rawValue.toString(); + detectedQrValue.value = barcode.rawValue.toString(); debugPrint(barcode.rawValue.toString()); - isQrEnabled.value = true; } }, ), ) : Padding( padding: const EdgeInsets.only(bottom: 15.0), - child: Text(qrValue.value), + child: Text(detectedQrValue.value), ), - isQrEnabled.value == true + (detectedQrValue.value.isNotEmpty) ? Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -389,6 +471,8 @@ class AddOrUpdateAlarmController extends GetxController { ), ), onPressed: () { + qrValue.value = detectedQrValue.value; + isQrEnabled.value = true; Get.back(); }, ), @@ -410,10 +494,32 @@ class AddOrUpdateAlarmController extends GetxController { ), onPressed: () async { qrController.dispose(); - restartQRCodeController(); - isQrEnabled.value = false; + restartQRCodeController(true); }, ), + if (isQrEnabled.value) + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(kprimaryColor), + ), + child: Text( + 'Disable', + style: Theme.of(Get.context!) + .textTheme + .displaySmall! + .copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () { + isQrEnabled.value = false; + qrValue.value = ''; + Get.back(); + }, + ), ], ) : const SizedBox(), @@ -502,7 +608,7 @@ class AddOrUpdateAlarmController extends GetxController { } } - restartQRCodeController() async { + restartQRCodeController(bool retake) async { // Camera permission already granted, proceed with QR code scanning qrController = MobileScannerController( autoStart: true, @@ -510,6 +616,7 @@ class AddOrUpdateAlarmController extends GetxController { facing: CameraFacing.back, torchEnabled: false, ); + detectedQrValue.value = retake ? '' : qrValue.value; } requestPhotoPermission(context) async { @@ -862,6 +969,7 @@ class AddOrUpdateAlarmController extends GetxController { isQrEnabled.value = alarmRecord!.isQrEnabled; qrValue.value = alarmRecord!.qrValue; + detectedQrValue.value = alarmRecord!.qrValue; isPhotochallengeEnabled.value = alarmRecord!.isPhotochallengeEnabled; imageurl.value = alarmRecord!.imageurl; @@ -923,6 +1031,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( @@ -939,38 +1126,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/controllers/input_time_controller.dart b/lib/app/modules/addOrUpdateAlarm/controllers/input_time_controller.dart index 7888ad57..6b7dc30a 100644 --- a/lib/app/modules/addOrUpdateAlarm/controllers/input_time_controller.dart +++ b/lib/app/modules/addOrUpdateAlarm/controllers/input_time_controller.dart @@ -3,14 +3,20 @@ import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/controllers/add_or_update_alarm_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/settings_controller.dart'; +import 'package:ultimate_alarm_clock/app/modules/timer/controllers/timer_controller.dart'; class InputTimeController extends GetxController { AddOrUpdateAlarmController addOrUpdateAlarmController = Get.find(); + TimerController timerController = Get.find(); SettingsController settingsController = Get.find(); final isTimePicker = false.obs; + final isTimePickerTimer = false.obs; TextEditingController inputHrsController = TextEditingController(); TextEditingController inputMinutesController = TextEditingController(); + TextEditingController inputHoursControllerTimer = TextEditingController(); + TextEditingController inputMinutesControllerTimer = TextEditingController(); + TextEditingController inputSecondsControllerTimer = TextEditingController(); final selectedDateTime = DateTime.now().obs; bool isInputtingTime = false; @@ -22,6 +28,7 @@ class InputTimeController extends GetxController { @override void onInit() { isTimePicker.value = true; + isTimePickerTimer.value = true; selectedDateTime.value = addOrUpdateAlarmController.selectedTime.value; isAM.value = addOrUpdateAlarmController.selectedTime.value.hour < 12; inputHrsController.text = settingsController.is24HrsEnabled.value @@ -32,6 +39,9 @@ class InputTimeController extends GetxController { ? (selectedDateTime.value.hour - 12).toString() : selectedDateTime.value.hour.toString())); inputMinutesController.text = selectedDateTime.value.minute.toString(); + inputHoursControllerTimer.text = timerController.hours.value.toString(); + inputMinutesControllerTimer.text = timerController.minutes.value.toString(); + inputSecondsControllerTimer.text = timerController.seconds.value.toString(); super.onInit(); } @@ -44,6 +54,10 @@ class InputTimeController extends GetxController { isTimePicker.value = !isTimePicker.value; } + changeTimePickerTimer() { + isTimePickerTimer.value = !isTimePickerTimer.value; + } + int convert24(int value) { if (!settingsController.is24HrsEnabled.value) { if (addOrUpdateAlarmController.meridiemIndex == 0) { @@ -95,7 +109,7 @@ class InputTimeController extends GetxController { addOrUpdateAlarmController.hours.value = 12; } else if (selectedDateTime.value.hour > 12) { addOrUpdateAlarmController.hours.value = - (selectedDateTime.value.hour-12); + (selectedDateTime.value.hour - 12); } else { addOrUpdateAlarmController.hours.value = selectedDateTime.value.hour; } @@ -114,10 +128,27 @@ class InputTimeController extends GetxController { } } + void setTimerTime() { + try { + int hours = int.parse(inputHoursControllerTimer.text); + int minutes = int.parse(inputMinutesControllerTimer.text); + int seconds = int.parse(inputSecondsControllerTimer.text); + + timerController.hours.value = hours; + timerController.minutes.value = minutes; + timerController.seconds.value = seconds; + } catch (e) { + debugPrint(e.toString()); + } + } + @override void onClose() { inputHrsController.dispose(); inputMinutesController.dispose(); + inputHoursControllerTimer.dispose(); + inputMinutesControllerTimer.dispose(); + inputSecondsControllerTimer.dispose(); super.onClose(); } } 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 362c29b4..095cc178 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'; diff --git a/lib/app/modules/addOrUpdateAlarm/views/choose_ringtone_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/choose_ringtone_tile.dart index 9e07396f..51c19173 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/choose_ringtone_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/choose_ringtone_tile.dart @@ -20,14 +20,14 @@ class ChooseRingtoneTile extends StatelessWidget { final double height; final double width; - void onTapPreview(String ringtonePath) async { + void onTapPreview(String ringtonePath) async { Utils.hapticFeedback(); - // Stop the currently playing audio before starting the preview for the new audio - await AudioUtils.stopPreviewCustomSound(); - - if (controller.isPlaying.value) { + // Stop the currently playing audio before starting the preview for the new + // audio + if (controller.isPlaying.value == true) { // If it was playing, reset the isPlaying state to false + await AudioUtils.stopPreviewCustomSound(); controller.toggleIsPlaying(); } else { await AudioUtils.previewCustomSound(ringtonePath); diff --git a/lib/app/modules/addOrUpdateAlarm/views/repeat_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/repeat_tile.dart index e01cd947..86b7fb5c 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/repeat_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/repeat_tile.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:get/get_connect/http/src/utils/utils.dart'; -import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/views/repeat_once_tile.dart'; import 'package:ultimate_alarm_clock/app/utils/constants.dart'; import 'package:ultimate_alarm_clock/app/utils/utils.dart'; @@ -38,10 +36,7 @@ class RepeatTile extends StatelessWidget { height: height * 0.45, child: Column( children: [ - buildDailyTile( - controller: controller, - themeController: themeController, - ), + buildDailyTile(), Container( color: themeController.isLightMode.value ? kLightSecondaryBackgroundColor @@ -52,10 +47,7 @@ class RepeatTile extends StatelessWidget { : kprimaryDisabledTextColor, ), ), - buildWeekdaysTile( - controller: controller, - themeController: themeController, - ), + buildWeekdaysTile(), Container( color: themeController.isLightMode.value ? kLightSecondaryBackgroundColor @@ -67,8 +59,6 @@ class RepeatTile extends StatelessWidget { ), ), buildCustomDaysTile( - controller: controller, - themeController: themeController, context: context, ), const SizedBox( @@ -168,12 +158,9 @@ class RepeatTile extends StatelessWidget { } } - ListTile buildDailyTile({ - required AddOrUpdateAlarmController controller, - required ThemeController themeController, - }) { + ListTile buildDailyTile() { return ListTile( - contentPadding: EdgeInsets.only(left: 10.0), + contentPadding: const EdgeInsets.only(left: 10.0), title: Obx( () => InkWell( onTap: () { @@ -186,7 +173,7 @@ class RepeatTile extends StatelessWidget { } }, child: Padding( - padding: EdgeInsets.all(8.0), // Adjust the padding as needed + padding: const EdgeInsets.all(8.0), // Adjust the padding as needed child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, @@ -261,13 +248,11 @@ class RepeatTile extends StatelessWidget { } ListTile buildCustomDaysTile({ - required AddOrUpdateAlarmController controller, - required ThemeController themeController, required BuildContext context, }) { List repeatDays = List.filled(7, false); return ListTile( - contentPadding: EdgeInsets.only(left: 10.0), + contentPadding: const EdgeInsets.only(left: 10.0), title: Obx( () => InkWell( onTap: () { @@ -362,7 +347,7 @@ class RepeatTile extends StatelessWidget { ); }, child: Padding( - padding: EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, @@ -393,12 +378,9 @@ class RepeatTile extends StatelessWidget { ); } - ListTile buildWeekdaysTile({ - required AddOrUpdateAlarmController controller, - required ThemeController themeController, - }) { + ListTile buildWeekdaysTile() { return ListTile( - contentPadding: EdgeInsets.only(left: 10.0), + contentPadding: const EdgeInsets.only(left: 10.0), title: Obx( () => InkWell( onTap: () { @@ -414,12 +396,12 @@ class RepeatTile extends StatelessWidget { } }, child: Padding( - padding: EdgeInsets.all(8.0), // Adjust the padding as needed + padding: const EdgeInsets.all(8.0), // Adjust the padding as needed child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text( + const Text( 'Weekdays', ), Checkbox.adaptive( @@ -434,7 +416,8 @@ class RepeatTile extends StatelessWidget { onChanged: (value) { Utils.hapticFeedback(); controller.setIsWeekdaysSelected( - !controller.isWeekdaysSelected.value); + !controller.isWeekdaysSelected.value, + ); // Update repeatDays based on isWeekdaysSelected value for (int i = 0; i < controller.repeatDays.length; i++) { @@ -453,4 +436,4 @@ class RepeatTile extends StatelessWidget { ), ); } -} +} \ No newline at end of file diff --git a/lib/app/modules/addOrUpdateAlarm/views/weather_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/weather_tile.dart index 54bd7625..3a41ddd4 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/weather_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/weather_tile.dart @@ -460,71 +460,80 @@ class WeatherTile extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - width: width * 0.4, - child: TextButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - kprimaryColor, + Expanded( + flex: 2, + child: SizedBox( + width: width * 0.4, + child: TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all( + kprimaryColor, + ), ), - ), - child: FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: Text( - 'Go to settings'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController - .isLightMode.value - ? kLightPrimaryTextColor - : ksecondaryTextColor, - ), + child: FittedBox( + fit: BoxFit.scaleDown, + alignment: Alignment.centerLeft, + child: Text( + 'Go to settings'.tr, + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + color: themeController + .isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), ), + onPressed: () { + Utils.hapticFeedback(); + Get.back(); + Get.toNamed('/settings'); + }, ), - onPressed: () { - Utils.hapticFeedback(); - Get.back(); - Get.toNamed('/settings'); - }, ), ), SizedBox( width: width * 0.05, ), - SizedBox( - width: width * 0.3, - child: TextButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - themeController.isLightMode.value - ? kLightPrimaryTextColor - .withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5), + Expanded( + flex: 1, + child: SizedBox( + width: width * 0.3, + child: TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all( + themeController.isLightMode.value + ? kLightPrimaryTextColor + .withOpacity(0.5) + : kprimaryTextColor. + withOpacity(0.5), + ), ), - ), - child: FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: Text( - 'Cancel'.tr, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController - .isLightMode.value - ? kLightPrimaryTextColor - : kprimaryTextColor, - ), + child: FittedBox( + fit: BoxFit.scaleDown, + alignment: Alignment.centerLeft, + child: Text( + 'Cancel'.tr, + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + color: themeController + .isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + ), + ), ), + onPressed: () { + Utils.hapticFeedback(); + Get.back(); + }, ), - onPressed: () { - Utils.hapticFeedback(); - Get.back(); - }, ), ), ], diff --git a/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart b/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart index cad0f28b..741f3256 100644 --- a/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart +++ b/lib/app/modules/alarmChallenge/controllers/alarm_challenge_controller.dart @@ -106,7 +106,7 @@ class AlarmChallengeController extends GetxController { ); final result = similarity; - Get.log('${result}'); + // Get.log('${result}'); return result; } diff --git a/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart b/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart index c556fe5e..23c96171 100644 --- a/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart +++ b/lib/app/modules/alarmRing/controllers/alarm_ring_controller.dart @@ -66,6 +66,10 @@ class AlarmControlController extends GetxController { return latestAlarm; } + void addMinutes(int incrementMinutes) { + minutes.value += incrementMinutes; + } + void startSnooze() async { Vibration.cancel(); vibrationTimer!.cancel(); diff --git a/lib/app/modules/alarmRing/views/alarm_ring_view.dart b/lib/app/modules/alarmRing/views/alarm_ring_view.dart index 2515111a..e37b76ea 100644 --- a/lib/app/modules/alarmRing/views/alarm_ring_view.dart +++ b/lib/app/modules/alarmRing/views/alarm_ring_view.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; @@ -12,6 +13,32 @@ class AlarmControlView extends GetView { final ThemeController themeController = Get.find(); + TextButton getAddSnoozeButtons( + BuildContext context, int snoozeMinutes, String title) { + return TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + ), + ), + child: Text( + title.tr, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor, + fontWeight: FontWeight.w600, + ), + ), + onPressed: () { + Utils.hapticFeedback(); + controller.addMinutes(snoozeMinutes); + }, + ); + } + @override Widget build(BuildContext context) { var width = Get.width; @@ -79,7 +106,7 @@ class AlarmControlView extends GetView { Get.offNamed( '/bottom-navigation-bar', arguments: controller.currentlyRingingAlarm - .value.showMotivationalQuote, + .value, ); } }, @@ -152,6 +179,23 @@ class AlarmControlView extends GetView { .displayLarge! .copyWith(fontSize: 50), ), + const SizedBox( + height: 20, + width: 0, + ), + Obx( + () => Visibility( + visible: controller.isSnoozing.value, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + getAddSnoozeButtons(context, 1, '+1 min'), + getAddSnoozeButtons(context, 2, '+2 min'), + getAddSnoozeButtons(context, 5, '+5 min'), + ], + ), + ), + ), ], ), ), diff --git a/lib/app/modules/bottomNavigationBar/bindings/bottom_navigation_bar_binding.dart b/lib/app/modules/bottomNavigationBar/bindings/bottom_navigation_bar_binding.dart index de7180ef..449db2f4 100644 --- a/lib/app/modules/bottomNavigationBar/bindings/bottom_navigation_bar_binding.dart +++ b/lib/app/modules/bottomNavigationBar/bindings/bottom_navigation_bar_binding.dart @@ -1,4 +1,5 @@ import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/controllers/add_or_update_alarm_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/home/controllers/home_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/settings_controller.dart'; @@ -19,5 +20,6 @@ class BottomNavigationBarBinding extends Bindings { ); Get.lazyPut(() => SettingsController(), fenix: true); Get.lazyPut(() => HomeController()); + Get.lazyPut(() => AddOrUpdateAlarmController()); } } diff --git a/lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart b/lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart index a17c8ac5..4a8815db 100644 --- a/lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart +++ b/lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart @@ -10,6 +10,7 @@ class BottomNavigationBarController extends GetxController with WidgetsBindingObserver { RxInt activeTabIndex = 0.obs; RxBool isTimerRunning = false.obs; + RxBool hasloaded = false.obs; final _secureStorageProvider = SecureStorageProvider(); @@ -25,7 +26,7 @@ class BottomNavigationBarController extends GetxController void onInit() { super.onInit(); WidgetsBinding.instance.addObserver(this); - _loadSavedState(); + loadSavedState(); } @override @@ -34,18 +35,10 @@ class BottomNavigationBarController extends GetxController super.onClose(); } - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - super.didChangeAppLifecycleState(state); - - if (state == AppLifecycleState.inactive || - state == AppLifecycleState.paused) { - _saveState(); - } - } - - void _loadSavedState() async { - activeTabIndex.value = await _secureStorageProvider.readTabIndex(); + Future loadSavedState() async { + int value = await _secureStorageProvider.readTabIndex(); + activeTabIndex.value = value; + hasloaded.value = true; } void _saveState() async { @@ -56,6 +49,7 @@ class BottomNavigationBarController extends GetxController void changeTab(int index) { activeTabIndex.value = index; + _saveState(); if (index == 0 && (timerController.isTimerRunning.value || isTimerRunning.value)) { diff --git a/lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart b/lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart index 9e863b9d..63fda0b7 100644 --- a/lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart +++ b/lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart @@ -1,48 +1,79 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:ultimate_alarm_clock/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.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'; class BottomNavigationBarView extends GetView { - final PageController pageController = PageController(); + PageController pageController = PageController(); + final ThemeController themeController = Get.find(); + BottomNavigationBarView({super.key}); @override Widget build(BuildContext context) { return Scaffold( - body: PageView( - controller: pageController, - children: controller.pages, - onPageChanged: (index) { - controller.changeTab(index); - }, - ), + body: Obx(() { + return FutureBuilder( + future: controller.loadSavedState(), + builder: (context, snapshot) { + if (controller.hasloaded.value != false) { + pageController = + PageController(initialPage: controller.activeTabIndex.value); + return PageView( + controller: pageController, + children: controller.pages, + onPageChanged: (index) { + controller.changeTab(index); + }, + ); + } else { + return const Center( + child: CircularProgressIndicator.adaptive( + backgroundColor: Colors.transparent, + valueColor: AlwaysStoppedAnimation( + kprimaryColor, + ), + ), + ); + } + }, + ); + }), bottomNavigationBar: Obx( () => BottomNavigationBar( useLegacyColorScheme: false, items: [ BottomNavigationBarItem( - icon: Icon(Icons.alarm), + icon: const Icon(Icons.alarm), label: 'Alarm'.tr, ), BottomNavigationBarItem( - icon: Icon(Icons.timer_outlined), + icon: const Icon(Icons.timer_outlined), label: 'StopWatch'.tr, ), BottomNavigationBarItem( - icon: Icon(Icons.timelapse_outlined), + icon: const Icon(Icons.timelapse_outlined), label: 'Timer'.tr, ), ], onTap: (index) { Utils.hapticFeedback(); controller.changeTab(index); - pageController.animateToPage(index, - duration: Duration(milliseconds: 300), curve: Curves.easeInOut); + pageController.jumpToPage( + index, + ); }, currentIndex: controller.activeTabIndex.value, + selectedLabelStyle: TextStyle( + color: kprimaryColor, + fontSize: 14, + decorationColor: + themeController.isLightMode.value ? Colors.black : Colors.white, + decorationThickness: 0.8, + ), ), ), ); } } - diff --git a/lib/app/modules/home/controllers/home_controller.dart b/lib/app/modules/home/controllers/home_controller.dart index aaa1ef2b..48539b48 100644 --- a/lib/app/modules/home/controllers/home_controller.dart +++ b/lib/app/modules/home/controllers/home_controller.dart @@ -27,6 +27,7 @@ class Pair { } class HomeController extends GetxController { + MethodChannel alarmChannel = const MethodChannel('ulticlock'); Stream? firestoreStreamAlarms; Stream? sharedAlarmsStream; @@ -64,6 +65,9 @@ class HomeController extends GetxController { Set> selectedAlarmSet = {}; + final RxInt duration = 3.obs; + final RxDouble selecteddurationDouble = 0.0.obs; + ThemeController themeController = Get.find(); loginWithGoogle() async { @@ -232,7 +236,7 @@ class HomeController extends GetxController { }); if (Get.arguments != null) { - bool showMotivationalQuote = Get.arguments; + bool showMotivationalQuote = Get.arguments.showMotivationalQuote; if (showMotivationalQuote) { Quote quote = Utils.getRandomQuote(); @@ -553,9 +557,9 @@ class HomeController extends GetxController { } Get.snackbar( - 'Alarm deleted'.tr, - 'The alarm has been deleted'.tr, - duration: const Duration(seconds: 4), + 'Alarm deleted', + 'The alarm has been deleted.', + duration: Duration(seconds: duration.toInt()), snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.symmetric( horizontal: 10, diff --git a/lib/app/modules/home/views/home_view.dart b/lib/app/modules/home/views/home_view.dart index d8b83cd6..5ace9bcb 100644 --- a/lib/app/modules/home/views/home_view.dart +++ b/lib/app/modules/home/views/home_view.dart @@ -515,7 +515,7 @@ class HomeView extends GetView { ), Container( padding: EdgeInsets.symmetric( - horizontal: 4 * + horizontal: 2 * controller .scalingFactor.value, ), @@ -673,345 +673,336 @@ class HomeView extends GetView { ), ], - body: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Expanded( - child: GlowingOverscrollIndicator( - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - axisDirection: AxisDirection.down, - child: Obx(() { - return FutureBuilder( - future: controller.isUserSignedIn.value - ? controller.initStream(controller.userModel.value) - : controller.initStream(controller.userModel.value), - builder: (context, AsyncSnapshot snapshot) { - if (snapshot.hasData) { - final Stream streamAlarms = snapshot.data; - - return StreamBuilder( - stream: streamAlarms, - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const Center( - child: CircularProgressIndicator.adaptive( - backgroundColor: Colors.transparent, - valueColor: AlwaysStoppedAnimation( - kprimaryColor, - ), - ), - ); - } else { - List alarms = snapshot.data; + body: RefreshIndicator( + onRefresh: () async { + refresh(context); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + child: GlowingOverscrollIndicator( + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + axisDirection: AxisDirection.down, + child: Obx(() { + return FutureBuilder( + future: controller.isUserSignedIn.value + ? controller + .initStream(controller.userModel.value) + : controller + .initStream(controller.userModel.value), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.hasData) { + final Stream streamAlarms = snapshot.data; - alarms = alarms - .where((alarm) => !alarm.isTimer) - .toList(); - controller.refreshTimer = true; - controller.refreshUpcomingAlarms(); - if (alarms.isEmpty) { - return Center( - child: Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - children: [ - SvgPicture.asset( - 'assets/images/empty.svg', - height: height * 0.3, - width: width * 0.8, - ), - Text( - 'Add an alarm to get started!'.tr, - textWidthBasis: - TextWidthBasis.longestLine, - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - color: themeController - .isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - ], + return StreamBuilder( + stream: streamAlarms, + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const Center( + child: CircularProgressIndicator.adaptive( + backgroundColor: Colors.transparent, + valueColor: AlwaysStoppedAnimation( + kprimaryColor, + ), ), ); - } - return ListView.separated( - separatorBuilder: (context, _) { - return SizedBox( - height: height * 0.02, + } else { + List alarms = snapshot.data; + + alarms = alarms + .where((alarm) => !alarm.isTimer) + .toList(); + controller.refreshTimer = true; + controller.refreshUpcomingAlarms(); + if (alarms.isEmpty) { + return Center( + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + 'assets/images/empty.svg', + height: height * 0.3, + width: width * 0.8, + ), + Text( + 'Add an alarm to get started!'.tr, + textWidthBasis: + TextWidthBasis.longestLine, + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + ], + ), ); - }, - itemCount: alarms.length + 1, - itemBuilder: (context, index) { - // Spacing after last card - if (index == alarms.length) { + } + return ListView.separated( + separatorBuilder: (context, _) { return SizedBox( - height: height * 0.1, + height: height * 0.02, ); - } - final AlarmModel alarm = alarms[index]; - - final repeatDays = - Utils.getRepeatDays(alarm.days); - // Main card - return Dismissible( - direction: DismissDirection.startToEnd, - onDismissed: (direction) async { - await controller.swipeToDeleteAlarm( - controller.userModel.value, - alarm, + }, + itemCount: alarms.length + 1, + itemBuilder: (context, index) { + // Spacing after last card + if (index == alarms.length) { + return SizedBox( + height: height * 0.1, ); - }, - key: ValueKey(alarms[index]), - background: Container( - color: Colors - .red, // Set the background color to red - padding: const EdgeInsets.symmetric( - horizontal: 20, - ), - alignment: Alignment.center, - child: const Icon( - Icons.delete, - color: Colors.white, - ), - ), - child: Obx( - () => GestureDetector( - onTap: () { - Utils.hapticFeedback(); - - // If multiple select mode is not on, then only you can update the alarm - if (!controller - .inMultipleSelectMode.value) { - Get.toNamed( - '/add-update-alarm', - arguments: alarm, + } + final AlarmModel alarm = alarms[index]; + final repeatDays = + Utils.getRepeatDays(alarm.days); + // Main card + return Dismissible( + onDismissed: (direction) async { + // pop up confirmation to delete on swipe + bool userConfirmed = + await showDeleteAlarmConfirmationPopupOnSwipe( + context, + ); + if (userConfirmed) { + if (alarm.isSharedAlarmEnabled == + true) { + await FirestoreDb.deleteAlarm( + controller.userModel.value, + alarm.firestoreId!, + ); + } else { + await IsarDb.deleteAlarm( + alarm.isarId, ); } - }, - onLongPress: () { - // Entering the multiple select mode - controller.inMultipleSelectMode - .value = true; - controller.isAnyAlarmHolded - .value = true; - - // Assigning the alarm list pairs to list of alarms and list of isSelected all equal to false initially - controller.alarmListPairs = Pair( - alarms, - List.generate( - alarms.length, - (index) => false.obs, - ), + } else { + // do not delete on dismiss + Get.offNamedUntil( + '/bottom-navigation-bar', + (route) => + route.settings.name == + '/splash-screen', ); + } + }, + key: ValueKey(alarms[index]), + background: Container( + color: Colors + .red, // Set the background color to red + padding: EdgeInsets.symmetric( + horizontal: 20, + ), + alignment: Alignment.center, + child: Icon( + Icons.delete, + color: Colors.white, + ), + ), + child: Obx( + () => GestureDetector( + onTap: () { + Utils.hapticFeedback(); - Utils.hapticFeedback(); - }, - onLongPressEnd: (details) { - controller.isAnyAlarmHolded - .value = false; - }, - child: AnimatedContainer( - duration: const Duration( - milliseconds: 600, - ), - curve: Curves.easeInOut, - margin: EdgeInsets.all( - controller - .isAnyAlarmHolded.value - ? 10 - : 0, - ), - child: Center( - child: Padding( - padding: const EdgeInsets - .symmetric( - horizontal: 10.0, + // If multiple select mode is not on, then only you can update the alarm + if (!controller + .inMultipleSelectMode + .value) { + Get.toNamed( + '/add-update-alarm', + arguments: alarm, + ); + } + }, + onLongPress: () { + // Entering the multiple select mode + controller.inMultipleSelectMode + .value = true; + controller.isAnyAlarmHolded + .value = true; + + // Assigning the alarm list pairs to list of alarms and list of isSelected all equal to false initially + controller.alarmListPairs = + Pair( + alarms, + List.generate( + alarms.length, + (index) => false.obs, ), - child: Card( - color: themeController - .isLightMode.value - ? kLightSecondaryBackgroundColor - : ksecondaryBackgroundColor, - shape: - RoundedRectangleBorder( - borderRadius: - BorderRadius.circular( - 18, - ), + ); + + Utils.hapticFeedback(); + }, + onLongPressEnd: (details) { + controller.isAnyAlarmHolded + .value = false; + }, + child: AnimatedContainer( + duration: const Duration( + milliseconds: 600, + ), + curve: Curves.easeInOut, + margin: EdgeInsets.all( + controller.isAnyAlarmHolded + .value + ? 10 + : 0, + ), + child: Center( + child: Padding( + padding: const EdgeInsets + .symmetric( + horizontal: 10.0, ), - child: Center( - child: Padding( - padding: - EdgeInsets.only( - left: 25.0, - right: controller - .inMultipleSelectMode - .value - ? 10.0 - : 0.0, - top: controller - .inMultipleSelectMode - .value - ? Utils.isChallengeEnabled( - alarm, - ) || - Utils.isAutoDismissalEnabled( - alarm, - ) - ? 15.0 - : 18.0 - : Utils.isChallengeEnabled( - alarm, - ) || - Utils.isAutoDismissalEnabled( - alarm, - ) - ? 8.0 - : 0.0, - bottom: controller - .inMultipleSelectMode - .value - ? Utils.isChallengeEnabled( - alarm, - ) || - Utils.isAutoDismissalEnabled( - alarm, - ) - ? 15.0 - : 18.0 - : Utils.isChallengeEnabled( - alarm, - ) || - Utils.isAutoDismissalEnabled( - alarm, - ) - ? 8.0 - : 0.0, + child: Card( + color: themeController + .isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + shape: + RoundedRectangleBorder( + borderRadius: + BorderRadius + .circular( + 18, ), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .start, - children: [ - Expanded( - flex: 3, - child: Column( - mainAxisAlignment: - MainAxisAlignment - .center, - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - IntrinsicHeight( - child: Row( - children: [ - Text( - repeatDays - .replaceAll( - 'Never'.tr, - 'One Time'.tr, - ), - style: Theme.of(context) - .textTheme - .bodySmall! - .copyWith( - fontWeight: FontWeight.w500, - color: alarm.isEnabled == true - ? kprimaryColor - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - if (alarm - .label - .isNotEmpty) - VerticalDivider( - color: alarm.isEnabled == true - ? kprimaryColor - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - thickness: - 1.4, - width: - 6, - indent: - 3.1, - endIndent: - 3.1, - ), - Expanded( - child: - Container( - child: - Text( - alarm.label, - overflow: TextOverflow.ellipsis, - // Set overflow property here - style: Theme.of(context).textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.w500, - color: alarm.isEnabled == true - ? kprimaryColor - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), + ), + child: Center( + child: Padding( + padding: + EdgeInsets.only( + left: 25.0, + right: controller + .inMultipleSelectMode + .value + ? 10.0 + : 0.0, + top: controller + .inMultipleSelectMode + .value + ? Utils.isChallengeEnabled( + alarm, + ) || + Utils.isAutoDismissalEnabled( + alarm, + ) + ? 15.0 + : 18.0 + : Utils.isChallengeEnabled( + alarm, + ) || + Utils.isAutoDismissalEnabled( + alarm, + ) + ? 8.0 + : 0.0, + bottom: controller + .inMultipleSelectMode + .value + ? Utils.isChallengeEnabled( + alarm, + ) || + Utils.isAutoDismissalEnabled( + alarm, + ) + ? 15.0 + : 18.0 + : Utils.isChallengeEnabled( + alarm, + ) || + Utils.isAutoDismissalEnabled( + alarm, + ) + ? 8.0 + : 0.0, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .start, + children: [ + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: + MainAxisAlignment + .center, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + IntrinsicHeight( + child: + Row( + children: [ + Text( + repeatDays.replaceAll( + 'Never'.tr, + 'One Time'.tr, ), + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w500, + color: alarm.isEnabled == true + ? kprimaryColor + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - ), - ], - ), - ), - Row( - children: [ - Text( - (settingsController.is24HrsEnabled.value - ? Utils.split24HourFormat(alarm.alarmTime) - : Utils.convertTo12HourFormat( - alarm.alarmTime, - ))[0], - style: Theme - .of( - context, - ) - .textTheme - .displayLarge! - .copyWith( + if (alarm + .label + .isNotEmpty) + VerticalDivider( color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor - : kprimaryTextColor + ? kprimaryColor : themeController.isLightMode.value ? kLightPrimaryDisabledTextColor : kprimaryDisabledTextColor, + thickness: 1.4, + width: 6, + indent: 3.1, + endIndent: 3.1, ), + Expanded( + child: + Container( + child: Text( + alarm.label, + overflow: TextOverflow.ellipsis, + // Set overflow property here + style: Theme.of(context).textTheme.bodySmall!.copyWith( + fontWeight: FontWeight.w500, + color: alarm.isEnabled == true + ? kprimaryColor + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + ), + ), + ], ), - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: - 3.0, - ), - child: - Text( + ), + Row( + children: [ + Text( (settingsController.is24HrsEnabled.value ? Utils.split24HourFormat(alarm.alarmTime) : Utils.convertTo12HourFormat( alarm.alarmTime, - ))[1], - style: Theme.of(context) - .textTheme - .displayMedium! - .copyWith( + ))[0], + style: Theme.of( + context, + ).textTheme.displayLarge!.copyWith( color: alarm.isEnabled == true ? themeController.isLightMode.value ? kLightPrimaryTextColor @@ -1021,368 +1012,363 @@ class HomeView extends GetView { : kprimaryDisabledTextColor, ), ), - ), - ], - ), - if (Utils - .isChallengeEnabled( - alarm, - ) || - Utils - .isAutoDismissalEnabled( - alarm, - ) || - alarm - .isSharedAlarmEnabled) - Row( - mainAxisAlignment: - MainAxisAlignment - .start, - children: [ - if (alarm - .isSharedAlarmEnabled) - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 3.0, - ), - child: - Icon( - Icons.share_arrival_time, - size: 24, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5) - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), + Padding( + padding: + const EdgeInsets.symmetric( + horizontal: + 3.0, ), - if (alarm - .isLocationEnabled) - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 3.0, - ), - child: - Icon( - Icons.location_pin, - size: 24, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5) - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), + child: + Text( + (settingsController.is24HrsEnabled.value + ? Utils.split24HourFormat(alarm.alarmTime) + : Utils.convertTo12HourFormat( + alarm.alarmTime, + ))[1], + style: Theme.of(context).textTheme.displayMedium!.copyWith( + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - if (alarm - .isActivityEnabled) - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 3.0, - ), - child: - Icon( - Icons.screen_lock_portrait, - size: 24, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5) - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + ), + ], + ), + if (Utils + .isChallengeEnabled( + alarm, + ) || + Utils + .isAutoDismissalEnabled( + alarm, + ) || + alarm + .isSharedAlarmEnabled) + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + if (alarm + .isSharedAlarmEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.share_arrival_time, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - ), - if (alarm - .isWeatherEnabled) - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 3.0, + if (alarm + .isLocationEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.location_pin, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - child: - Icon( - Icons.cloudy_snowing, - size: 24, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5) - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + if (alarm + .isActivityEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.screen_lock_portrait, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - ), - if (alarm - .isQrEnabled) - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 3.0, + if (alarm + .isWeatherEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.cloudy_snowing, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - child: - Icon( - Icons.qr_code_scanner, - size: 24, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5) - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + if (alarm + .isQrEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.qr_code_scanner, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - ), - if (alarm - .isShakeEnabled) - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 3.0, + if (alarm + .isShakeEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.vibration, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - child: - Icon( - Icons.vibration, - size: 24, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5) - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + if (alarm + .isMathsEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.calculate, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - ), - if (alarm - .isMathsEnabled) - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 3.0, + if (alarm + .isPedometerEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.directions_walk, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), + ], + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets + .symmetric( + horizontal: + 10.0, + ), + child: controller + .inMultipleSelectMode + .value + ? Column( + // Showing the toggle button + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + flex: + 0, child: - Icon( - Icons.calculate, - size: 24, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5) - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + ToggleButton( + controller: controller, + alarmIndex: index, ), ), - if (alarm - .isPedometerEnabled) - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 3.0, - ), + ], + ) + : Column( + // Showing the switch and pop up menu button + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + flex: + 0, child: - Icon( - Icons.directions_walk, - size: 24, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor.withOpacity(0.5) - : kprimaryTextColor.withOpacity(0.5) - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + Switch.adaptive( + activeColor: ksecondaryColor, + value: alarm.isEnabled, + onChanged: (bool value) async { + Utils.hapticFeedback(); + alarm.isEnabled = value; + if (alarm.isSharedAlarmEnabled == true) { + await FirestoreDb.updateAlarm(alarm.ownerId, alarm); + } else { + await IsarDb.updateAlarm(alarm); + } + controller.refreshTimer = true; + controller.refreshUpcomingAlarms(); + }, ), ), - ], - ), - ], - ), - ), - Padding( - padding: - const EdgeInsets - .symmetric( - horizontal: - 10.0, - ), - child: controller - .inMultipleSelectMode - .value - ? Column( - // Showing the toggle button - mainAxisAlignment: - MainAxisAlignment - .center, - children: [ - Expanded( - flex: - 0, - child: - ToggleButton( - controller: - controller, - alarmIndex: - index, - ), - ), - ], - ) - : Column( - // Showing the switch and pop up menu button - mainAxisAlignment: - MainAxisAlignment - .center, - children: [ - Expanded( - flex: - 0, - child: - Switch.adaptive( - activeColor: - ksecondaryColor, - value: - alarm.isEnabled, - onChanged: - (bool value) async { - Utils.hapticFeedback(); - alarm.isEnabled = value; - if (alarm.isSharedAlarmEnabled == true) { - await FirestoreDb.updateAlarm(alarm.ownerId, alarm); - } else { - await IsarDb.updateAlarm(alarm); - } - controller.refreshTimer = true; - controller.refreshUpcomingAlarms(); - }, - ), - ), - Expanded( - flex: - 0, - child: - PopupMenuButton( - onSelected: - (value) async { - Utils.hapticFeedback(); - if (value == 0) { - Get.back(); - Get.offNamed('/alarm-ring', arguments: alarm); - } else if (value == 1) { - debugPrint(alarm.isSharedAlarmEnabled.toString()); + Expanded( + flex: + 0, + child: + PopupMenuButton( + onSelected: (value) async { + Utils.hapticFeedback(); + if (value == 0) { + Get.back(); + Get.offNamed('/alarm-ring', arguments: alarm); + } else if (value == 1) { + debugPrint(alarm.isSharedAlarmEnabled.toString()); - if (alarm.isSharedAlarmEnabled == true) { - await FirestoreDb.deleteAlarm(controller.userModel.value, alarm.firestoreId!); - } else { - if (await File(alarm.imageurl).exists()) { - // Get the temporary directory + if (alarm.isSharedAlarmEnabled == true) { + await FirestoreDb.deleteAlarm(controller.userModel.value, alarm.firestoreId!); + } else { + if (await File(alarm.imageurl).exists()) { + // Get the temporary directory - Directory tempDir = await getTemporaryDirectory(); + Directory tempDir = await getTemporaryDirectory(); - // Generate a unique filename for the temporary copy - String tempFileName = '${DateTime.now().millisecondsSinceEpoch}.jpg'; + // Generate a unique filename for the temporary copy + String tempFileName = '${DateTime.now().millisecondsSinceEpoch}.jpg'; - // Create a temporary file path - String tempFilePath = '${tempDir.path}/$tempFileName'; - // Copy the content of the original file to the temporary file - await File(alarm.imageurl).copy(tempFilePath); - // Store the temporary file path in the map - String alarmid = alarm.alarmID; - controller.deletedAlarmsMap[alarmid] = tempFilePath; - await controller.deleteFileIfExists(alarm.imageurl); - } + // Create a temporary file path + String tempFilePath = '${tempDir.path}/$tempFileName'; + // Copy the content of the original file to the temporary file + await File(alarm.imageurl).copy(tempFilePath); + // Store the temporary file path in the map + String alarmid = alarm.alarmID; + controller.deletedAlarmsMap[alarmid] = tempFilePath; + await controller.deleteFileIfExists(alarm.imageurl); + } - await IsarDb.deleteAlarm(alarm.isarId); - } + await IsarDb.deleteAlarm(alarm.isarId); + } - if (Get.isSnackbarOpen) { - Get.closeAllSnackbars(); - } + if (Get.isSnackbarOpen) { + Get.closeAllSnackbars(); + } - Get.snackbar( - 'Alarm deleted', - 'The alarm has been deleted.', - duration: const Duration(seconds: 4), - snackPosition: SnackPosition.BOTTOM, - margin: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 15, - ), - mainButton: TextButton( - onPressed: () async { - if (alarm.isSharedAlarmEnabled == true) { - await FirestoreDb.addAlarm(controller.userModel.value, alarm); - } else { - if (controller.deletedAlarmsMap[alarm.alarmID] != null && await File(controller.deletedAlarmsMap[alarm.alarmID]!).exists()) { - await File(controller.deletedAlarmsMap[alarm.alarmID]!).copy(alarm.imageurl); - // Remove the alarm from the temporary storage - controller.deletedAlarmsMap.remove(alarm.alarmID); + Get.snackbar( + 'Alarm deleted', + 'The alarm has been deleted.', + duration: const Duration(seconds: 4), + snackPosition: SnackPosition.BOTTOM, + margin: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 15, + ), + mainButton: TextButton( + onPressed: () async { + if (alarm.isSharedAlarmEnabled == true) { + await FirestoreDb.addAlarm(controller.userModel.value, alarm); + } else { + if (controller.deletedAlarmsMap[alarm.alarmID] != null && await File(controller.deletedAlarmsMap[alarm.alarmID]!).exists()) { + await File(controller.deletedAlarmsMap[alarm.alarmID]!).copy(alarm.imageurl); + // Remove the alarm from the temporary storage + controller.deletedAlarmsMap.remove(alarm.alarmID); + } + await IsarDb.addAlarm(alarm); } - await IsarDb.addAlarm(alarm); - } - }, - child: const Text('Undo'), - ), - ); + }, + child: const Text('Undo'), + ), + ); - String ringtoneName = alarm.ringtoneName; + String ringtoneName = alarm.ringtoneName; - await AudioUtils.updateRingtoneCounterOfUsage( - customRingtoneName: ringtoneName, - counterUpdate: CounterUpdate.decrement, - ); + await AudioUtils.updateRingtoneCounterOfUsage( + customRingtoneName: ringtoneName, + counterUpdate: CounterUpdate.decrement, + ); - controller.refreshTimer = true; - controller.refreshUpcomingAlarms(); - } - }, - color: themeController.isLightMode.value - ? kLightPrimaryBackgroundColor - : kprimaryBackgroundColor, - icon: - Icon( - Icons.more_vert, - color: alarm.isEnabled == true - ? themeController.isLightMode.value - ? kLightPrimaryTextColor - : kprimaryTextColor - : themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - itemBuilder: - (context) { - return [ - PopupMenuItem( - value: 0, - child: Text( - 'Preview Alarm'.tr, - style: Theme.of(context).textTheme.bodyMedium, - ), - ), - if (alarm.isSharedAlarmEnabled == false || (alarm.isSharedAlarmEnabled == true && alarm.ownerId == controller.userModel.value!.id)) + controller.refreshTimer = true; + controller.refreshUpcomingAlarms(); + } + }, + color: themeController.isLightMode.value ? kLightPrimaryBackgroundColor : kprimaryBackgroundColor, + icon: Icon( + Icons.more_vert, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor + : kprimaryTextColor + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + itemBuilder: (context) { + return [ PopupMenuItem( - value: 1, + value: 0, child: Text( - 'Delete Alarm'.tr, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Colors.red, - ), + 'Preview Alarm'.tr, + style: Theme.of(context).textTheme.bodyMedium, ), ), - ]; - }, + if (alarm.isSharedAlarmEnabled == false || (alarm.isSharedAlarmEnabled == true && alarm.ownerId == controller.userModel.value!.id)) + PopupMenuItem( + value: 1, + child: Text( + 'Delete Alarm'.tr, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Colors.red, + ), + ), + ), + ]; + }, + ), ), - ), - ], - ), - ), - ], + ], + ), + ), + ], + ), ), ), ), @@ -1391,31 +1377,106 @@ class HomeView extends GetView { ), ), ), - ), - ); - }, - ); - } - }, - ); - } else { - return const CircularProgressIndicator.adaptive( - backgroundColor: Colors.transparent, - valueColor: AlwaysStoppedAnimation( - kprimaryColor, - ), - ); - } - }, - ); - }), + ); + }, + ); + } + }, + ); + } else { + return const CircularProgressIndicator.adaptive( + backgroundColor: Colors.transparent, + valueColor: AlwaysStoppedAnimation( + kprimaryColor, + ), + ); + } + }, + ); + }), + ), + ), + ], + ), + ), + ), + ), + ), + ); + } + + Future showDeleteAlarmConfirmationPopupOnSwipe( + BuildContext context, + ) async { + // Return true if user confirms deletion, false if canceled + + var result = await Get.defaultDialog( + titlePadding: const EdgeInsets.symmetric( + vertical: 20, + ), + backgroundColor: themeController.isLightMode.value + ? kLightSecondaryBackgroundColor + : ksecondaryBackgroundColor, + title: 'Confirmation'.tr, + titleStyle: Theme.of(context).textTheme.displaySmall, + content: Column( + children: [ + Text( + 'want to delete?'.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(result: false); + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(kprimaryColor), + ), + child: Text( + 'No'.tr, + style: Theme.of(context).textTheme.displaySmall!.copyWith( + color: kprimaryBackgroundColor, + ), + ), + ), + TextButton( + onPressed: () { + Get.back(result: true); // User confirmed + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(kprimaryColor), + ), + child: Text( + 'Yes'.tr, + style: Theme.of(context).textTheme.displaySmall!.copyWith( + color: kprimaryBackgroundColor, + ), ), ), ], ), ), - ), + ], ), ); + + return result ?? + false; // Default to false if the user dismisses the dialog without tapping any button + } + + void refresh(BuildContext context) async { + await Get.offNamedUntil( + '/bottom-navigation-bar', + (route) => route.settings.name == '/splash-screen', + ); + await Future.delayed(const Duration(seconds: 3)); } } diff --git a/lib/app/modules/settings/views/settings_view.dart b/lib/app/modules/settings/views/settings_view.dart index 20eb31c8..2dbc1704 100644 --- a/lib/app/modules/settings/views/settings_view.dart +++ b/lib/app/modules/settings/views/settings_view.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:ultimate_alarm_clock/app/modules/home/controllers/home_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; +import 'package:ultimate_alarm_clock/app/modules/settings/views/customize_undo_duration.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/views/enable_24Hour_format.dart'; @@ -110,6 +111,14 @@ class SettingsView extends GetView { const SizedBox( height: 20, ), + CustomizeUndoDuration( + width: width, + height: height, + themeController: controller.themeController + ), + const SizedBox( + height: 20, + ), LanguageMenu( controller: controller, height: height, diff --git a/lib/app/modules/settings/views/weather_api.dart b/lib/app/modules/settings/views/weather_api.dart index af44c5ac..43b290a9 100644 --- a/lib/app/modules/settings/views/weather_api.dart +++ b/lib/app/modules/settings/views/weather_api.dart @@ -110,7 +110,9 @@ class WeatherApi extends StatelessWidget { .value = true; // Validation If String is empty - if (controller.apiKey.text.isEmpty) { + if (controller.apiKey.text + .trim() + .isEmpty) { // setState(() { controller.isApiKeyEmpty.value = true; @@ -122,8 +124,9 @@ class WeatherApi extends StatelessWidget { } // Reset state after getting error message - if (controller - .apiKey.text.isNotEmpty) { + if (controller.apiKey.text + .trim() + .isNotEmpty) { // setState(() { controller.isApiKeyEmpty.value = false; diff --git a/lib/app/modules/timer/bindings/timer_binding.dart b/lib/app/modules/timer/bindings/timer_binding.dart index 603d88b0..541d2dd8 100644 --- a/lib/app/modules/timer/bindings/timer_binding.dart +++ b/lib/app/modules/timer/bindings/timer_binding.dart @@ -1,4 +1,6 @@ import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/controllers/add_or_update_alarm_controller.dart'; +import 'package:ultimate_alarm_clock/app/modules/addOrUpdateAlarm/controllers/input_time_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/home/controllers/home_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/settings_controller.dart'; diff --git a/lib/app/modules/timer/controllers/timer_controller.dart b/lib/app/modules/timer/controllers/timer_controller.dart index 25fcd1a5..574b45bd 100644 --- a/lib/app/modules/timer/controllers/timer_controller.dart +++ b/lib/app/modules/timer/controllers/timer_controller.dart @@ -18,7 +18,7 @@ class TimerController extends GetxController with WidgetsBindingObserver { Rx countdownTimer = Rx(null); AlarmModel alarmRecord = Utils.genFakeAlarmModel(); late int currentTimerIsarId; - var hours=0.obs, minutes=1.obs, seconds=0.obs; + var hours = 0.obs, minutes = 1.obs, seconds = 0.obs; final _secureStorageProvider = SecureStorageProvider(); @@ -37,15 +37,6 @@ class TimerController extends GetxController with WidgetsBindingObserver { super.onClose(); } - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - super.didChangeAppLifecycleState(state); - - if (state == AppLifecycleState.resumed) { - loadTimerStateFromStorage(); - } - } - void saveTimerStateToStorage() async { await _secureStorageProvider.writeRemainingTimeInSeconds( remainingTimeInSeconds: remainingTime.value.inSeconds, diff --git a/lib/app/modules/timer/views/timer_view.dart b/lib/app/modules/timer/views/timer_view.dart index 065dd95c..d51a81ea 100644 --- a/lib/app/modules/timer/views/timer_view.dart +++ b/lib/app/modules/timer/views/timer_view.dart @@ -1,8 +1,10 @@ +import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:numberpicker/numberpicker.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/modules/addOrUpdateAlarm/controllers/input_time_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; import 'package:ultimate_alarm_clock/app/modules/timer/controllers/timer_controller.dart'; import 'package:ultimate_alarm_clock/app/routes/app_pages.dart'; @@ -14,6 +16,7 @@ class TimerView extends GetView { TimerView({Key? key}) : super(key: key); ThemeController themeController = Get.find(); + InputTimeController inputTimeController = Get.put(InputTimeController()); @override Widget build(BuildContext context) { @@ -51,10 +54,9 @@ class TimerView extends GetView { body: Obx( () => controller.isTimerRunning.value ? Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - SizedBox( - height: height * 0.3, - ), Center( child: Obx( () { @@ -76,7 +78,7 @@ class TimerView extends GetView { Expanded( child: Center( child: Text( - '$hours', + hours, style: const TextStyle( fontSize: 50.0, fontWeight: FontWeight.bold, @@ -94,7 +96,7 @@ class TimerView extends GetView { Expanded( child: Center( child: Text( - '$minutes', + minutes, style: const TextStyle( fontSize: 50.0, fontWeight: FontWeight.bold, @@ -112,7 +114,7 @@ class TimerView extends GetView { Expanded( child: Center( child: Text( - '$seconds', + seconds, style: const TextStyle( fontSize: 50.0, fontWeight: FontWeight.bold, @@ -125,15 +127,10 @@ class TimerView extends GetView { }, ), ), - SizedBox( - height: height * 0.15, - ), Obx( () => Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - width: width * 0.20, - ), FloatingActionButton.small( heroTag: 'stop', onPressed: () async { @@ -168,246 +165,462 @@ class TimerView extends GetView { ), ], ) - : Obx( - () => Container( - color: themeController.isLightMode.value - ? kLightPrimaryBackgroundColor - : kprimaryBackgroundColor, - height: height * 0.32, - width: width, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Hours', - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - fontWeight: FontWeight.bold, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - SizedBox( - height: height * 0.008, - ), - NumberPicker( - minValue: 0, - maxValue: 23, - value: controller.hours.value, - onChanged: (value) { - Utils.hapticFeedback(); - controller.hours.value = value; - }, - 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, + : InkWell( + onTap: () { + Utils.hapticFeedback(); + inputTimeController.changeTimePickerTimer(); + }, + child: Obx( + () => Container( + color: themeController.isLightMode.value + ? kLightPrimaryBackgroundColor + : kprimaryBackgroundColor, + height: height * 0.32, + width: width, + child: inputTimeController.isTimePickerTimer.value + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Hours', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + SizedBox( + height: height * 0.008, + ), + NumberPicker( + minValue: 0, + maxValue: 23, + value: controller.hours.value, + onChanged: (value) { + Utils.hapticFeedback(); + controller.hours.value = value; + }, + 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.only( + left: width * 0.02, + right: width * 0.02, + top: height * 0.035, ), - bottom: BorderSide( - width: width * 0.005, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + child: Text( + ':', + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), ), - ), - ), - ], - ), - Padding( - padding: EdgeInsets.only( - left: width * 0.02, - right: width * 0.02, - top: height * 0.035, - ), - child: Text( - ':', - style: Theme.of(context) - .textTheme - .displayLarge! - .copyWith( - fontWeight: FontWeight.bold, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Minutes', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + SizedBox( + height: height * 0.008, + ), + NumberPicker( + minValue: 0, + maxValue: 59, + value: controller.minutes.value, + onChanged: (value) { + controller.minutes.value = value; + }, + 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, + ), + ), + ), + ), + ], ), - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Minutes', - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - fontWeight: FontWeight.bold, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - SizedBox( - height: height * 0.008, - ), - NumberPicker( - minValue: 0, - maxValue: 59, - value: controller.minutes.value, - onChanged: (value) { - controller.minutes.value = value; - }, - 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, + Padding( + padding: EdgeInsets.only( + left: width * 0.02, + right: width * 0.02, + top: height * 0.035, ), - bottom: BorderSide( - width: width * 0.005, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + child: Text( + ':', + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), ), - ), - ), - ], - ), - Padding( - padding: EdgeInsets.only( - left: width * 0.02, - right: width * 0.02, - top: height * 0.035, - ), - child: Text( - ':', - style: Theme.of(context) - .textTheme - .displayLarge! - .copyWith( - fontWeight: FontWeight.bold, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Seconds', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + SizedBox( + height: height * 0.008, + ), + NumberPicker( + minValue: 0, + maxValue: 59, + value: controller.seconds.value, + onChanged: (value) { + controller.seconds.value = value; + }, + 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, + ), + ), + ), + ), + ], ), - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Seconds', - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - fontWeight: FontWeight.bold, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, - ), - ), - SizedBox( - height: height * 0.008, - ), - NumberPicker( - minValue: 0, - maxValue: 59, - value: controller.seconds.value, - onChanged: (value) { - controller.seconds.value = value; - }, - infiniteLoop: true, - itemWidth: width * 0.17, - zeroPad: true, - selectedTextStyle: Theme.of(context) - .textTheme - .displayLarge! - .copyWith( - fontWeight: FontWeight.bold, - color: kprimaryColor, + ], + ) + : Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Hours', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + SizedBox( + height: height * 0.008, + ), + SizedBox( + width: 80, + child: TextField( + onChanged: (_) { + inputTimeController.setTimerTime(); + }, + decoration: const InputDecoration( + hintText: 'HH', + border: InputBorder.none, + ), + textAlign: TextAlign.center, + controller: inputTimeController + .inputHoursControllerTimer, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow( + RegExp( + '[1,2,3,4,5,6,7,8,9,0]', + ), + ), + LengthLimitingTextInputFormatter( + 2, + ), + LimitRange( + 0, + 23, + ), + ], + ), + ), + ], + ), + Padding( + padding: EdgeInsets.only( + left: width * 0.02, + right: width * 0.02, + top: height * 0.035, ), - textStyle: Theme.of(context) - .textTheme - .displayMedium! - .copyWith( - fontSize: 20, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + child: Text( + ':', + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), - decoration: BoxDecoration( - border: Border( - top: BorderSide( - width: width * 0.005, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + ), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Minutes', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + SizedBox( + height: height * 0.008, + ), + SizedBox( + width: 80, + child: TextField( + onChanged: (_) { + inputTimeController.setTimerTime(); + }, + decoration: const InputDecoration( + hintText: 'MM', + border: InputBorder.none, + ), + textAlign: TextAlign.center, + controller: inputTimeController + .inputMinutesControllerTimer, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow( + RegExp( + '[1,2,3,4,5,6,7,8,9,0]', + ), + ), + LengthLimitingTextInputFormatter( + 2, + ), + LimitRange( + 0, + 59, + ), + ], + ), + ), + ], + ), + Padding( + padding: EdgeInsets.only( + left: width * 0.02, + right: width * 0.02, + top: height * 0.035, ), - bottom: BorderSide( - width: width * 0.005, - color: themeController.isLightMode.value - ? kLightPrimaryDisabledTextColor - : kprimaryDisabledTextColor, + child: Text( + ':', + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), ), ), - ), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Seconds', + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + fontWeight: FontWeight.bold, + color: themeController + .isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), + SizedBox( + height: height * 0.008, + ), + SizedBox( + width: 80, + child: TextField( + onChanged: (_) { + inputTimeController.setTimerTime(); + }, + decoration: const InputDecoration( + hintText: 'SS', + border: InputBorder.none, + ), + textAlign: TextAlign.center, + controller: inputTimeController + .inputSecondsControllerTimer, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow( + RegExp( + '[1,2,3,4,5,6,7,8,9,0]', + ), + ), + LengthLimitingTextInputFormatter( + 2, + ), + LimitRange( + 0, + 59, + ), + ], + ), + ), + ], + ), + ], ), - ], - ), - ], ), ), ), @@ -446,7 +659,7 @@ class TimerView extends GetView { ), ), ), - endDrawer: buildEndDrawer(context) + endDrawer: buildEndDrawer(context), ); } } diff --git a/lib/app/utils/audio_utils.dart b/lib/app/utils/audio_utils.dart index 146866e7..544aa49d 100644 --- a/lib/app/utils/audio_utils.dart +++ b/lib/app/utils/audio_utils.dart @@ -14,7 +14,7 @@ class AudioUtils { static MethodChannel alarmChannel = const MethodChannel('ulticlock'); static AudioSession? audioSession; - + static bool isPreviewing = false; static Future initializeAudioSession() async { @@ -92,8 +92,6 @@ class AudioUtils { } } - - static Future stopDefaultAlarm() async { try { if (audioSession != null) { @@ -115,6 +113,7 @@ class AudioUtils { if (ringtoneName == 'Default') { await alarmChannel.invokeMethod('playDefaultAlarm'); + isPreviewing = true; } else { int customRingtoneId = fastHash(ringtoneName); RingtoneModel? customRingtone = await IsarDb.getCustomRingtone( @@ -128,10 +127,7 @@ class AudioUtils { await audioSession!.setActive(true); await playCustomSound(customRingtonePath); isPreviewing = true; - } else { - await alarmChannel.invokeMethod('playDefaultAlarm'); - isPreviewing = true; - } + } } } catch (e) { debugPrint(e.toString()); diff --git a/lib/app/utils/constants.dart b/lib/app/utils/constants.dart index 5b5b19df..11e42791 100644 --- a/lib/app/utils/constants.dart +++ b/lib/app/utils/constants.dart @@ -120,12 +120,24 @@ ThemeData kThemeData = ThemeData( backgroundColor: kprimaryBackgroundColor, selectedLabelStyle: TextStyle( color: kprimaryColor, + shadows: [ + Shadow(color: Color.fromARGB(90, 255, 255, 255), offset: Offset(1, 1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(90, 255, 255, 255), offset: Offset(1, -1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(90, 255, 255, 255), offset: Offset(-1, 1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(90, 255, 255, 255), offset: Offset(-1, -1), blurRadius: 10.0), + ], ), unselectedLabelStyle: TextStyle( color: kprimaryTextColor, ), selectedIconTheme: IconThemeData( color: kprimaryColor, + shadows: [ + Shadow(color: Color.fromARGB(90, 255, 255, 255), offset: Offset(1, 1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(90, 255, 255, 255), offset: Offset(1, -1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(90, 255, 255, 255), offset: Offset(-1, 1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(90, 255, 255, 255), offset: Offset(-1, -1), blurRadius: 10.0), + ], ), unselectedIconTheme: IconThemeData( color: kprimaryTextColor, @@ -219,12 +231,24 @@ ThemeData kLightThemeData = ThemeData( backgroundColor: kLightPrimaryBackgroundColor, selectedLabelStyle: TextStyle( color: kprimaryColor, + shadows: [ + Shadow(color: Color.fromARGB(120, 0, 0, 0), offset: Offset(1, 1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(120, 0, 0, 0), offset: Offset(1, -1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(120, 0, 0, 0), offset: Offset(-1, 1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(120, 0, 0, 0), offset: Offset(-1, -1), blurRadius: 10.0), + ], ), unselectedLabelStyle: TextStyle( color: kLightPrimaryTextColor, ), selectedIconTheme: IconThemeData( color: kprimaryColor, + shadows: [ + Shadow(color: Color.fromARGB(100, 0, 0, 0), offset: Offset(1, 1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(100, 0, 0, 0), offset: Offset(1, -1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(100, 0, 0, 0), offset: Offset(-1, 1), blurRadius: 10.0), + Shadow(color: Color.fromARGB(100, 0, 0, 0), offset: Offset(-1, -1), blurRadius: 10.0), + ], ), unselectedIconTheme: IconThemeData( color: kLightPrimaryTextColor, diff --git a/lib/app/utils/language.dart b/lib/app/utils/language.dart index c8b7945f..b743d0fb 100644 --- a/lib/app/utils/language.dart +++ b/lib/app/utils/language.dart @@ -53,6 +53,11 @@ class AppTranslations extends Translations { 'Create alarm': 'Create alarm', 'Join alarm': 'Join alarm', 'Okay': 'Okay', + 'Yes': 'Yes', + 'No': 'No', + 'Confirmation': 'Confirmation', + 'want to delete?': 'Are you sure you want to delete this alarm?', + 'You cannot join your own alarm!': 'You cannot join your own alarm!', 'An alarm with this ID doesn\'t exist!': 'An alarm with this ID doesn\'t exist!', diff --git a/lib/app/utils/languages/french_translations.dart b/lib/app/utils/languages/french_translations.dart index a187f770..a310bd05 100644 --- a/lib/app/utils/languages/french_translations.dart +++ b/lib/app/utils/languages/french_translations.dart @@ -52,6 +52,10 @@ class FrenchTranslations extends Translations { 'Create alarm': 'Créer un réveil', 'Join alarm': 'Rejoindre un réveil', 'Okay': 'D\'accord', + 'Yes': 'Oui', + 'No': 'Non', + 'Confirmation': 'Confirmation', + 'want to delete?': 'Êtes-vous sûr de vouloir supprimer cette alarme ?', 'You cannot join your own alarm!': 'Vous ne pouvez pas rejoindre votre propre réveil !', 'An alarm with this ID doesn\'t exist!': diff --git a/lib/app/utils/languages/german_translations.dart b/lib/app/utils/languages/german_translations.dart index e07e6159..c492dc14 100644 --- a/lib/app/utils/languages/german_translations.dart +++ b/lib/app/utils/languages/german_translations.dart @@ -45,6 +45,10 @@ class GermanTranslations extends Translations { 'Create alarm': 'Alarm erstellen', 'Join alarm': 'Alarm beitreten', 'Okay': 'Okay', + 'Yes': 'Ja', + 'No': 'Nein', + 'Confirmation': 'Bestätigung', + 'want to delete?': 'Sind Sie sicher, dass Sie diesen Alarm löschen möchten?', 'You cannot join your own alarm!': 'Sie können Ihrem eigenen Alarm nicht beitreten!', 'An alarm with this ID doesn\'t exist!': diff --git a/lib/app/utils/languages/russian_translations.dart b/lib/app/utils/languages/russian_translations.dart index b66cbd57..df32e943 100644 --- a/lib/app/utils/languages/russian_translations.dart +++ b/lib/app/utils/languages/russian_translations.dart @@ -51,6 +51,10 @@ class RussianTranslations extends Translations { 'Create alarm': 'Создать будильник', 'Join alarm': 'Присоединиться к будильнику', 'Okay': 'Хорошо', + 'Yes': 'Да', + 'No': 'Нет', + 'Confirmation': 'подтверждение', + 'want to delete?': 'Вы уверены, что хотите удалить этот будильник?', 'You cannot join your own alarm!': 'Вы не можете присоединиться к собственной тревоге!', 'An alarm with this ID doesn\'t exist!': diff --git a/lib/app/utils/languages/spanish_translations.dart b/lib/app/utils/languages/spanish_translations.dart index ffd6ed48..ed1ce0d7 100644 --- a/lib/app/utils/languages/spanish_translations.dart +++ b/lib/app/utils/languages/spanish_translations.dart @@ -52,6 +52,10 @@ class SpanishTranslations extends Translations { 'Create alarm': 'Crear alarma', 'Join alarm': 'Unirse a alarma', 'Okay': 'Aceptar', + 'Yes': 'Sí', + 'No': 'No', + 'Confirmation': 'Confirmación', + 'want to delete?': '¿Estás seguro de que deseas eliminar esta alarma?', 'You cannot join your own alarm!': '¡No puedes unirte a tu propia alarma!', 'An alarm with this ID doesn\'t exist!': diff --git a/pubspec.lock b/pubspec.lock index cbd772ce..70ce4b4e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -628,10 +628,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 cf7d8a9a..43f51f28 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 From 5454a01cd9a4431679509be2b17775d0482b1844 Mon Sep 17 00:00:00 2001 From: krish Date: Thu, 21 Mar 2024 00:54:55 +0530 Subject: [PATCH 12/14] imporved ui --- .../add_or_update_alarm_controller.dart | 56 ++++++++++++++++--- .../views/photo_challenge_tile.dart | 2 +- .../views/photo_challengeview.dart | 7 ++- lib/app/modules/home/views/home_view.dart | 18 ++++++ 4 files changed, 71 insertions(+), 12 deletions(-) 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 8568b813..6dbf2687 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 @@ -727,6 +727,7 @@ class AddOrUpdateAlarmController extends GetxController { if (imageurl.value == '') { pickedFile.copySync(newFilePath); debugPrint(newFilePath); + return newFilePath; } else { // Assuming imageurl.value already contains the full path, @@ -765,14 +766,17 @@ class AddOrUpdateAlarmController extends GetxController { content: Obx( () => Column( children: [ - Padding( - padding: const EdgeInsets.only(bottom: 15.0), - child: Image.file( - File(imageurl.value), - fit: BoxFit.cover, - height: MediaQuery.of(Get.context!).size.height * 0.3, - width: MediaQuery.of(Get.context!).size.width, - )), + (isPhotochallengeEnabled.value) + ? Padding( + padding: const EdgeInsets.only(bottom: 15.0), + child: Image.file( + File(imageurl.value), + fit: BoxFit.cover, + height: MediaQuery.of(Get.context!).size.height * 0.3, + width: MediaQuery.of(Get.context!).size.width, + ), + ) + : const Text('Photo Challenge Disabled'), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -814,6 +818,10 @@ class AddOrUpdateAlarmController extends GetxController { // showPhotoDialog(); final pickedFile = await picker.pickImage(source: ImageSource.camera); + + if (await File(imageurl.value).exists()) { + await File(imageurl.value).delete(); + } if (pickedFile != null) { File imagepickedfile = File(pickedFile.path); @@ -823,9 +831,41 @@ class AddOrUpdateAlarmController extends GetxController { //clear image chache await imagepickedfile.delete(); isPhotochallengeEnabled.value = true; + Get.back(); } else {} }, ), + if (isPhotochallengeEnabled.value) + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(kprimaryColor), + ), + child: Text( + 'Disable', + style: Theme.of(Get.context!) + .textTheme + .displaySmall! + .copyWith( + color: themeController.isLightMode.value + ? kLightPrimaryTextColor + : ksecondaryTextColor, + ), + ), + onPressed: () async { + isPhotochallengeEnabled.value = false; + File file = File(imageurl.value); + + if (await file.exists()) { + await file.delete(); + debugPrint('File deleted successfully.'); + } else { + debugPrint('File does not exist.'); + } + imageurl.value = ''; + Get.back(); + }, + ), ], ), ], diff --git a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart index 5e477b5a..cd5e21c5 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart @@ -47,7 +47,7 @@ class PhotoChallenge extends StatelessWidget { // description: // 'Scan the QR/Bar code on any object, like a book, and relocate it to a different room. To deactivate the alarm, simply rescan the same QR/Bar code.', description: 'qrDescription'.tr, - iconData: Icons.qr_code_scanner, + iconData: Icons.camera_alt, isLightMode: themeController.isLightMode.value, ); }, diff --git a/lib/app/modules/alarmChallenge/views/photo_challengeview.dart b/lib/app/modules/alarmChallenge/views/photo_challengeview.dart index 5fba4612..47891361 100644 --- a/lib/app/modules/alarmChallenge/views/photo_challengeview.dart +++ b/lib/app/modules/alarmChallenge/views/photo_challengeview.dart @@ -87,11 +87,11 @@ class PhotoChallengeView extends GetView { controller .alarmRecord.imageurl, ), - fit: BoxFit.cover, + fit: BoxFit.contain, height: MediaQuery.of( Get.context!, ).size.height * - 0.3, + 0.36, width: MediaQuery.of( Get.context!, ).size.width * @@ -143,7 +143,8 @@ class PhotoChallengeView extends GetView { controller.imageurl.value, ); Get.log( - '${controller.imagesimilarity.value}'); + '${controller.imagesimilarity.value}', + ); if (controller.imagesimilarity .value <= 0.36) { diff --git a/lib/app/modules/home/views/home_view.dart b/lib/app/modules/home/views/home_view.dart index 5ace9bcb..66c245ce 100644 --- a/lib/app/modules/home/views/home_view.dart +++ b/lib/app/modules/home/views/home_view.dart @@ -1142,6 +1142,24 @@ class HomeView extends GetView { : kprimaryDisabledTextColor, ), ), + if (alarm + .isPhotochallengeEnabled) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + child: Icon( + Icons.camera_alt, + size: 24, + color: alarm.isEnabled == true + ? themeController.isLightMode.value + ? kLightPrimaryTextColor.withOpacity(0.5) + : kprimaryTextColor.withOpacity(0.5) + : themeController.isLightMode.value + ? kLightPrimaryDisabledTextColor + : kprimaryDisabledTextColor, + ), + ), if (alarm .isShakeEnabled) Padding( From c2884ae55ba5273c93d169e57d510d24cda2621d Mon Sep 17 00:00:00 2001 From: krish Date: Thu, 21 Mar 2024 01:34:00 +0530 Subject: [PATCH 13/14] added description and translation --- .../addOrUpdateAlarm/views/photo_challenge_tile.dart | 2 +- lib/app/utils/language.dart | 7 +++++++ lib/app/utils/languages/french_translations.dart | 12 +++++++++++- lib/app/utils/languages/german_translations.dart | 12 +++++++++++- lib/app/utils/languages/russian_translations.dart | 8 ++++++++ lib/app/utils/languages/spanish_translations.dart | 11 ++++++++++- 6 files changed, 48 insertions(+), 4 deletions(-) diff --git a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart index cd5e21c5..5347f6ca 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart @@ -46,7 +46,7 @@ class PhotoChallenge extends StatelessWidget { title: 'Photo'.tr, // description: // 'Scan the QR/Bar code on any object, like a book, and relocate it to a different room. To deactivate the alarm, simply rescan the same QR/Bar code.', - description: 'qrDescription'.tr, + description: 'photoDescription'.tr, iconData: Icons.camera_alt, isLightMode: themeController.isLightMode.value, ); diff --git a/lib/app/utils/language.dart b/lib/app/utils/language.dart index b743d0fb..1e0ac81f 100644 --- a/lib/app/utils/language.dart +++ b/lib/app/utils/language.dart @@ -134,6 +134,13 @@ class AppTranslations extends Translations { 'QR/Bar Code': 'QR/Bar Code', 'qrDescription': 'Scan the QR/Bar code on any object, like a book, and relocate it to a different room. To deactivate the alarm, simply rescan the same QR/Bar code.', + //photo_challenge_tile.dart + 'Take': 'Take', + 'Retake': 'Retake', + 'Disable': 'Disable', + 'Photo': 'Photo', + 'photoDescription': + 'The ultimate photo challenge app that turns capturing moments into an exhilarating game! Snap a shot to kickstart the challenge, then race against the clock to recreate it and silence the alarm. Are you up for the challenge?', //repeat_once_tile.dart 'Repeat only once': 'Repeat only once', //repeat_tile.dart diff --git a/lib/app/utils/languages/french_translations.dart b/lib/app/utils/languages/french_translations.dart index a310bd05..65763226 100644 --- a/lib/app/utils/languages/french_translations.dart +++ b/lib/app/utils/languages/french_translations.dart @@ -55,7 +55,8 @@ class FrenchTranslations extends Translations { 'Yes': 'Oui', 'No': 'Non', 'Confirmation': 'Confirmation', - 'want to delete?': 'Êtes-vous sûr de vouloir supprimer cette alarme ?', + 'want to delete?': + 'Êtes-vous sûr de vouloir supprimer cette alarme ?', 'You cannot join your own alarm!': 'Vous ne pouvez pas rejoindre votre propre réveil !', 'An alarm with this ID doesn\'t exist!': @@ -161,6 +162,15 @@ class FrenchTranslations extends Translations { 'QR/Bar Code': 'QR/Code-barres', 'qrDescription': 'Scannez le QR/Code-barres sur n\'importe quel objet, comme un livre, et déplacez-le dans une pièce différente. Pour désactiver l\'alarme, scannez à nouveau le même QR/Code-barres.', + +//photo_challenge_tile.dart + 'Take': 'Prendre', + 'Retake': 'Reprendre', + 'Disable': 'Désactiver', + 'Photo': 'Photo', + 'photoDescription': + "L'application ultime de défi photo qui transforme la capture de moments en un jeu palpitant ! Prenez une photo pour lancer le défi, puis défiez le temps pour la recréer et arrêter l'alarme. Êtes-vous prêt pour le défi ?", + //repeat_once_tile.dart 'Repeat only once': 'Répéter une seule fois', //repeat_tile.dart diff --git a/lib/app/utils/languages/german_translations.dart b/lib/app/utils/languages/german_translations.dart index c492dc14..02e45a29 100644 --- a/lib/app/utils/languages/german_translations.dart +++ b/lib/app/utils/languages/german_translations.dart @@ -48,7 +48,8 @@ class GermanTranslations extends Translations { 'Yes': 'Ja', 'No': 'Nein', 'Confirmation': 'Bestätigung', - 'want to delete?': 'Sind Sie sicher, dass Sie diesen Alarm löschen möchten?', + 'want to delete?': + 'Sind Sie sicher, dass Sie diesen Alarm löschen möchten?', 'You cannot join your own alarm!': 'Sie können Ihrem eigenen Alarm nicht beitreten!', 'An alarm with this ID doesn\'t exist!': @@ -156,6 +157,15 @@ class GermanTranslations extends Translations { 'QR/Bar Code': 'QR-/Strichcode', 'qrDescription': 'Scannen Sie den QR-/Strichcode auf einem Objekt wie einem Buch und verschieben Sie es in einen anderen Raum. Zum Deaktivieren des Alarms scannen Sie einfach denselben QR-/Strichcode erneut.', +//photo_challenge_tile.dart + + 'Take': 'Aufnehmen', + 'Retake': 'Erneut aufnehmen', + 'Disable': 'Deaktivieren', + 'Photo': 'Foto', + 'photoDescription': + 'Die ultimative Foto-Challenge-App, die das Erfassen von Momenten in ein aufregendes Spiel verwandelt! Machen Sie ein Foto, um die Herausforderung zu starten, und versuchen Sie dann, es schnellstmöglich nachzustellen, um den Alarm zu stoppen. Sind Sie bereit für die Herausforderung?', + //repeat_once_tile.dart 'Repeat only once': 'Nur einmal wiederholen', //repeat_tile.dart diff --git a/lib/app/utils/languages/russian_translations.dart b/lib/app/utils/languages/russian_translations.dart index df32e943..2bc4c276 100644 --- a/lib/app/utils/languages/russian_translations.dart +++ b/lib/app/utils/languages/russian_translations.dart @@ -145,6 +145,14 @@ class RussianTranslations extends Translations { 'QR/Bar Code': 'QR-код / Штрих-код', 'qrDescription': 'Отсканируйте QR-код / Штрих-код на любом объекте, например, на книге, и переместите его в другую комнату. Чтобы отключить будильник, просто повторно отсканируйте тот же QR-код / Штрих-код.', +//photo_challenge_tile.dart + 'Take': 'Сделать', + 'Retake': 'Переснять', + 'Disable': 'Отключить', + 'Photo': 'Фото', + 'photoDescription': + 'Это приложение для фотовызовов, которое превращает запечатление моментов в захватывающую игру! Сделайте снимок, чтобы начать вызов, затем соревнуйтесь с временем, чтобы воссоздать его и выключить сигнал тревоги. Готовы ли вы к вызову?', + //repeat_once_tile.dart 'Repeat only once': 'Повторять только один раз', //repeat_tile.dart diff --git a/lib/app/utils/languages/spanish_translations.dart b/lib/app/utils/languages/spanish_translations.dart index ed1ce0d7..9cafa4b4 100644 --- a/lib/app/utils/languages/spanish_translations.dart +++ b/lib/app/utils/languages/spanish_translations.dart @@ -55,7 +55,8 @@ class SpanishTranslations extends Translations { 'Yes': 'Sí', 'No': 'No', 'Confirmation': 'Confirmación', - 'want to delete?': '¿Estás seguro de que deseas eliminar esta alarma?', + 'want to delete?': + '¿Estás seguro de que deseas eliminar esta alarma?', 'You cannot join your own alarm!': '¡No puedes unirte a tu propia alarma!', 'An alarm with this ID doesn\'t exist!': @@ -159,6 +160,14 @@ class SpanishTranslations extends Translations { 'QR/Bar Code': 'Código QR/Código de barras', 'qrDescription': 'Escanee el código QR/código de barras en cualquier objeto, como un libro, y muévalo a una habitación diferente. Para desactivar la alarma, simplemente vuelva a escanear el mismo código QR/código de barras.', +//photo_challenge_tile.dart + 'Tomar': 'Tomar', + 'Volver a tomar': 'Volver a tomar', + 'Desactivar': 'Desactivar', + 'Foto': 'Foto', + 'photoDescription': + '¡La aplicación definitiva de desafío fotográfico que convierte la captura de momentos en un emocionante juego! Toma una foto para comenzar el desafío, luego compite contra el reloj para recrearla y silenciar la alarma. ¿Estás listo para el desafío?', + //repeat_once_tile.dart 'Repeat only once': 'Repetir solo una vez', //repeat_tile.dart From 86da1bd91fc31dea34d02b2432f8f6f639ad693a Mon Sep 17 00:00:00 2001 From: krish Date: Thu, 21 Mar 2024 02:18:27 +0530 Subject: [PATCH 14/14] added description and translation for photo challenge --- .../controllers/add_or_update_alarm_controller.dart | 8 ++++---- .../addOrUpdateAlarm/views/photo_challenge_tile.dart | 4 ++-- .../addOrUpdateAlarm/views/qr_bar_code_tile.dart | 2 +- .../alarmChallenge/views/photo_challengeview.dart | 2 +- lib/app/utils/language.dart | 10 +++++++--- lib/app/utils/languages/french_translations.dart | 3 ++- lib/app/utils/languages/german_translations.dart | 2 ++ lib/app/utils/languages/russian_translations.dart | 3 ++- lib/app/utils/languages/spanish_translations.dart | 2 ++ lib/app/utils/utils.dart | 1 + 10 files changed, 24 insertions(+), 13 deletions(-) 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 6dbf2687..9f26ca51 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 @@ -761,7 +761,7 @@ class AddOrUpdateAlarmController extends GetxController { backgroundColor: themeController.isLightMode.value ? kLightSecondaryBackgroundColor : ksecondaryBackgroundColor, - title: 'Capture a Photo', + title: 'Capture a Photo'.tr, titleStyle: Theme.of(Get.context!).textTheme.displaySmall, content: Obx( () => Column( @@ -785,7 +785,7 @@ class AddOrUpdateAlarmController extends GetxController { backgroundColor: MaterialStateProperty.all(kprimaryColor), ), child: Text( - 'Save', + 'Save'.tr, style: Theme.of(Get.context!) .textTheme .displaySmall! @@ -804,7 +804,7 @@ class AddOrUpdateAlarmController extends GetxController { backgroundColor: MaterialStateProperty.all(kprimaryColor), ), child: Text( - 'Retake', + 'Retake'.tr, style: Theme.of(Get.context!) .textTheme .displaySmall! @@ -842,7 +842,7 @@ class AddOrUpdateAlarmController extends GetxController { MaterialStateProperty.all(kprimaryColor), ), child: Text( - 'Disable', + 'Disable'.tr, style: Theme.of(Get.context!) .textTheme .displaySmall! diff --git a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart index 5347f6ca..1c0e8f55 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/photo_challenge_tile.dart @@ -24,7 +24,7 @@ class PhotoChallenge extends StatelessWidget { alignment: Alignment.centerLeft, fit: BoxFit.scaleDown, child: Text( - 'Photo', + 'Photo'.tr, style: TextStyle( color: themeController.isLightMode.value ? kLightPrimaryTextColor @@ -46,7 +46,7 @@ class PhotoChallenge extends StatelessWidget { title: 'Photo'.tr, // description: // 'Scan the QR/Bar code on any object, like a book, and relocate it to a different room. To deactivate the alarm, simply rescan the same QR/Bar code.', - description: 'photoDescription'.tr, + description: 'photoDescription', iconData: Icons.camera_alt, isLightMode: themeController.isLightMode.value, ); diff --git a/lib/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart b/lib/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart index 898e098e..cbffb856 100644 --- a/lib/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart +++ b/lib/app/modules/addOrUpdateAlarm/views/qr_bar_code_tile.dart @@ -46,7 +46,7 @@ class QrBarCode extends StatelessWidget { title: 'QR/Bar Code'.tr, // description: // 'Scan the QR/Bar code on any object, like a book, and relocate it to a different room. To deactivate the alarm, simply rescan the same QR/Bar code.', - description: 'qrDescription'.tr, + description: 'qrDescription', iconData: Icons.qr_code_scanner, isLightMode: themeController.isLightMode.value, ); diff --git a/lib/app/modules/alarmChallenge/views/photo_challengeview.dart b/lib/app/modules/alarmChallenge/views/photo_challengeview.dart index 47891361..25efd794 100644 --- a/lib/app/modules/alarmChallenge/views/photo_challengeview.dart +++ b/lib/app/modules/alarmChallenge/views/photo_challengeview.dart @@ -107,7 +107,7 @@ class PhotoChallengeView extends GetView { ), ), child: Text( - 'Take Photo', + 'Take Photo'.tr, style: Theme.of(Get.context!) .textTheme .displaySmall! diff --git a/lib/app/utils/language.dart b/lib/app/utils/language.dart index 1e0ac81f..7cd36d0f 100644 --- a/lib/app/utils/language.dart +++ b/lib/app/utils/language.dart @@ -86,7 +86,7 @@ class AppTranslations extends Translations { 'Leave': 'Leave', 'Save': 'Save', 'Update': 'Update', - 'Rings in @timeToAlarm': 'Rings in @timeToAlarm', + // 'Rings in @timeToAlarm': 'Rings in @timeToAlarm', 'Uh-oh!': 'Uh-oh!', 'alarmEditing': 'This alarm is currently being edited!', 'Go back': 'Go back', @@ -141,6 +141,10 @@ class AppTranslations extends Translations { 'Photo': 'Photo', 'photoDescription': 'The ultimate photo challenge app that turns capturing moments into an exhilarating game! Snap a shot to kickstart the challenge, then race against the clock to recreate it and silence the alarm. Are you up for the challenge?', + + 'Take Photo': 'Tak1 Photo', + 'Capture a Photo': 'Capture a Photo', + //repeat_once_tile.dart 'Repeat only once': 'Repeat only once', //repeat_tile.dart @@ -164,7 +168,7 @@ class AppTranslations extends Translations { 'times': 'times', 'time': 'time', //'shared_alarm_tile.dart - 'Shared Alarm': 'Shared Alarm', + // 'Shared Alarm': 'Shared Alarm', 'Shared alarms': 'Shared alarms', 'sharedDescription': 'Share alarms with others using the Alarm ID. Each shared user can choose to have their alarm ring before or after the set time.', @@ -203,7 +207,7 @@ class AppTranslations extends Translations { //qr_challenge_view.dart 'Scan your QR/Bar Code!': 'Scan your QR/Bar Code!', 'Wrong Code Scanned!': 'Wrong Code Scanned!', - 'Retake': 'Retake', + //shake_challenge_view.dart 'Shake your phone!': 'Shake your phone!', //alarm_ring_view.dart diff --git a/lib/app/utils/languages/french_translations.dart b/lib/app/utils/languages/french_translations.dart index 65763226..926848fa 100644 --- a/lib/app/utils/languages/french_translations.dart +++ b/lib/app/utils/languages/french_translations.dart @@ -170,7 +170,8 @@ class FrenchTranslations extends Translations { 'Photo': 'Photo', 'photoDescription': "L'application ultime de défi photo qui transforme la capture de moments en un jeu palpitant ! Prenez une photo pour lancer le défi, puis défiez le temps pour la recréer et arrêter l'alarme. Êtes-vous prêt pour le défi ?", - + 'Take Photo': 'Prendre une photo', + 'Capture a Photo': 'Capturer une photo', //repeat_once_tile.dart 'Repeat only once': 'Répéter une seule fois', //repeat_tile.dart diff --git a/lib/app/utils/languages/german_translations.dart b/lib/app/utils/languages/german_translations.dart index 02e45a29..a36b8bf2 100644 --- a/lib/app/utils/languages/german_translations.dart +++ b/lib/app/utils/languages/german_translations.dart @@ -165,6 +165,8 @@ class GermanTranslations extends Translations { 'Photo': 'Foto', 'photoDescription': 'Die ultimative Foto-Challenge-App, die das Erfassen von Momenten in ein aufregendes Spiel verwandelt! Machen Sie ein Foto, um die Herausforderung zu starten, und versuchen Sie dann, es schnellstmöglich nachzustellen, um den Alarm zu stoppen. Sind Sie bereit für die Herausforderung?', + 'Take Photo': 'Foto machen', + 'Capture a Photo': 'Foto aufnehmen', //repeat_once_tile.dart 'Repeat only once': 'Nur einmal wiederholen', diff --git a/lib/app/utils/languages/russian_translations.dart b/lib/app/utils/languages/russian_translations.dart index 2bc4c276..e3e5b660 100644 --- a/lib/app/utils/languages/russian_translations.dart +++ b/lib/app/utils/languages/russian_translations.dart @@ -152,7 +152,8 @@ class RussianTranslations extends Translations { 'Photo': 'Фото', 'photoDescription': 'Это приложение для фотовызовов, которое превращает запечатление моментов в захватывающую игру! Сделайте снимок, чтобы начать вызов, затем соревнуйтесь с временем, чтобы воссоздать его и выключить сигнал тревоги. Готовы ли вы к вызову?', - + 'Take Photo': 'Сделать фото', + 'Capture a Photo': 'Захватить фотографию', //repeat_once_tile.dart 'Repeat only once': 'Повторять только один раз', //repeat_tile.dart diff --git a/lib/app/utils/languages/spanish_translations.dart b/lib/app/utils/languages/spanish_translations.dart index 9cafa4b4..9fb70c7b 100644 --- a/lib/app/utils/languages/spanish_translations.dart +++ b/lib/app/utils/languages/spanish_translations.dart @@ -167,6 +167,8 @@ class SpanishTranslations extends Translations { 'Foto': 'Foto', 'photoDescription': '¡La aplicación definitiva de desafío fotográfico que convierte la captura de momentos en un emocionante juego! Toma una foto para comenzar el desafío, luego compite contra el reloj para recrearla y silenciar la alarma. ¿Estás listo para el desafío?', + 'Take Photo': 'Tomar foto', + 'Capture a Photo': 'Capturar una foto', //repeat_once_tile.dart 'Repeat only once': 'Repetir solo una vez', diff --git a/lib/app/utils/utils.dart b/lib/app/utils/utils.dart index 41b0fdc8..a50c8b31 100644 --- a/lib/app/utils/utils.dart +++ b/lib/app/utils/utils.dart @@ -566,6 +566,7 @@ class Utils { ? kLightSecondaryBackgroundColor : ksecondaryBackgroundColor, builder: (context) { + Get.log(description.tr); return Center( child: Padding( padding: const EdgeInsets.all(25.0),