mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-14 21:18:51 -06:00
Sub habits and groups are filtered correctly
This commit is contained in:
@@ -81,7 +81,7 @@ class HabitsApplication : Application() {
|
|||||||
|
|
||||||
val habitGroupList = component.habitGroupList
|
val habitGroupList = component.habitGroupList
|
||||||
for (hgr in habitGroupList) hgr.recompute()
|
for (hgr in habitGroupList) hgr.recompute()
|
||||||
habitGroupList.populateGroupsWith(habitList)
|
habitGroupList.attachHabitsToGroups()
|
||||||
|
|
||||||
widgetUpdater = component.widgetUpdater.apply {
|
widgetUpdater = component.widgetUpdater.apply {
|
||||||
startListening()
|
startListening()
|
||||||
|
|||||||
@@ -17,9 +17,27 @@ data class HabitGroup(
|
|||||||
val scores: ScoreList,
|
val scores: ScoreList,
|
||||||
val streaks: StreakList
|
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 {
|
init {
|
||||||
if (uuid == null) this.uuid = UUID.randomUUID().toString().replace("-", "")
|
if (uuid == null) this.uuid = UUID.randomUUID().toString().replace("-", "")
|
||||||
// habitList.groupID = this.id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var observable = ModelObservable()
|
var observable = ModelObservable()
|
||||||
|
|||||||
@@ -166,31 +166,10 @@ abstract class HabitGroupList : Iterable<HabitGroup> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For an empty Habit group list, and a given list of habits,
|
* For each habit group, point all the habits in it
|
||||||
* populate the habit groups with their appropriate habits
|
* to the group it is contained in
|
||||||
*
|
|
||||||
* @param habitList list of habits to add to the groups
|
|
||||||
* */
|
* */
|
||||||
fun populateGroupsWith(habitList: HabitList) {
|
abstract fun attachHabitsToGroups()
|
||||||
val toRemove = mutableListOf<String?>()
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the list of habit groups to the given writer, in CSV format. There is
|
* Writes the list of habit groups to the given writer, in CSV format. There is
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ class MemoryHabitGroupList : HabitGroupList {
|
|||||||
primaryOrder = parent.primaryOrder
|
primaryOrder = parent.primaryOrder
|
||||||
secondaryOrder = parent.secondaryOrder
|
secondaryOrder = parent.secondaryOrder
|
||||||
parent.observable.addListener { loadFromParent() }
|
parent.observable.addListener { loadFromParent() }
|
||||||
|
for (hgr in parent.list) {
|
||||||
|
hgr.habitList.observable.addListener { loadFromParent() }
|
||||||
|
}
|
||||||
loadFromParent()
|
loadFromParent()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +187,14 @@ class MemoryHabitGroupList : HabitGroupList {
|
|||||||
resort()
|
resort()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun attachHabitsToGroups() {
|
||||||
|
for (hgr in list) {
|
||||||
|
for (h in hgr.habitList) {
|
||||||
|
h.parent = hgr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun throwIfHasParent() {
|
private fun throwIfHasParent() {
|
||||||
check(parent == null) {
|
check(parent == null) {
|
||||||
"Filtered lists cannot be modified directly. " +
|
"Filtered lists cannot be modified directly. " +
|
||||||
@@ -195,9 +206,10 @@ class MemoryHabitGroupList : HabitGroupList {
|
|||||||
private fun loadFromParent() {
|
private fun loadFromParent() {
|
||||||
checkNotNull(parent)
|
checkNotNull(parent)
|
||||||
list.clear()
|
list.clear()
|
||||||
for (h in parent!!) {
|
for (hgr in parent!!) {
|
||||||
if (filter.matches(h)) {
|
if (filter.matches(hgr)) {
|
||||||
list.add(h)
|
val filteredHgr = HabitGroup(hgr, filter)
|
||||||
|
list.add(filteredHgr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resort()
|
resort()
|
||||||
|
|||||||
@@ -189,6 +189,10 @@ class SQLiteHabitGroupList @Inject constructor(private val modelFactory: ModelFa
|
|||||||
observable.notifyListeners()
|
observable.notifyListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun attachHabitsToGroups() {
|
||||||
|
list.attachHabitsToGroups()
|
||||||
|
}
|
||||||
|
|
||||||
override fun resort() {
|
override fun resort() {
|
||||||
list.resort()
|
list.resort()
|
||||||
observable.notifyListeners()
|
observable.notifyListeners()
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ class HabitCardListCache @Inject constructor(
|
|||||||
private val data: CacheData
|
private val data: CacheData
|
||||||
private var filteredHabits: HabitList
|
private var filteredHabits: HabitList
|
||||||
private var filteredHabitGroups: HabitGroupList
|
private var filteredHabitGroups: HabitGroupList
|
||||||
private var filteredSubHabits: MutableList<HabitList>
|
|
||||||
private val taskRunner: TaskRunner
|
private val taskRunner: TaskRunner
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@@ -157,7 +156,6 @@ class HabitCardListCache @Inject constructor(
|
|||||||
habitGroups.primaryOrder = order
|
habitGroups.primaryOrder = order
|
||||||
filteredHabits.primaryOrder = order
|
filteredHabits.primaryOrder = order
|
||||||
filteredHabitGroups.primaryOrder = order
|
filteredHabitGroups.primaryOrder = order
|
||||||
filteredSubHabits.forEach { it.primaryOrder = order }
|
|
||||||
refreshAllHabits()
|
refreshAllHabits()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +168,6 @@ class HabitCardListCache @Inject constructor(
|
|||||||
habitGroups.secondaryOrder = order
|
habitGroups.secondaryOrder = order
|
||||||
filteredHabits.secondaryOrder = order
|
filteredHabits.secondaryOrder = order
|
||||||
filteredHabitGroups.secondaryOrder = order
|
filteredHabitGroups.secondaryOrder = order
|
||||||
filteredSubHabits.forEach { it.secondaryOrder = order }
|
|
||||||
refreshAllHabits()
|
refreshAllHabits()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,8 +243,9 @@ class HabitCardListCache @Inject constructor(
|
|||||||
val hgrIdx = data.habitGroups.indexOf(hgr)
|
val hgrIdx = data.habitGroups.indexOf(hgr)
|
||||||
|
|
||||||
for (habit in data.subHabits[hgrIdx].reversed()) {
|
for (habit in data.subHabits[hgrIdx].reversed()) {
|
||||||
|
val habitPos = data.uuidToPosition[habit.uuid]!!
|
||||||
data.removeWithUUID(habit.uuid)
|
data.removeWithUUID(habit.uuid)
|
||||||
listener.onItemRemoved(data.uuidToPosition[habit.uuid]!!)
|
listener.onItemRemoved(habitPos)
|
||||||
}
|
}
|
||||||
data.subHabits.removeAt(hgrIdx)
|
data.subHabits.removeAt(hgrIdx)
|
||||||
data.habitGroups.removeAt(hgrIdx)
|
data.habitGroups.removeAt(hgrIdx)
|
||||||
@@ -279,10 +277,6 @@ class HabitCardListCache @Inject constructor(
|
|||||||
fun setFilter(matcher: HabitMatcher) {
|
fun setFilter(matcher: HabitMatcher) {
|
||||||
filteredHabits = habits.getFiltered(matcher)
|
filteredHabits = habits.getFiltered(matcher)
|
||||||
filteredHabitGroups = habitGroups.getFiltered(matcher)
|
filteredHabitGroups = habitGroups.getFiltered(matcher)
|
||||||
filteredSubHabits.clear()
|
|
||||||
for (hgr in filteredHabitGroups) {
|
|
||||||
filteredSubHabits.add(hgr.habitList.getFiltered(matcher))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@@ -369,11 +363,11 @@ class HabitCardListCache @Inject constructor(
|
|||||||
habits.add(h)
|
habits.add(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((index, hgr) in filteredHabitGroups.withIndex()) {
|
for (hgr in filteredHabitGroups) {
|
||||||
if (hgr.uuid == null) continue
|
if (hgr.uuid == null) continue
|
||||||
habitGroups.add(hgr)
|
habitGroups.add(hgr)
|
||||||
val habitList = LinkedList<Habit>()
|
val habitList = LinkedList<Habit>()
|
||||||
for (h in filteredSubHabits[index]) {
|
for (h in hgr.habitList) {
|
||||||
habitList.add(h)
|
habitList.add(h)
|
||||||
}
|
}
|
||||||
subHabits.add(habitList)
|
subHabits.add(habitList)
|
||||||
@@ -780,11 +774,6 @@ class HabitCardListCache @Inject constructor(
|
|||||||
init {
|
init {
|
||||||
filteredHabits = habits
|
filteredHabits = habits
|
||||||
filteredHabitGroups = habitGroups
|
filteredHabitGroups = habitGroups
|
||||||
filteredSubHabits = LinkedList()
|
|
||||||
for (hgr in habitGroups) {
|
|
||||||
val subList = hgr.habitList
|
|
||||||
filteredSubHabits.add(subList)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.taskRunner = taskRunner
|
this.taskRunner = taskRunner
|
||||||
listener = object : Listener {}
|
listener = object : Listener {}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ open class ListHabitsBehavior @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onEdit(habit: Habit, timestamp: Timestamp?) {
|
fun onEdit(habit: Habit, timestamp: Timestamp?) {
|
||||||
|
val list = if (habit.isSubHabit()) habit.parent!!.habitList else habitList
|
||||||
val entry = habit.computedEntries.get(timestamp!!)
|
val entry = habit.computedEntries.get(timestamp!!)
|
||||||
if (habit.type == HabitType.NUMERICAL) {
|
if (habit.type == HabitType.NUMERICAL) {
|
||||||
val oldValue = entry.value.toDouble() / 1000
|
val oldValue = entry.value.toDouble() / 1000
|
||||||
@@ -73,7 +74,7 @@ open class ListHabitsBehavior @Inject constructor(
|
|||||||
screen.showConfetti(habit.color, x, y)
|
screen.showConfetti(habit.color, x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value, newNotes))
|
commandRunner.run(CreateRepetitionCommand(list, habit, timestamp, value, newNotes))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
screen.showCheckmarkPopup(
|
screen.showCheckmarkPopup(
|
||||||
@@ -82,7 +83,7 @@ open class ListHabitsBehavior @Inject constructor(
|
|||||||
habit.color
|
habit.color
|
||||||
) { newValue: Int, newNotes: String, x: Float, y: Float ->
|
) { newValue: Int, newNotes: String, x: Float, y: Float ->
|
||||||
if (newValue != entry.value && newValue == YES_MANUAL) screen.showConfetti(habit.color, x, y)
|
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) {
|
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(
|
commandRunner.run(
|
||||||
CreateRepetitionCommand(habitList, habit, timestamp, value, notes)
|
CreateRepetitionCommand(list, habit, timestamp, value, notes)
|
||||||
)
|
)
|
||||||
if (value == YES_MANUAL) screen.showConfetti(habit.color, x, y)
|
if (value == YES_MANUAL) screen.showConfetti(habit.color, x, y)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user