mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-14 21:18:51 -06:00
Implement option to remove sub habits from groups
This commit is contained in:
@@ -300,7 +300,7 @@ class EditHabitActivity : AppCompatActivity() {
|
|||||||
habit.unit = binding.unitInput.text.trim().toString()
|
habit.unit = binding.unitInput.text.trim().toString()
|
||||||
}
|
}
|
||||||
habit.type = habitType
|
habit.type = habitType
|
||||||
habit.parent = parentGroup
|
habit.group = parentGroup
|
||||||
habit.groupId = parentGroup?.id
|
habit.groupId = parentGroup?.id
|
||||||
habit.groupUUID = parentGroup?.uuid
|
habit.groupUUID = parentGroup?.uuid
|
||||||
|
|
||||||
|
|||||||
@@ -75,12 +75,14 @@ class ListHabitsSelectionMenu @Inject constructor(
|
|||||||
val itemColor = menu.findItem(R.id.action_color)
|
val itemColor = menu.findItem(R.id.action_color)
|
||||||
val itemArchive = menu.findItem(R.id.action_archive_habit)
|
val itemArchive = menu.findItem(R.id.action_archive_habit)
|
||||||
val itemUnarchive = menu.findItem(R.id.action_unarchive_habit)
|
val itemUnarchive = menu.findItem(R.id.action_unarchive_habit)
|
||||||
|
val itemRemoveFromGroup = menu.findItem(R.id.action_remove_from_group)
|
||||||
val itemNotify = menu.findItem(R.id.action_notify)
|
val itemNotify = menu.findItem(R.id.action_notify)
|
||||||
|
|
||||||
itemColor.isVisible = true
|
itemColor.isVisible = true
|
||||||
itemEdit.isVisible = behavior.canEdit()
|
itemEdit.isVisible = behavior.canEdit()
|
||||||
itemArchive.isVisible = behavior.canArchive()
|
itemArchive.isVisible = behavior.canArchive()
|
||||||
itemUnarchive.isVisible = behavior.canUnarchive()
|
itemUnarchive.isVisible = behavior.canUnarchive()
|
||||||
|
itemRemoveFromGroup.isVisible = behavior.areSubHabits()
|
||||||
itemNotify.isVisible = prefs.isDeveloper
|
itemNotify.isVisible = prefs.isDeveloper
|
||||||
activeActionMode?.title = (listAdapter.selectedHabits.size + listAdapter.selectedHabitGroups.size).toString()
|
activeActionMode?.title = (listAdapter.selectedHabits.size + listAdapter.selectedHabitGroups.size).toString()
|
||||||
return true
|
return true
|
||||||
@@ -106,6 +108,11 @@ class ListHabitsSelectionMenu @Inject constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.action_remove_from_group -> {
|
||||||
|
behavior.onRemoveFromGroup()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
R.id.action_delete -> {
|
R.id.action_delete -> {
|
||||||
behavior.onDeleteHabits()
|
behavior.onDeleteHabits()
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ class HabitCardView(
|
|||||||
set(value) {
|
set(value) {
|
||||||
scoreRing.setPercentage(value.toFloat())
|
scoreRing.setPercentage(value.toFloat())
|
||||||
scoreRing.setPrecision(1.0f / 16)
|
scoreRing.setPrecision(1.0f / 16)
|
||||||
// behavior.onChangeScore(habit!!)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var unit
|
var unit
|
||||||
|
|||||||
@@ -41,6 +41,11 @@
|
|||||||
android:title="@string/unarchive"
|
android:title="@string/unarchive"
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_remove_from_group"
|
||||||
|
android:title="@string/remove_from_group"
|
||||||
|
app:showAsAction="never"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_delete"
|
android:id="@+id/action_delete"
|
||||||
android:title="@string/delete"
|
android:title="@string/delete"
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
<string name="archive">Archive</string>
|
<string name="archive">Archive</string>
|
||||||
<string name="unarchive">Unarchive</string>
|
<string name="unarchive">Unarchive</string>
|
||||||
|
<string name="remove_from_group">Remove from group</string>
|
||||||
<string name="add_habit">Add habit</string>
|
<string name="add_habit">Add habit</string>
|
||||||
<string name="color_picker_default_title">Change color</string>
|
<string name="color_picker_default_title">Change color</string>
|
||||||
<string name="toast_habit_created">Habit created</string>
|
<string name="toast_habit_created">Habit created</string>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ data class DeleteHabitsCommand(
|
|||||||
if (!h.isSubHabit()) {
|
if (!h.isSubHabit()) {
|
||||||
habitList.remove(h)
|
habitList.remove(h)
|
||||||
} else {
|
} else {
|
||||||
val list = (h.parent as HabitGroup).habitList
|
val list = (h.group as HabitGroup).habitList
|
||||||
list.remove(h)
|
list.remove(h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ data class RefreshParentGroupCommand(
|
|||||||
) : Command {
|
) : Command {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (!habit.isSubHabit()) return
|
if (!habit.isSubHabit()) return
|
||||||
val hgr = habit.parent
|
val hgr = habit.group
|
||||||
hgr!!.recompute()
|
hgr!!.recompute()
|
||||||
habitGroupList.resort()
|
habitGroupList.resort()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.HabitList
|
||||||
|
|
||||||
|
data class RemoveFromGroupCommand(
|
||||||
|
val habitList: HabitList,
|
||||||
|
val selected: List<Habit>
|
||||||
|
) : Command {
|
||||||
|
override fun run() {
|
||||||
|
for (habit in selected) {
|
||||||
|
val hgr = habit.group!!
|
||||||
|
hgr.habitList.remove(habit)
|
||||||
|
habit.groupId = null
|
||||||
|
habit.group = null
|
||||||
|
habit.groupUUID = null
|
||||||
|
habitList.add(habit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@ data class Habit(
|
|||||||
if (uuid == null) this.uuid = UUID.randomUUID().toString().replace("-", "")
|
if (uuid == null) this.uuid = UUID.randomUUID().toString().replace("-", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
var parent: HabitGroup? = null
|
var group: HabitGroup? = null
|
||||||
var observable = ModelObservable()
|
var observable = ModelObservable()
|
||||||
|
|
||||||
val isNumerical: Boolean
|
val isNumerical: Boolean
|
||||||
@@ -128,7 +128,7 @@ data class Habit(
|
|||||||
this.type = other.type
|
this.type = other.type
|
||||||
this.unit = other.unit
|
this.unit = other.unit
|
||||||
this.uuid = other.uuid
|
this.uuid = other.uuid
|
||||||
this.parent = other.parent
|
this.group = other.group
|
||||||
this.groupId = other.groupId
|
this.groupId = other.groupId
|
||||||
this.groupUUID = other.groupUUID
|
this.groupUUID = other.groupUUID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ class MemoryHabitGroupList : HabitGroupList {
|
|||||||
override fun attachHabitsToGroups() {
|
override fun attachHabitsToGroups() {
|
||||||
for (hgr in list) {
|
for (hgr in list) {
|
||||||
for (h in hgr.habitList) {
|
for (h in hgr.habitList) {
|
||||||
h.parent = hgr
|
h.group = hgr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +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 list = if (habit.isSubHabit()) habit.group!!.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
|
||||||
@@ -114,8 +114,8 @@ open class ListHabitsBehavior @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onReorderHabit(from: Habit, to: Habit) {
|
fun onReorderHabit(from: Habit, to: Habit) {
|
||||||
if (from.parent == to.parent) {
|
if (from.group == to.group) {
|
||||||
val list = from.parent?.habitList ?: habitList
|
val list = from.group?.habitList ?: habitList
|
||||||
taskRunner.execute { list.reorder(from, to) }
|
taskRunner.execute { list.reorder(from, to) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ 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
|
val list = if (habit.isSubHabit()) habit.group!!.habitList else habitList
|
||||||
commandRunner.run(
|
commandRunner.run(
|
||||||
CreateRepetitionCommand(list, habit, timestamp, value, notes)
|
CreateRepetitionCommand(list, habit, timestamp, value, notes)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.isoron.uhabits.core.commands.CommandRunner
|
|||||||
import org.isoron.uhabits.core.commands.DeleteHabitGroupsCommand
|
import org.isoron.uhabits.core.commands.DeleteHabitGroupsCommand
|
||||||
import org.isoron.uhabits.core.commands.DeleteHabitsCommand
|
import org.isoron.uhabits.core.commands.DeleteHabitsCommand
|
||||||
import org.isoron.uhabits.core.commands.RefreshParentGroupCommand
|
import org.isoron.uhabits.core.commands.RefreshParentGroupCommand
|
||||||
|
import org.isoron.uhabits.core.commands.RemoveFromGroupCommand
|
||||||
import org.isoron.uhabits.core.commands.UnarchiveHabitsCommand
|
import org.isoron.uhabits.core.commands.UnarchiveHabitsCommand
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.models.HabitGroup
|
import org.isoron.uhabits.core.models.HabitGroup
|
||||||
@@ -59,6 +60,11 @@ class ListHabitsSelectionMenuBehavior @Inject constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun areSubHabits(): Boolean {
|
||||||
|
if (adapter.getSelectedHabitGroups().isNotEmpty()) return false
|
||||||
|
return (adapter.getSelectedHabits().all { it.isSubHabit() })
|
||||||
|
}
|
||||||
|
|
||||||
fun onArchiveHabits() {
|
fun onArchiveHabits() {
|
||||||
commandRunner.run(ArchiveHabitsCommand(habitList, adapter.getSelectedHabits()))
|
commandRunner.run(ArchiveHabitsCommand(habitList, adapter.getSelectedHabits()))
|
||||||
commandRunner.run(ArchiveHabitGroupsCommand(habitGroupList, adapter.getSelectedHabitGroups()))
|
commandRunner.run(ArchiveHabitGroupsCommand(habitGroupList, adapter.getSelectedHabitGroups()))
|
||||||
@@ -130,6 +136,12 @@ class ListHabitsSelectionMenuBehavior @Inject constructor(
|
|||||||
adapter.clearSelection()
|
adapter.clearSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onRemoveFromGroup() {
|
||||||
|
adapter.performRemove(adapter.getSelectedHabits())
|
||||||
|
commandRunner.run(RemoveFromGroupCommand(habitList, adapter.getSelectedHabits()))
|
||||||
|
adapter.clearSelection()
|
||||||
|
}
|
||||||
|
|
||||||
interface Adapter {
|
interface Adapter {
|
||||||
fun clearSelection()
|
fun clearSelection()
|
||||||
fun getSelectedHabits(): List<Habit>
|
fun getSelectedHabits(): List<Habit>
|
||||||
|
|||||||
Reference in New Issue
Block a user