From c7cc1583ac1c613cad7a5a51f895da1b1a2c18af Mon Sep 17 00:00:00 2001 From: powerjungle Date: Sun, 13 Apr 2025 12:24:26 +0200 Subject: [PATCH 1/3] feat(ui): new option to grey completed/entered habits Works the same way as hiding habits, but only changes the color. The reason this is useful, is because when a habit is treated as completed/entered, the cause might be just the frequency set for that habit. So, if it's once per month and you've entered it only once, till a month has passed the habit will be hidden, but the habit might've been done again within that month and it would be useful to be able to see it to enter that data. At some point it'll be good to change the darkest grey in the habit palet in "Edit habit", so that it doesn't conflict with the archived habit and "grey complete" colors. --- .../activities/habits/list/ListHabitsMenu.kt | 10 ++++++++ .../habits/list/views/HabitCardView.kt | 23 ++++++++++++++++--- .../src/main/res/menu/list_habits.xml | 6 +++++ .../src/main/res/values/strings.xml | 2 ++ .../uhabits/core/preferences/Preferences.kt | 5 ++++ .../habits/list/ListHabitsMenuBehavior.kt | 8 +++++++ .../core/preferences/PreferencesTest.kt | 3 +++ 7 files changed, 54 insertions(+), 3 deletions(-) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsMenu.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsMenu.kt index a70008d13..c7b6feb62 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsMenu.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsMenu.kt @@ -49,13 +49,17 @@ class ListHabitsMenu @Inject constructor( val nightModeItem = menu.findItem(R.id.actionToggleNightMode) val hideArchivedItem = menu.findItem(R.id.actionHideArchived) val hideCompletedItem = menu.findItem(R.id.actionHideCompleted) + val greyCompletedItem = menu.findItem(R.id.actionGreyCompleted) nightModeItem.isChecked = themeSwitcher.isNightMode hideArchivedItem.isChecked = !preferences.showArchived hideCompletedItem.isChecked = !preferences.showCompleted + greyCompletedItem.isChecked = preferences.greyCompleted if (preferences.areQuestionMarksEnabled || preferences.isSkipEnabled) { hideCompletedItem.title = activity.resources.getString(R.string.hide_entered) + greyCompletedItem.title = activity.resources.getString(R.string.grey_entered) } else { hideCompletedItem.title = activity.resources.getString(R.string.hide_completed) + greyCompletedItem.title = activity.resources.getString(R.string.grey_completed) } updateArrows(menu) } @@ -121,6 +125,12 @@ class ListHabitsMenu @Inject constructor( return true } + R.id.actionGreyCompleted -> { + behavior.onToggleGreyCompleted() + activity.invalidateOptionsMenu() + return true + } + R.id.actionSortColor -> { behavior.onSortByColor() return true diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt index eea1244eb..beb8e0418 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt @@ -35,14 +35,17 @@ import android.widget.FrameLayout import android.widget.LinearLayout import android.widget.TextView import org.isoron.platform.gui.toInt +import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.R import org.isoron.uhabits.activities.common.views.RingView import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.ModelObservable import org.isoron.uhabits.core.models.Timestamp +import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.inject.ActivityContext +import org.isoron.uhabits.inject.HabitsApplicationComponent import org.isoron.uhabits.utils.currentTheme import org.isoron.uhabits.utils.dp import org.isoron.uhabits.utils.sres @@ -123,7 +126,12 @@ class HabitCardView( numberPanel.notes = values } + private val appComponent: HabitsApplicationComponent = + (context.applicationContext as HabitsApplication).component + private val prefs: Preferences = appComponent.preferences + var checkmarkPanel: CheckmarkPanelView + private var numberPanel: NumberPanelView private var innerFrame: LinearLayout private var label: TextView @@ -264,10 +272,19 @@ class HabitCardView( private fun copyAttributesFrom(h: Habit) { fun getActiveColor(habit: Habit): Int { - return when (habit.isArchived) { - true -> sres.getColor(R.attr.contrast60) - false -> currentTheme().color(habit.color).toInt() + var retCol: Int = currentTheme().color(habit.color).toInt() + + if (habit.isArchived) { + retCol = sres.getColor(R.attr.contrast60) + } else if (prefs.greyCompleted) { + if (prefs.areQuestionMarksEnabled && habit.isEnteredToday()) { + retCol = sres.getColor(R.attr.contrast40) + } else if (!prefs.areQuestionMarksEnabled && habit.isCompletedToday()) { + retCol = sres.getColor(R.attr.contrast40) + } } + + return retCol } val c = getActiveColor(h) diff --git a/uhabits-android/src/main/res/menu/list_habits.xml b/uhabits-android/src/main/res/menu/list_habits.xml index 90eda8ca5..b9b5bc3f4 100644 --- a/uhabits-android/src/main/res/menu/list_habits.xml +++ b/uhabits-android/src/main/res/menu/list_habits.xml @@ -48,6 +48,12 @@ android:enabled="true" android:title="@string/hide_completed"/> + + None Filter Hide completed + Grey completed Hide entered + Grey entered Hide archived Make notifications sticky Prevents notifications from being swiped away. 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 6ba408cfd..39ad2d760 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 @@ -101,6 +101,11 @@ open class Preferences(private val storage: Storage) { set(showCompleted) { storage.putBoolean("pref_show_completed", showCompleted) } + var greyCompleted: Boolean + get() = storage.getBoolean("pref_grey_completed", false) + set(greyCompleted) { + storage.putBoolean("pref_grey_completed", greyCompleted) + } var theme: Int get() = storage.getInt("pref_theme", ThemeSwitcher.THEME_AUTOMATIC) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsMenuBehavior.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsMenuBehavior.kt index 7769dd32b..dcfd65183 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsMenuBehavior.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsMenuBehavior.kt @@ -31,6 +31,7 @@ class ListHabitsMenuBehavior @Inject constructor( private val themeSwitcher: ThemeSwitcher ) { private var showCompleted: Boolean + private var greyCompleted: Boolean private var showArchived: Boolean fun onCreateHabit() { @@ -61,6 +62,12 @@ class ListHabitsMenuBehavior @Inject constructor( updateAdapterFilter() } + fun onToggleGreyCompleted() { + greyCompleted = !greyCompleted + preferences.greyCompleted = greyCompleted + updateAdapterFilter() + } + fun onSortByManually() { adapter.primaryOrder = HabitList.Order.BY_POSITION } @@ -137,6 +144,7 @@ class ListHabitsMenuBehavior @Inject constructor( init { showCompleted = preferences.showCompleted + greyCompleted = preferences.greyCompleted showArchived = preferences.showArchived updateAdapterFilter() } 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 1dd2eace4..7202f3f61 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 @@ -156,10 +156,13 @@ class PreferencesTest : BaseUnitTest() { fun testFiltering() { assertFalse(prefs.showArchived) assertTrue(prefs.showCompleted) + assertFalse(prefs.greyCompleted) prefs.showArchived = true prefs.showCompleted = false + prefs.greyCompleted = true assertTrue(prefs.showArchived) assertFalse(prefs.showCompleted) + assertTrue(prefs.greyCompleted) } @Test From 97a1a58a39fadda29697ad23eefa0cd95d593b13 Mon Sep 17 00:00:00 2001 From: powerjungle Date: Sun, 13 Apr 2025 12:59:35 +0200 Subject: [PATCH 2/3] fix(ui): hacky fix for updating colors on grey completed setting change This is to avoid restarting the app to see the results, when changing the grey completed setting. --- .../core/ui/screens/habits/list/ListHabitsMenuBehavior.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsMenuBehavior.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsMenuBehavior.kt index dcfd65183..3a207b4a7 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsMenuBehavior.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsMenuBehavior.kt @@ -65,7 +65,7 @@ class ListHabitsMenuBehavior @Inject constructor( fun onToggleGreyCompleted() { greyCompleted = !greyCompleted preferences.greyCompleted = greyCompleted - updateAdapterFilter() + screen.applyTheme() } fun onSortByManually() { From d43fd52553da1738d41303a0e0af48d1d2b948a6 Mon Sep 17 00:00:00 2001 From: powerjungle Date: Sun, 13 Apr 2025 19:21:36 +0200 Subject: [PATCH 3/3] fix(ui): hacky fix for updating colors on show question marks setting change This only applies if the grey completed setting is enabled. This is to avoid restarting the app to see the resulting color change, when changing the show question marks setting. It'll be good to call `finish()` on the settings activity, to avoid stacking activities every time the setting is changed. --- .../uhabits/activities/habits/list/ListHabitsActivity.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt index d4e2ffa69..43f9ea09a 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt @@ -75,8 +75,12 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener { private lateinit var menu: ListHabitsMenu override fun onQuestionMarksChanged() { - invalidateOptionsMenu() - menu.behavior.onPreferencesChanged() + if (prefs.greyCompleted) { + restartWithFade(this::class.java) + } else { + invalidateOptionsMenu() + menu.behavior.onPreferencesChanged() + } } override fun onCreate(savedInstanceState: Bundle?) {