mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-14 04:58:52 -06:00
Implement habit group score ring, sorting sub habits (except with score)
This commit is contained in:
@@ -97,6 +97,7 @@ class HabitCardView(
|
||||
set(value) {
|
||||
scoreRing.setPercentage(value.toFloat())
|
||||
scoreRing.setPrecision(1.0f / 16)
|
||||
behavior.onChangeScore(habit!!)
|
||||
}
|
||||
|
||||
var unit
|
||||
|
||||
@@ -26,6 +26,13 @@ data class DeleteHabitsCommand(
|
||||
val selected: List<Habit>
|
||||
) : Command {
|
||||
override fun run() {
|
||||
for (h in selected) habitList.remove(h)
|
||||
for (h in selected) {
|
||||
if (!h.isSubHabit()) {
|
||||
habitList.remove(h)
|
||||
} else {
|
||||
val list = h.parent!!.habitList
|
||||
list.remove(h)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2021 Álinson Santos Xavier <git@axavier.org>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.isoron.uhabits.core.commands
|
||||
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.HabitGroupList
|
||||
|
||||
data class RefreshParentGroupCommand(
|
||||
val habit: Habit,
|
||||
val habitGroupList: HabitGroupList
|
||||
) : Command {
|
||||
override fun run() {
|
||||
if (!habit.isSubHabit()) return
|
||||
val hgr = habit.parent
|
||||
hgr!!.recompute()
|
||||
habitGroupList.resort()
|
||||
}
|
||||
}
|
||||
@@ -113,10 +113,6 @@ data class Habit(
|
||||
return computedEntries.getKnown().lastOrNull()?.timestamp ?: DateUtils.getTodayWithOffset()
|
||||
}
|
||||
|
||||
fun isInGroup(): Boolean {
|
||||
return (parentID != null)
|
||||
}
|
||||
|
||||
fun copyFrom(other: Habit) {
|
||||
this.color = other.color
|
||||
this.description = other.description
|
||||
|
||||
@@ -214,49 +214,46 @@ class HabitCardListCache @Inject constructor(
|
||||
|
||||
@Synchronized
|
||||
fun remove(uuid: String) {
|
||||
val type = data.positionTypes[data.uuidToPosition[uuid]!!]
|
||||
val position = data.uuidToPosition[uuid] ?: return
|
||||
val type = data.positionTypes[position]
|
||||
if (type == STANDALONE_HABIT) {
|
||||
val h = data.uuidToHabit[uuid]
|
||||
if (h != null) {
|
||||
val position = data.habits.indexOf(h)
|
||||
data.habits.removeAt(position)
|
||||
data.checkmarks.remove(uuid)
|
||||
data.notes.remove(uuid)
|
||||
data.scores.remove(uuid)
|
||||
data.decrementPositions(position + 1, data.positionTypes.size)
|
||||
listener.onItemRemoved(position)
|
||||
val pos = data.habits.indexOf(h)
|
||||
data.habits.removeAt(pos)
|
||||
data.removeWithUUID(uuid)
|
||||
data.positionTypes.removeAt(pos)
|
||||
data.decrementPositions(pos + 1, data.positionTypes.size)
|
||||
listener.onItemRemoved(pos)
|
||||
}
|
||||
} else if (type == SUB_HABIT) {
|
||||
val h = data.uuidToHabit[uuid]
|
||||
if (h != null) {
|
||||
val position = data.uuidToPosition[uuid]!!
|
||||
val pos = data.uuidToPosition[uuid]!!
|
||||
val hgrUUID = h.parentUUID
|
||||
val hgr = data.uuidToHabitGroup[hgrUUID]
|
||||
val hgrIdx = data.habitGroups.indexOf(hgr)
|
||||
data.subHabits[hgrIdx].remove(h)
|
||||
data.checkmarks.remove(uuid)
|
||||
data.notes.remove(uuid)
|
||||
data.scores.remove(uuid)
|
||||
data.decrementPositions(position + 1, data.positionTypes.size)
|
||||
listener.onItemRemoved(position)
|
||||
data.removeWithUUID(uuid)
|
||||
data.positionTypes.removeAt(pos)
|
||||
data.decrementPositions(pos + 1, data.positionTypes.size)
|
||||
listener.onItemRemoved(pos)
|
||||
}
|
||||
} else if (type == HABIT_GROUP) {
|
||||
val hgr = data.uuidToHabitGroup[uuid]
|
||||
if (hgr != null) {
|
||||
val position = data.uuidToPosition[uuid]!!
|
||||
val pos = data.uuidToPosition[uuid]!!
|
||||
val hgrIdx = data.habitGroups.indexOf(hgr)
|
||||
|
||||
for (habit in data.subHabits[hgrIdx].reversed()) {
|
||||
data.checkmarks.remove(habit.uuid)
|
||||
data.notes.remove(habit.uuid)
|
||||
data.scores.remove(habit.uuid)
|
||||
data.removeWithUUID(habit.uuid)
|
||||
listener.onItemRemoved(data.uuidToPosition[habit.uuid]!!)
|
||||
}
|
||||
data.subHabits.removeAt(hgrIdx)
|
||||
data.habitGroups.removeAt(hgrIdx)
|
||||
data.scores.remove(hgr.uuid)
|
||||
data.removeWithUUID(hgr.uuid)
|
||||
data.rebuildPositions()
|
||||
listener.onItemRemoved(position)
|
||||
listener.onItemRemoved(pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -466,7 +463,6 @@ class HabitCardListCache @Inject constructor(
|
||||
|
||||
@Synchronized
|
||||
fun decrementPositions(fromPosition: Int, toPosition: Int) {
|
||||
positionTypes.removeAt(fromPosition)
|
||||
for (pos in positionToHabit.keys.sortedBy { it }) {
|
||||
if (pos in fromPosition..toPosition) {
|
||||
positionToHabit[pos - 1] = positionToHabit[pos]!!
|
||||
@@ -508,10 +504,11 @@ class HabitCardListCache @Inject constructor(
|
||||
|
||||
if (type == STANDALONE_HABIT) {
|
||||
habits.removeAt(fromPosition)
|
||||
positionTypes.removeAt(fromPosition)
|
||||
if (fromPosition < checkedToPosition) {
|
||||
decrementPositions(fromPosition + 1, checkedToPosition)
|
||||
} else {
|
||||
incrementPositions(toPosition, fromPosition - 1)
|
||||
incrementPositions(checkedToPosition, fromPosition - 1)
|
||||
}
|
||||
habits.add(checkedToPosition, habit)
|
||||
positionTypes.add(checkedToPosition, STANDALONE_HABIT)
|
||||
@@ -520,10 +517,11 @@ class HabitCardListCache @Inject constructor(
|
||||
val hgrIdx = habitGroups.indexOf(hgr)
|
||||
val h = positionToHabit[fromPosition]!!
|
||||
subHabits[hgrIdx].remove(h)
|
||||
positionTypes.removeAt(fromPosition)
|
||||
if (fromPosition < checkedToPosition) {
|
||||
decrementPositions(fromPosition + 1, checkedToPosition)
|
||||
} else {
|
||||
incrementPositions(toPosition, fromPosition - 1)
|
||||
incrementPositions(checkedToPosition, fromPosition - 1)
|
||||
}
|
||||
subHabits[hgrIdx].add(checkedToPosition - uuidToPosition[hgr!!.uuid]!! - 1, habit)
|
||||
positionTypes.add(checkedToPosition, SUB_HABIT)
|
||||
@@ -556,6 +554,15 @@ class HabitCardListCache @Inject constructor(
|
||||
listener.onItemMoved(fromPosition, toPosition)
|
||||
}
|
||||
|
||||
fun removeWithUUID(uuid: String?) {
|
||||
uuidToPosition.remove(uuid)
|
||||
uuidToHabit.remove(uuid)
|
||||
uuidToHabitGroup.remove(uuid)
|
||||
scores.remove(uuid)
|
||||
notes.remove(uuid)
|
||||
checkmarks.remove(uuid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CacheData without any content.
|
||||
*/
|
||||
@@ -654,10 +661,6 @@ class HabitCardListCache @Inject constructor(
|
||||
data.habits.add(position, habit)
|
||||
data.positionTypes.add(position, STANDALONE_HABIT)
|
||||
} else {
|
||||
// val parent = data.uuidToHabitGroup[habit.parentUUID]
|
||||
// val parentIdx = data.habitGroups.indexOf(parent)
|
||||
// val parentPosition = data.uuidToPosition[habit.parentUUID]!!
|
||||
// data.subHabits[parentIdx].add(position - parentPosition - 1, habit)
|
||||
data.positionTypes.add(position, SUB_HABIT)
|
||||
}
|
||||
data.incrementPositions(position, data.positionTypes.size - 1)
|
||||
|
||||
@@ -20,9 +20,11 @@ package org.isoron.uhabits.core.ui.screens.habits.list
|
||||
|
||||
import org.isoron.uhabits.core.commands.CommandRunner
|
||||
import org.isoron.uhabits.core.commands.CreateRepetitionCommand
|
||||
import org.isoron.uhabits.core.commands.RefreshParentGroupCommand
|
||||
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.HabitGroup
|
||||
import org.isoron.uhabits.core.models.HabitGroupList
|
||||
import org.isoron.uhabits.core.models.HabitList
|
||||
import org.isoron.uhabits.core.models.HabitType
|
||||
import org.isoron.uhabits.core.models.NumericalHabitType.AT_LEAST
|
||||
@@ -41,6 +43,7 @@ import kotlin.math.roundToInt
|
||||
|
||||
open class ListHabitsBehavior @Inject constructor(
|
||||
private val habitList: HabitList,
|
||||
private val habitGroupList: HabitGroupList,
|
||||
private val dirFinder: DirFinder,
|
||||
private val taskRunner: TaskRunner,
|
||||
private val screen: Screen,
|
||||
@@ -141,6 +144,12 @@ open class ListHabitsBehavior @Inject constructor(
|
||||
if (value == YES_MANUAL) screen.showConfetti(habit.color, x, y)
|
||||
}
|
||||
|
||||
fun onChangeScore(habit: Habit) {
|
||||
commandRunner.run(
|
||||
RefreshParentGroupCommand(habit, habitGroupList)
|
||||
)
|
||||
}
|
||||
|
||||
enum class Message {
|
||||
COULD_NOT_EXPORT,
|
||||
IMPORT_SUCCESSFUL,
|
||||
|
||||
@@ -95,8 +95,8 @@ class ListHabitsSelectionMenuBehavior @Inject constructor(
|
||||
{
|
||||
adapter.performRemove(adapter.getSelectedHabits())
|
||||
adapter.performRemoveHabitGroup(adapter.getSelectedHabitGroups())
|
||||
commandRunner.run(DeleteHabitsCommand(habitList, adapter.getSelectedHabits()))
|
||||
commandRunner.run(DeleteHabitGroupsCommand(habitGroupList, adapter.getSelectedHabitGroups()))
|
||||
commandRunner.run(DeleteHabitsCommand(habitList, adapter.getSelectedHabits()))
|
||||
adapter.clearSelection()
|
||||
},
|
||||
adapter.getSelectedHabits().size + adapter.getSelectedHabitGroups().size
|
||||
|
||||
Reference in New Issue
Block a user