From be81a06e62579cc05976fd59803b151623c21e95 Mon Sep 17 00:00:00 2001 From: Dharanish Date: Sun, 7 Jul 2024 00:05:04 +0200 Subject: [PATCH] Sub habits and groups are filtered correctly --- .../org/isoron/uhabits/HabitsApplication.kt | 2 +- .../isoron/uhabits/core/models/HabitGroup.kt | 20 +++++++++++++- .../uhabits/core/models/HabitGroupList.kt | 27 +++---------------- .../models/memory/MemoryHabitGroupList.kt | 18 ++++++++++--- .../models/sqlite/SQLiteHabitGroupList.kt | 4 +++ .../screens/habits/list/HabitCardListCache.kt | 19 +++---------- .../screens/habits/list/ListHabitsBehavior.kt | 8 +++--- 7 files changed, 51 insertions(+), 47 deletions(-) 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 da242e3d2..b8421c5c1 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt @@ -81,7 +81,7 @@ class HabitsApplication : Application() { val habitGroupList = component.habitGroupList for (hgr in habitGroupList) hgr.recompute() - habitGroupList.populateGroupsWith(habitList) + habitGroupList.attachHabitsToGroups() widgetUpdater = component.widgetUpdater.apply { startListening() diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroup.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroup.kt index 629c76b8c..83f02dcc5 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroup.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroup.kt @@ -17,9 +17,27 @@ data class HabitGroup( val scores: ScoreList, val streaks: StreakList ) { + + constructor( + parent: HabitGroup, + matcher: HabitMatcher + ) : this( + parent.color, + parent.description, + parent.id, + parent.isArchived, + parent.name, + parent.position, + parent.question, + parent.reminder, + parent.uuid, + parent.habitList.getFiltered(matcher), + parent.scores, + parent.streaks + ) + init { if (uuid == null) this.uuid = UUID.randomUUID().toString().replace("-", "") -// habitList.groupID = this.id } var observable = ModelObservable() diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroupList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroupList.kt index 471e0b62f..376deb81e 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroupList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroupList.kt @@ -166,31 +166,10 @@ abstract class HabitGroupList : Iterable { } /** - * For an empty Habit group list, and a given list of habits, - * populate the habit groups with their appropriate habits - * - * @param habitList list of habits to add to the groups + * For each habit group, point all the habits in it + * to the group it is contained in * */ - fun populateGroupsWith(habitList: HabitList) { - val toRemove = mutableListOf() - for (habit in habitList) { - val hgr = getByUUID(habit.parentUUID) - if (hgr != null) { - hgr.habitList.add(habit) - habit.parent = hgr - toRemove.add(habit.uuid) - } - } - for (uuid in toRemove) { - val h = habitList.getByUUID(uuid) - if (h != null) { - habitList.remove(h) - } - } - for (hgr in this) { - hgr.recompute() - } - } + abstract fun attachHabitsToGroups() /** * Writes the list of habit groups to the given writer, in CSV format. There is diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt index 983514a4b..732119513 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt @@ -45,6 +45,9 @@ class MemoryHabitGroupList : HabitGroupList { primaryOrder = parent.primaryOrder secondaryOrder = parent.secondaryOrder parent.observable.addListener { loadFromParent() } + for (hgr in parent.list) { + hgr.habitList.observable.addListener { loadFromParent() } + } loadFromParent() } @@ -184,6 +187,14 @@ class MemoryHabitGroupList : HabitGroupList { resort() } + override fun attachHabitsToGroups() { + for (hgr in list) { + for (h in hgr.habitList) { + h.parent = hgr + } + } + } + private fun throwIfHasParent() { check(parent == null) { "Filtered lists cannot be modified directly. " + @@ -195,9 +206,10 @@ class MemoryHabitGroupList : HabitGroupList { private fun loadFromParent() { checkNotNull(parent) list.clear() - for (h in parent!!) { - if (filter.matches(h)) { - list.add(h) + for (hgr in parent!!) { + if (filter.matches(hgr)) { + val filteredHgr = HabitGroup(hgr, filter) + list.add(filteredHgr) } } resort() diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt index 6fd62d7cb..4ec45595f 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt @@ -189,6 +189,10 @@ class SQLiteHabitGroupList @Inject constructor(private val modelFactory: ModelFa observable.notifyListeners() } + override fun attachHabitsToGroups() { + list.attachHabitsToGroups() + } + override fun resort() { list.resort() observable.notifyListeners() diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HabitCardListCache.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HabitCardListCache.kt index 173ed700c..a5c5100bd 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HabitCardListCache.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HabitCardListCache.kt @@ -68,7 +68,6 @@ class HabitCardListCache @Inject constructor( private val data: CacheData private var filteredHabits: HabitList private var filteredHabitGroups: HabitGroupList - private var filteredSubHabits: MutableList private val taskRunner: TaskRunner @Synchronized @@ -157,7 +156,6 @@ class HabitCardListCache @Inject constructor( habitGroups.primaryOrder = order filteredHabits.primaryOrder = order filteredHabitGroups.primaryOrder = order - filteredSubHabits.forEach { it.primaryOrder = order } refreshAllHabits() } @@ -170,7 +168,6 @@ class HabitCardListCache @Inject constructor( habitGroups.secondaryOrder = order filteredHabits.secondaryOrder = order filteredHabitGroups.secondaryOrder = order - filteredSubHabits.forEach { it.secondaryOrder = order } refreshAllHabits() } @@ -246,8 +243,9 @@ class HabitCardListCache @Inject constructor( val hgrIdx = data.habitGroups.indexOf(hgr) for (habit in data.subHabits[hgrIdx].reversed()) { + val habitPos = data.uuidToPosition[habit.uuid]!! data.removeWithUUID(habit.uuid) - listener.onItemRemoved(data.uuidToPosition[habit.uuid]!!) + listener.onItemRemoved(habitPos) } data.subHabits.removeAt(hgrIdx) data.habitGroups.removeAt(hgrIdx) @@ -279,10 +277,6 @@ class HabitCardListCache @Inject constructor( fun setFilter(matcher: HabitMatcher) { filteredHabits = habits.getFiltered(matcher) filteredHabitGroups = habitGroups.getFiltered(matcher) - filteredSubHabits.clear() - for (hgr in filteredHabitGroups) { - filteredSubHabits.add(hgr.habitList.getFiltered(matcher)) - } } @Synchronized @@ -369,11 +363,11 @@ class HabitCardListCache @Inject constructor( habits.add(h) } - for ((index, hgr) in filteredHabitGroups.withIndex()) { + for (hgr in filteredHabitGroups) { if (hgr.uuid == null) continue habitGroups.add(hgr) val habitList = LinkedList() - for (h in filteredSubHabits[index]) { + for (h in hgr.habitList) { habitList.add(h) } subHabits.add(habitList) @@ -780,11 +774,6 @@ class HabitCardListCache @Inject constructor( init { filteredHabits = habits filteredHabitGroups = habitGroups - filteredSubHabits = LinkedList() - for (hgr in habitGroups) { - val subList = hgr.habitList - filteredSubHabits.add(subList) - } this.taskRunner = taskRunner listener = object : Listener {} diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt index 4e35841e9..7690d4e12 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt @@ -60,6 +60,7 @@ open class ListHabitsBehavior @Inject constructor( } fun onEdit(habit: Habit, timestamp: Timestamp?) { + val list = if (habit.isSubHabit()) habit.parent!!.habitList else habitList val entry = habit.computedEntries.get(timestamp!!) if (habit.type == HabitType.NUMERICAL) { val oldValue = entry.value.toDouble() / 1000 @@ -73,7 +74,7 @@ open class ListHabitsBehavior @Inject constructor( screen.showConfetti(habit.color, x, y) } } - commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value, newNotes)) + commandRunner.run(CreateRepetitionCommand(list, habit, timestamp, value, newNotes)) } } else { screen.showCheckmarkPopup( @@ -82,7 +83,7 @@ open class ListHabitsBehavior @Inject constructor( habit.color ) { newValue: Int, newNotes: String, x: Float, y: Float -> if (newValue != entry.value && newValue == YES_MANUAL) screen.showConfetti(habit.color, x, y) - commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, newValue, newNotes)) + commandRunner.run(CreateRepetitionCommand(list, habit, timestamp, newValue, newNotes)) } } } @@ -138,8 +139,9 @@ open class ListHabitsBehavior @Inject constructor( } fun onToggle(habit: Habit, timestamp: Timestamp, value: Int, notes: String, x: Float, y: Float) { + val list = if (habit.isSubHabit()) habit.parent!!.habitList else habitList commandRunner.run( - CreateRepetitionCommand(habitList, habit, timestamp, value, notes) + CreateRepetitionCommand(list, habit, timestamp, value, notes) ) if (value == YES_MANUAL) screen.showConfetti(habit.color, x, y) }