diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt
index 37fa11420..4f00f4d1f 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt
@@ -24,7 +24,7 @@ import android.content.Context
import org.isoron.uhabits.core.database.UnsupportedDatabaseVersionException
import org.isoron.uhabits.core.reminders.ReminderScheduler
import org.isoron.uhabits.core.ui.NotificationTray
-import org.isoron.uhabits.core.utils.DateUtils
+import org.isoron.uhabits.core.utils.DateUtils.Companion.setStartDayOffset
import org.isoron.uhabits.inject.AppContextModule
import org.isoron.uhabits.inject.DaggerHabitsApplicationComponent
import org.isoron.uhabits.inject.HabitsApplicationComponent
@@ -67,14 +67,22 @@ class HabitsApplication : Application() {
.habitsModule(HabitsModule(db))
.build()
- DateUtils.setStartDayOffset(3, 0)
+ val prefs = component.preferences
+ prefs.lastAppVersion = BuildConfig.VERSION_CODE
+
+ if (prefs.isMidnightDelayEnabled) {
+ setStartDayOffset(3, 0)
+ } else {
+ setStartDayOffset(0, 0)
+ }
val habitList = component.habitList
for (h in habitList) h.recompute()
- widgetUpdater = component.widgetUpdater
- widgetUpdater.startListening()
- widgetUpdater.scheduleStartDayWidgetUpdate()
+ widgetUpdater = component.widgetUpdater.apply {
+ startListening()
+ scheduleStartDayWidgetUpdate()
+ }
reminderScheduler = component.reminderScheduler
reminderScheduler.startListening()
@@ -82,9 +90,6 @@ class HabitsApplication : Application() {
notificationTray = component.notificationTray
notificationTray.startListening()
- val prefs = component.preferences
- prefs.lastAppVersion = BuildConfig.VERSION_CODE
-
val taskRunner = component.taskRunner
taskRunner.execute {
reminderScheduler.scheduleAll()
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/preferences/SharedPreferencesStorage.kt b/uhabits-android/src/main/java/org/isoron/uhabits/preferences/SharedPreferencesStorage.kt
index 279357858..1b4c51078 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/preferences/SharedPreferencesStorage.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/preferences/SharedPreferencesStorage.kt
@@ -86,6 +86,8 @@ class SharedPreferencesStorage
when (key) {
"pref_checkmark_reverse_order" ->
preferences.isCheckmarkSequenceReversed = getBoolean(key, false)
+ "pref_midnight_delay" ->
+ preferences.isMidnightDelayEnabled = getBoolean(key, false)
"pref_sticky_notifications" ->
preferences.setNotificationsSticky(getBoolean(key, false))
"pref_led_notifications" ->
diff --git a/uhabits-android/src/main/res/values/strings.xml b/uhabits-android/src/main/res/values/strings.xml
index 256184c37..67833a3cf 100644
--- a/uhabits-android/src/main/res/values/strings.xml
+++ b/uhabits-android/src/main/res/values/strings.xml
@@ -240,4 +240,6 @@
Differentiate days without data from actual lapses. To enter a lapse, toggle twice.
You are now a developer
No app was found to support this action
-
\ No newline at end of file
+ Extend day a few hours past midnight
+ Wait until 3:00 AM to show a new day. Useful if you typically go to sleep after midnight. N.B.: this setting will not take effect until you restart the app.
+
diff --git a/uhabits-android/src/main/res/xml/preferences.xml b/uhabits-android/src/main/res/xml/preferences.xml
index 21f25c263..835ccde84 100644
--- a/uhabits-android/src/main/res/xml/preferences.xml
+++ b/uhabits-android/src/main/res/xml/preferences.xml
@@ -31,6 +31,13 @@
android:title="@string/pref_toggle_title"
app:iconSpaceReserved="false" />
+
+
-
\ No newline at end of file
+
diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt
index 3923cf87a..7375e844e 100644
--- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt
+++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt
@@ -183,6 +183,13 @@ open class Preferences(private val storage: Storage) {
for (l in listeners) l.onCheckmarkSequenceChanged()
}
+ open var isMidnightDelayEnabled: Boolean
+ get() = storage.getBoolean("pref_midnight_delay", false)
+ set(enabled) {
+ storage.putBoolean("pref_midnight_delay", enabled)
+ for (l in listeners) l.onCheckmarkSequenceChanged()
+ }
+
fun updateLastHint(number: Int, timestamp: Timestamp) {
storage.putInt("last_hint_number", number)
storage.putLong("last_hint_timestamp", timestamp.unixTime)
diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/preferences/PreferencesTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/preferences/PreferencesTest.kt
index d73cf9bce..883ce2e98 100644
--- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/preferences/PreferencesTest.kt
+++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/preferences/PreferencesTest.kt
@@ -167,4 +167,12 @@ class PreferencesTest : BaseUnitTest() {
assertTrue(prefs.showArchived)
assertFalse(prefs.showCompleted)
}
+
+ @Test
+ @Throws(Exception::class)
+ fun testMidnightDelay() {
+ assertFalse(prefs.isMidnightDelayEnabled)
+ prefs.isMidnightDelayEnabled = true
+ assertTrue(prefs.isMidnightDelayEnabled)
+ }
}