diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 8deddef..37c461c 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -15,8 +15,6 @@ android { compileSdk = flutter.compileSdkVersion ndkVersion = flutter.ndkVersion - - compileOptions { isCoreLibraryDesugaringEnabled = true targetCompatibility = JavaVersion.VERSION_17 @@ -77,3 +75,27 @@ dependencies { flutter { source = "../.." } + +/// To use this, first be in $PROJ/android/, then run: ./gradlew printFlutterVariables +tasks.register("printFlutterVariables") { + description = "Print Local Flutter Variables" + doLast { + // android // + // compileSdk = flutter.compileSdkVersion + println("compileSdk: ${android.compileSdk}") + println("compileSdkVersion: ${android.compileSdkVersion}") + // ndkVersion = flutter.ndkVersion + println("ndkVersion: ${android.ndkVersion}") + + // android.defaultConfig // + // minSdk = flutter.minSdkVersion + println("minSdk: ${android.defaultConfig.minSdk}") + // targetSdk = flutter.targetSdkVersion + println("targetSdk: ${android.defaultConfig.targetSdk}") + println("targetSdkVersion: ${android.defaultConfig.targetSdkVersion}") + // versionCode = flutter.versionCode + println("versionCode: ${android.defaultConfig.versionCode}") + // versionName = flutter.versionName + println("versionName: ${android.defaultConfig.versionName}") + } +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 5d64b5a..87530ac 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,6 +27,9 @@ + + + --> + diff --git a/android/app/src/main/res/drawable-xhdpi/ic_notification.png b/android/app/src/main/res/drawable-xhdpi/ic_notification.png index af689f4..4e76c78 100644 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png index ba21403..76b1123 100644 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png index 3df67b3..17c80a5 100644 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml index 304732f..473c77c 100644 --- a/android/app/src/main/res/drawable/launch_background.xml +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -10,3 +10,4 @@ android:src="@mipmap/launch_image" /> --> + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 82cd4a2..4df90c3 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,6 @@ - + - + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 82cd4a2..4df90c3 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,6 +1,6 @@ - + - + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..5fa6765 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index ec7deb9..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..75a8e44 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp deleted file mode 100644 index 917e5d2..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png new file mode 100644 index 0000000..da78661 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..5fa6765 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index 6a99f7c..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..8f481cf Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 89bc8a9..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..4e373cb Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp deleted file mode 100644 index 1e80f22..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png new file mode 100644 index 0000000..8e6a88d Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..8f481cf Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index afaccb8..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..0314db0 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 9ddfa30..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..f818b45 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp deleted file mode 100644 index 3183d36..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png new file mode 100644 index 0000000..01c41ec Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..0314db0 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 179cdc8..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..e1fe472 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp deleted file mode 100644 index 800c5b8..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..69a3cbb Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp deleted file mode 100644 index 932cd18..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png new file mode 100644 index 0000000..0b28acf Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..e1fe472 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index 134afc6..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..09449dc Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp deleted file mode 100644 index 603f71b..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..caa44dc Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp deleted file mode 100644 index f3abc6b..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png new file mode 100644 index 0000000..d8572ac Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..09449dc Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp deleted file mode 100644 index 204a273..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..c5d5899 --- /dev/null +++ b/android/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FFFFFF + \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 90f15b6..d6a1a9c 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ #Sat Sep 12 19:36:23 MST 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.0-bin.zip #distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/compile.sh b/compile.sh index e6f23de..956a5e9 100755 --- a/compile.sh +++ b/compile.sh @@ -32,7 +32,7 @@ version="" for i in `grep version $app_details`; do version="$i" done -version="v${version// /_}" +version="${version// /_}" if [[ -z $name || -z $version ]]; then echo "ERROR: Could not retrieve name or version. name='$name' version='$version'" diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..fa0b357 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/lib/main.dart b/lib/main.dart index 9260cb3..8bd76ef 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,9 +12,16 @@ import 'package:alarm/alarm.dart'; import 'dart:convert'; +// For trusting Let's Encrypt on older devices (SDK 24, Android 7) +//import 'dart:io'; +//import 'package:http/http.dart' as http; +import 'package:flutter/services.dart' show rootBundle; + /// TBD: /// - Add other languages (Spanish, Croatian) /// v1.1.0 +/// - Move the switchtile back to its own row so that it handles titles better. +/// v1.2.0 /// - Change sunset grabber to checkbox and retrieve it each alarm or open. /// v2.0.0 /// - Add sunrise section and change app name to Sunshine Alarm? @@ -22,6 +29,14 @@ import 'dart:convert'; void main() async { WidgetsFlutterBinding.ensureInitialized(); + + final certData = await rootBundle.load( + 'media/certs/open-meteo-com_isrg-root-x1.pem', + ); + SecurityContext.defaultContext.setTrustedCertificatesBytes( + certData.buffer.asUint8List(), + ); + tz.initializeTimeZones(); await Alarm.init(); runApp(const SunsetAlarmApp()); @@ -66,8 +81,8 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { final _latController = TextEditingController(); final _lngController = TextEditingController(); - final _sunsetController = TextEditingController(); - final _minutesController = TextEditingController(text: '30'); + final _sunsetController = TextEditingController(text: "18:00"); + final _minutesController = TextEditingController(text: "30"); final FlutterLocalNotificationsPlugin _notifications = FlutterLocalNotificationsPlugin(); @@ -79,6 +94,7 @@ class _HomeScreenState extends State { String? _sunsetErrorText; String? _minuteErrorText; + bool _validTime = false; static const _alarmId = 1001; @@ -107,15 +123,20 @@ class _HomeScreenState extends State { Future _loadPrefs() async { final prefs = await SharedPreferences.getInstance(); setState(() { - final lat = prefs.getDouble('lat'); - final lng = prefs.getDouble('lng'); - final sunset = prefs.getString('sunset_time'); - _alarmEnabled = prefs.getBool('alarm_enabled') ?? false; + final lat = prefs.getDouble('lat').toString(); + final lng = prefs.getDouble('lng').toString(); + final sun = prefs.getString('sunset_time'); + _latController.text = (lat == "null") ? "" : lat; + _lngController.text = (lng == "null") ? "" : lng; + _sunsetController.text = sun ?? ""; + _minutesBefore = prefs.getInt('minutes_before') ?? 30; - if (lat != null) _latController.text = lat.toString(); - if (lng != null) _lngController.text = lng.toString(); - if (sunset != null) _sunsetController.text = sunset; - _minutesController.text = '$_minutesBefore'; + _minutesController.text = _minutesBefore.toString(); + + _alarmEnabled = prefs.getBool('alarm_enabled') ?? false; + _validTime = prefs.getBool('valid_time') ?? false; + + _calcPlural(); }); if (_alarmEnabled && _sunsetController.text.isNotEmpty) { _scheduleAlarm(); @@ -133,6 +154,7 @@ class _HomeScreenState extends State { } await prefs.setBool('alarm_enabled', _alarmEnabled); await prefs.setInt('minutes_before', _minutesBefore); + await prefs.setBool('valid_time', _validTime); } Future _getGpsLocation() async { @@ -193,7 +215,10 @@ class _HomeScreenState extends State { } catch (e) { _showSnack('Network Error: $e'); } finally { - setState(() => _loading = false); + setState(() { + _loading = false; + _validTime = true; + }); } if (_alarmEnabled) { @@ -247,11 +272,10 @@ class _HomeScreenState extends State { ); } else if (Platform.isAndroid) { // Get the Notifications permission: - final android = - _notifications - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin - >(); + final android = _notifications + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin + >(); await android?.requestNotificationsPermission(); // Ensure that Android has the correct alarm permissions. @@ -327,18 +351,26 @@ class _HomeScreenState extends State { if (value) { await _scheduleAlarm(); } else { - _alarmTimer?.cancel(); - if (!Platform.isLinux) { - // Notification Method - if (ANDROID_USE_NOTIF) await _notifications.cancel(id: _alarmId); - - // Alarm Method - if (ANDROID_USE_ALARM) await Alarm.stop(_alarmId); - } - _showSnack('Alarm Cancelled'); + _stopAlarm(); } } + Future _stopAlarm() async { + if (Platform.isLinux) { + _alarmTimer?.cancel(); + } else if (Platform.isAndroid) { + // Notification Method + if (ANDROID_USE_NOTIF) { + await _notifications.cancel(id: _alarmId); + } + // Alarm Method + if (ANDROID_USE_ALARM) { + await Alarm.stop(_alarmId); + } + } + _showSnack('Alarm Cancelled'); + } + void _showSnack(String msg) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); } @@ -354,6 +386,9 @@ class _HomeScreenState extends State { } String? _validateTime(String? value) { + setState(() { + _validTime = false; + }); if (value == null || !RegExp(r'^\d{2}:\d{2}$').hasMatch(value)) { return 'Use HH:MM Format'; } @@ -361,9 +396,18 @@ class _HomeScreenState extends State { final m = int.parse(value.substring(3, 5)); if (h > 23) return 'Hour Must Be 0–23'; if (m > 59) return 'Minute Must Be 0–59'; + setState(() { + _validTime = true; + }); return null; // valid } + void _calcPlural() { + setState(() { + _plural = (_minutesBefore == 1) ? '' : 's'; + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -449,10 +493,9 @@ class _HomeScreenState extends State { '${picked.hour.toString().padLeft(2, '0')}:' '${picked.minute.toString().padLeft(2, '0')}'; setState( - () => - _sunsetErrorText = _validateTime( - _sunsetController.text, - ), + () => _sunsetErrorText = _validateTime( + _sunsetController.text, + ), ); if (_alarmEnabled) { _scheduleAlarm(); @@ -462,6 +505,9 @@ class _HomeScreenState extends State { ), ), onChanged: (v) { + if (v == "") { + _stopAlarm(); + } final val = _validateTime(v); if (val == null) { _savePrefs(); @@ -477,14 +523,13 @@ class _HomeScreenState extends State { ), const SizedBox(width: 8), IconButton.filledTonal( - icon: - _loading - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : const Icon(Icons.cloud_done_outlined), + icon: _loading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ) + : const Icon(Icons.cloud_done_outlined), tooltip: 'Fetch Open-Meteo Sunset Data', onPressed: () { if (!_loading) { @@ -507,6 +552,7 @@ class _HomeScreenState extends State { children: [ if (!_alarmEnabled) Expanded( + flex: 1, // _validTime ? 3 : 2, child: TextField( controller: _minutesController, keyboardType: TextInputType.number, @@ -524,24 +570,44 @@ class _HomeScreenState extends State { } else { _minuteErrorText = 'Invalid Minute Value'; } - _plural = (_minutesBefore == 1) ? '' : 's'; + _calcPlural(); }); }, ), ), + //Expanded( + // flex: 3, + // child: Center( + // child: + // _validTime ? Text("") : Text("Sunset Time Needed") , + // ), + //), + // --- Toggle --- Expanded( + flex: 1, //_validTime ? 2 : 5, child: SwitchListTile( - //title: const Text('Enable Sunset Alarm'), - title: Text(_alarmEnabled ? 'Sunset Alarm Enabled' : ''), - subtitle: Text( - _alarmEnabled - ? '${_minutesBefore} Minute${_plural} Before @ $_alarmDisplayTime' - : '', + title: Center( + child: Text( + _validTime + ? _alarmEnabled + ? "Sunset Alarm Enabled" + : "" //"Enable" + : "", // "Disabled", + ), ), - value: _alarmEnabled, - onChanged: _toggleAlarm, + subtitle: Center( + child: Text( + _validTime + ? _alarmEnabled + ? "${_minutesBefore} Minute${_plural} Before @ $_alarmDisplayTime" + : "" //"Sunset Alarm" + : "", //"Enter Valid Time", + ), + ), + value: _validTime ? _alarmEnabled : false, + onChanged: _validTime ? _toggleAlarm : null, ), ), ], @@ -573,11 +639,10 @@ final _plugin = FlutterLocalNotificationsPlugin(); Future requestPermissions() async { if (Platform.isAndroid) { - final android = - _plugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin - >(); + final android = _plugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin + >(); // Android 13+ — standard notification permission (shows a dialog) await android?.requestNotificationsPermission(); @@ -587,8 +652,7 @@ Future requestPermissions() async { } } -final android = - _plugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin - >(); +final android = _plugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin + >(); diff --git a/media/certs/open-meteo-com_isrg-root-x1.pem b/media/certs/open-meteo-com_isrg-root-x1.pem new file mode 100644 index 0000000..30aa936 --- /dev/null +++ b/media/certs/open-meteo-com_isrg-root-x1.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/media/icons/sunrise03.png b/media/icons/sunrise03.png new file mode 100644 index 0000000..a3f29ed Binary files /dev/null and b/media/icons/sunrise03.png differ diff --git a/media/icons/sunrise03.xcf b/media/icons/sunrise03.xcf new file mode 100644 index 0000000..02ee9d2 Binary files /dev/null and b/media/icons/sunrise03.xcf differ diff --git a/media/icons/sunrise03_mc.png b/media/icons/sunrise03_mc.png new file mode 100644 index 0000000..bfe805f Binary files /dev/null and b/media/icons/sunrise03_mc.png differ diff --git a/media/icons/sunrise03_mc.xcf b/media/icons/sunrise03_mc.xcf new file mode 100644 index 0000000..4c9a97f Binary files /dev/null and b/media/icons/sunrise03_mc.xcf differ diff --git a/media/icons/sunrise03_mc_i.png b/media/icons/sunrise03_mc_i.png new file mode 100644 index 0000000..ab34441 Binary files /dev/null and b/media/icons/sunrise03_mc_i.png differ diff --git a/media/icons/sunrise03_mc_i.xcf b/media/icons/sunrise03_mc_i.xcf new file mode 100644 index 0000000..066710a Binary files /dev/null and b/media/icons/sunrise03_mc_i.xcf differ diff --git a/pubspec.yaml b/pubspec.yaml index 03b4df2..3297e63 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: sunset_alarm description: "Set an alarm to go off a specified time before sunset." publish_to: 'none' -version: 1.0.0 +version: 1.0.1 environment: sdk: ^3.7.2 @@ -23,3 +23,5 @@ dev_dependencies: flutter: uses-material-design: true + assets: + - media/certs/