From eafa6ffa5f74d5931ae3c58ed2c13cc89224a2be Mon Sep 17 00:00:00 2001 From: Hyperling Date: Sun, 1 Nov 2026 15:07:31 -0700 Subject: [PATCH 01/17] changelog, update to match release. --- CHANGELOG.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dd07e4..4d15c11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,10 @@ Usability improvements. - allows showing text without crowding out or hiding minutes field - fix monochrome icons, source was not white which may have been causing issues - begin creating tar files for Linux rather than zips, will use zstd on release -- begin using a proper release signature rather that flutter's debug. -- update internal plugin versions. +- begin using a proper release signature rather that flutter's debug +- update internal plugin versions -This version may require uninstalling any previous versions before updating -due to the signature change. It is a one-time event. +This version may require uninstalling any previous versions before updating due to the signature change. It is a one-time event. ## 1.0.1 (2026-09-29) -- 2.54.0 From 14c75e83313e79b400d941d768c389c7e5834fa7 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Sun, 1 Nov 2026 15:07:45 -0700 Subject: [PATCH 02/17] gitignore, add release and build files. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index a82d757..791d5a7 100644 --- a/.gitignore +++ b/.gitignore @@ -122,6 +122,9 @@ app.*.symbols # Gradle files .gradle/ build/ +android/app/release/* +android/build/* +android/app/build/* # Local configuration file (sdk path, etc) local.properties -- 2.54.0 From 7eaa2dc3a4aa1c0e49e44f4a5c1582f263c4b1b6 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Tue, 10 Nov 2026 19:57:33 -0700 Subject: [PATCH 03/17] main, attempt to reschedule alarm for next day after the current day goes off. --- lib/main.dart | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index e15ad51..e200183 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'dart:async'; +import 'package:alarm/utils/alarm_set.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -29,6 +30,7 @@ void main() async { tz.initializeTimeZones(); await Alarm.init(); + runApp(const SunsetAlarmApp()); } @@ -93,13 +95,20 @@ class _HomeScreenState extends State { super.initState(); _initNotifications(); _loadPrefs(); + + // Reschedule alarm any time one goes off. + Alarm.ringing.listen((AlarmSet alarmSet) { + for (final alarm in alarmSet.alarms) { + if (alarm.id == _alarmId) _scheduleAlarm(); + } + }); } Future _initNotifications() async { const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const iosInit = DarwinInitializationSettings(); const linuxInit = LinuxInitializationSettings( - defaultActionName: 'Sunset Alarm', + defaultActionName: 'Sunset Alarm ', ); await _notifications.initialize( settings: const InitializationSettings( @@ -300,9 +309,9 @@ class _HomeScreenState extends State { androidScheduleMode: AndroidScheduleMode.alarmClock, ); _showSnack('Alarm scheduled!'); - debugPrint('DEBUG: Alarm time: ${tzAlarm.toString()}'); - debugPrint('DEBUG: Current time: ${DateTime.now().toUtc().toString()}'); - debugPrint('DEBUG: ${_notifications.toString()}'); + _debug('Alarm time: ${tzAlarm.toString()}'); + _debug('Current time: ${DateTime.now().toUtc().toString()}'); + _debug('${_notifications.toString()}'); } // End Notification Method ***/ @@ -366,6 +375,14 @@ class _HomeScreenState extends State { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); } + void _log(String tag, String msg) { + debugPrint(tag + ": " + msg); + } + + void _debug(String msg) { + _log("DEBUG", msg); + } + @override void dispose() { _savePrefs(); -- 2.54.0 From e163a2e2908e5e3bbdcd6571698596f317cc9b2f Mon Sep 17 00:00:00 2001 From: Hyperling Date: Tue, 10 Nov 2026 20:33:33 -0700 Subject: [PATCH 04/17] main, add output to see if the alarm going off really does schedule the next alarm. --- lib/main.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/main.dart b/lib/main.dart index e200183..ae22a3b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -249,6 +249,8 @@ class _HomeScreenState extends State { alarmTime = alarmTime.add(const Duration(days: 1)); } + _debug("_scheduleAlarm, alarmTime=" + alarmTime.toIso8601String()); + if (Platform.isLinux) { // Linux: use a Timer (app must stay open) _alarmTimer?.cancel(); -- 2.54.0 From 66f42a514122c4432e4c88b22cfea8bb57bf2ee7 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Tue, 10 Nov 2026 20:34:04 -0700 Subject: [PATCH 05/17] build, add flutter proguard file. --- android/app/build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 37c461c..b697149 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -55,7 +55,8 @@ android { isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" + "proguard-rules.pro", + "flutter_proguard_rules.pro" ) /// 20260928 - With minifying, helped some, but also used -- 2.54.0 From cfd0ca514d30aba21a3378aac4f6b193f432db78 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Tue, 10 Nov 2026 20:34:30 -0700 Subject: [PATCH 06/17] settings, fix typo in comment. --- android/settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts index 94e510e..ff898be 100644 --- a/android/settings.gradle.kts +++ b/android/settings.gradle.kts @@ -21,7 +21,7 @@ plugins { id("com.android.application") version "9.5.0" apply false - // This will need removed in Gradle/AGP 9. JK - needs to exist otherwiese: + // This will need removed in Gradle/AGP 9. JK - needs to exist otherwise: // "Error: Your project's Kotlin version (2.2.10) is lower than Flutter's minimum supported version of 2.2.20." id("org.jetbrains.kotlin.android") version "2.4.21" apply false } -- 2.54.0 From 08e9ff66b758403180d3a133f135dc7d1ef754e8 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Tue, 10 Nov 2026 20:35:04 -0700 Subject: [PATCH 07/17] Upgrade Gradle (9.8.2 -> 9.9.0). --- android/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 6b23797..f67093b 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Sep 12 19:36:23 MST 2026 +#Tue Nov 10 20:28:41 MST 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.9.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -- 2.54.0 From f212f9927bf916e52a3e5134902607b52bc6c037 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 08:13:28 -0700 Subject: [PATCH 08/17] Upgrade AGP. --- android/settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts index ff898be..5858ba5 100644 --- a/android/settings.gradle.kts +++ b/android/settings.gradle.kts @@ -19,7 +19,7 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "9.5.0" apply false + id("com.android.application") version "9.5.1" apply false // This will need removed in Gradle/AGP 9. JK - needs to exist otherwise: // "Error: Your project's Kotlin version (2.2.10) is lower than Flutter's minimum supported version of 2.2.20." -- 2.54.0 From 8adaecbf7dc9a8728df70f49c60d48d2a55d0195 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 08:13:50 -0700 Subject: [PATCH 09/17] Android Studio or Flutter changes. --- android/gradle/wrapper/gradle-wrapper.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index f67093b..94c356a 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,9 @@ -#Tue Nov 10 20:28:41 MST 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-9.9.0-bin.zip +networkTimeout=10000 +retries=0 +retryBackOffMs=500 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -- 2.54.0 From f0b723e15825c88dbd3536c4fef3119871ed86cf Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 08:14:47 -0700 Subject: [PATCH 10/17] main, fix rescheduling by making each day's alarm ID unique so that it does not cancel the alarm currently going off. --- lib/main.dart | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index ae22a3b..dbc0c53 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -88,7 +88,12 @@ class _HomeScreenState extends State { String? _minuteErrorText; bool _validTime = false; - static const _alarmId = 1001; + static int _alarmId = 20260000; + + int dateAsId(DateTime d) => d.year * 10000 + d.month * 100 + d.day; + int todayAsId() { + return dateAsId(DateTime.now()); + } @override void initState() { @@ -99,7 +104,10 @@ class _HomeScreenState extends State { // Reschedule alarm any time one goes off. Alarm.ringing.listen((AlarmSet alarmSet) { for (final alarm in alarmSet.alarms) { - if (alarm.id == _alarmId) _scheduleAlarm(); + if (alarm.id == todayAsId()) { + _scheduleAlarm(); + break; + } } }); } @@ -249,7 +257,9 @@ class _HomeScreenState extends State { alarmTime = alarmTime.add(const Duration(days: 1)); } - _debug("_scheduleAlarm, alarmTime=" + alarmTime.toIso8601String()); + _debug("_scheduleAlarm, alarmTime=${alarmTime.toIso8601String()}"); + _alarmId = dateAsId(alarmTime); + _debug("_alarmId=$_alarmId"); if (Platform.isLinux) { // Linux: use a Timer (app must stay open) @@ -338,6 +348,16 @@ class _HomeScreenState extends State { icon: 'ic_notification', ), ); + + // Skip if tomorrow's alarm already exists. + final existing = await Alarm.getAlarm(_alarmId); + if (existing == settings) { + _debug( + "Alarm already exists, skipping schedule. ${settings.toString()}", + ); + return; + } + await Alarm.set(alarmSettings: settings); } // End Alarm Method ***/ @@ -363,11 +383,13 @@ class _HomeScreenState extends State { } else if (Platform.isAndroid) { // Notification Method if (ANDROID_USE_NOTIF) { - await _notifications.cancel(id: _alarmId); + //await _notifications.cancel(id: _alarmId); + await _notifications.cancelAll(); } // Alarm Method if (ANDROID_USE_ALARM) { - await Alarm.stop(_alarmId); + //await Alarm.stop(_alarmId); + await Alarm.stopAll(); } } _showSnack('Alarm Cancelled'); -- 2.54.0 From 3bb3123a129a9827ee755ca9e0dd99a73bfbb574 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 08:24:04 -0700 Subject: [PATCH 11/17] main, add alarm ID to switch text for now so we can see which date it's for. --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index dbc0c53..a50957d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -619,7 +619,7 @@ class _HomeScreenState extends State { child: Text( _validTime ? _alarmEnabled - ? "${_minutesBefore} Minute${_plural} Before @ $_alarmDisplayTime" + ? "${_minutesBefore} Minute${_plural} Before @ $_alarmId $_alarmDisplayTime" : "Sunset Alarm" : "Enter Valid Time", ), -- 2.54.0 From e04aa9f447d40328d75b9252218212ec3f22bca4 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 08:36:26 -0700 Subject: [PATCH 12/17] main, ensure the alarm ID gets refreshed on the screen by using setState() at the end of the function. --- lib/main.dart | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index a50957d..dda8f84 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -63,6 +63,11 @@ class SunsetAlarmApp extends StatelessWidget { } } +int dateAsId(DateTime d) => d.year * 10000 + d.month * 100 + d.day; +int todayAsId() { + return dateAsId(DateTime.now()); +} + class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @@ -88,12 +93,7 @@ class _HomeScreenState extends State { String? _minuteErrorText; bool _validTime = false; - static int _alarmId = 20260000; - - int dateAsId(DateTime d) => d.year * 10000 + d.month * 100 + d.day; - int todayAsId() { - return dateAsId(DateTime.now()); - } + int _alarmId = 20260000; @override void initState() { @@ -365,6 +365,10 @@ class _HomeScreenState extends State { } else { _showSnack('Platform Not Detected - Contact Developer'); } + // If we made it this far, refresh the alarm ID on the screen. + setState(() { + _alarmId = _alarmId; + }); } Future _toggleAlarm(bool value) async { @@ -623,6 +627,7 @@ class _HomeScreenState extends State { : "Sunset Alarm" : "Enter Valid Time", ), + // .toString().replaceRange(4, 4, '-').replaceRange(7, 7, '-') ), value: _validTime ? _alarmEnabled : false, onChanged: _validTime ? _toggleAlarm : null, -- 2.54.0 From b6ae6b1f10ac7d88e297ac839f20e8aa30623aa1 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 08:44:49 -0700 Subject: [PATCH 13/17] changelog, add working version. --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1744311..b164276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog -## 1.1.0 (In Development) +## 1.2.0 (In Development) + +- Automatically enable next day's alarm when the current day's is activated. +- Add the alarm's date to the SwitchTile text for confirming it's truly set. + +## 1.1.0 (2026-11-01) Usability improvements. -- 2.54.0 From 17d69fb3a7614f042caba71826f82fec0db1db82 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 08:45:16 -0700 Subject: [PATCH 14/17] pubspec, increment version. --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 8c5597d..5425037 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.1.0 +version: 1.2.0 environment: sdk: ^3.7.2 -- 2.54.0 From 8060c0755ac11e005cbe4b30abb37ef11a365334 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 18:57:47 -0700 Subject: [PATCH 15/17] main, reword notification time for smaller screens and add dashes back in. --- lib/main.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index dda8f84..cf1058d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -623,11 +623,11 @@ class _HomeScreenState extends State { child: Text( _validTime ? _alarmEnabled - ? "${_minutesBefore} Minute${_plural} Before @ $_alarmId $_alarmDisplayTime" + ? "Scheduled @ ${_alarmId.toString().replaceRange(4, 4, '-').replaceRange(7, 7, '-')} $_alarmDisplayTime" : "Sunset Alarm" : "Enter Valid Time", ), - // .toString().replaceRange(4, 4, '-').replaceRange(7, 7, '-') + // ), value: _validTime ? _alarmEnabled : false, onChanged: _validTime ? _toggleAlarm : null, -- 2.54.0 From fb76a04c58a6765f1dac4cbc7af4bc3dd4671620 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 19:03:53 -0700 Subject: [PATCH 16/17] main, keep the alarm scheduled even if app is killed. --- lib/main.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/main.dart b/lib/main.dart index cf1058d..4fae997 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -347,6 +347,7 @@ class _HomeScreenState extends State { stopButton: 'Dismiss', icon: 'ic_notification', ), + androidStopAlarmOnTermination: false, ); // Skip if tomorrow's alarm already exists. -- 2.54.0 From e7b5dd768ce02a27d3653d51ae74dc8a44132fcb Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 11 Nov 2026 19:08:55 -0700 Subject: [PATCH 17/17] main, remove extra space added when trying to get VS Codium and Flutter to sync. --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 4fae997..8c487c3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -116,7 +116,7 @@ class _HomeScreenState extends State { const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const iosInit = DarwinInitializationSettings(); const linuxInit = LinuxInitializationSettings( - defaultActionName: 'Sunset Alarm ', + defaultActionName: 'Sunset Alarm', ); await _notifications.initialize( settings: const InitializationSettings( -- 2.54.0