Move canMove/min/max logic into TaskAdapter

pull/996/head
Alex Baker 4 years ago
parent 2568383a71
commit 8816270653

@ -6,22 +6,6 @@ import org.tasks.data.TaskContainer
import org.tasks.date.DateTimeUtils.toAppleEpoch
open class CaldavTaskAdapter internal constructor(private val taskDao: TaskDao, private val caldavDao: CaldavDao, private val newTasksOnTop: Boolean = false) : TaskAdapter() {
override fun canMove(source: TaskContainer, from: Int, target: TaskContainer, to: Int) = !taskIsChild(source, to)
override fun maxIndent(previousPosition: Int, task: TaskContainer) = getTask(previousPosition).getIndent() + 1
override fun minIndent(nextPosition: Int, task: TaskContainer): Int {
(nextPosition until count).forEach {
if (isHeader(it)) {
return 0
}
if (!taskIsChild(task, it)) {
return getTask(it).indent
}
}
return 0
}
override fun supportsParentingOrManualSort() = true
override fun moved(from: Int, to: Int, indent: Int) {
@ -42,25 +26,8 @@ open class CaldavTaskAdapter internal constructor(private val taskDao: TaskDao,
}
internal fun changeParent(task: TaskContainer, indent: Int, to: Int): Long {
val previous = if (to > 0) getTask(to - 1) else null
val newParent = when {
indent == 0 || previous == null -> 0
indent == previous.getIndent() -> previous.parent
indent > previous.getIndent() -> previous.id
else -> {
var newParent = previous.parent
var currentIndex = to
for (i in 0 until previous.getIndent() - indent) {
var thisParent = newParent
while (newParent == thisParent) {
thisParent = getTask(--currentIndex).parent
}
newParent = thisParent
}
newParent
}
}
if (newParent != task.parent) {
val newParent = findParent(indent, to)?.id ?: 0
if (task.parent != newParent) {
changeParent(task, newParent)
}
return newParent
@ -79,18 +46,4 @@ open class CaldavTaskAdapter internal constructor(private val taskDao: TaskDao,
caldavDao.update(caldavTask.cd_id, caldavTask.cd_remote_parent)
taskDao.save(task.getTask(), null)
}
private fun taskIsChild(source: TaskContainer, destinationIndex: Int): Boolean {
(destinationIndex downTo 0).forEach {
if (isHeader(it)) {
return false
}
when (getTask(it).parent) {
0L -> return false
source.parent -> return false
source.id -> return true
}
}
return false
}
}

@ -3,46 +3,15 @@ package com.todoroo.astrid.adapter
import com.todoroo.astrid.dao.TaskDao
import org.tasks.BuildConfig
import org.tasks.data.GoogleTaskDao
import org.tasks.data.TaskContainer
open class GoogleTaskAdapter internal constructor(private val taskDao: TaskDao, private val googleTaskDao: GoogleTaskDao, private val newTasksOnTop: Boolean) : TaskAdapter() {
override fun canMove(source: TaskContainer, from: Int, target: TaskContainer, to: Int): Boolean {
return if (!source.hasChildren() || to <= 0 || to >= count - 1) {
true
} else if (from < to) {
when {
target.hasChildren() -> false
target.hasParent() -> !getTask(to + 1).hasParent()
else -> true
}
} else {
when {
target.hasChildren() -> true
target.hasParent() -> target.parent == source.id && target.secondarySort == 0L
else -> true
}
}
}
override fun maxIndent(previousPosition: Int, task: TaskContainer) = if (task.hasChildren()) 0 else 1
override fun minIndent(nextPosition: Int, task: TaskContainer) = if (task.hasChildren() || !getTask(nextPosition).hasParent()) 0 else 1
override fun supportsParentingOrManualSort() = true
override fun moved(from: Int, to: Int, indent: Int) {
val task = getTask(from)
val googleTask = task.googleTask
if (indent == 0) {
if (googleTask.indent == 0) {
return
}
googleTaskDao.move(
googleTask, 0, if (newTasksOnTop) 0 else googleTaskDao.getBottom(googleTask.listId, 0))
} else {
val previous = if (to > 0) getTask(to - 1) else null
val newParent = if (previous!!.hasParent()) previous.parent else previous.id
val newParent = findParent(indent, to)?.id ?: 0
if (googleTask.parent == newParent) {
return
}
@ -50,7 +19,6 @@ open class GoogleTaskAdapter internal constructor(private val taskDao: TaskDao,
googleTask,
newParent,
if (newTasksOnTop) 0 else googleTaskDao.getBottom(googleTask.listId, newParent))
}
taskDao.touch(task.id)
if (BuildConfig.DEBUG) {
googleTaskDao.validateSorting(task.googleTaskList!!)

@ -4,7 +4,9 @@ import com.todoroo.astrid.dao.TaskDao
import org.tasks.BuildConfig
import org.tasks.data.GoogleTaskDao
class GoogleTaskManualSortAdapter internal constructor(val taskDao: TaskDao, val googleTaskDao: GoogleTaskDao) : GoogleTaskAdapter(taskDao, googleTaskDao, false) {
class GoogleTaskManualSortAdapter internal constructor(val taskDao: TaskDao, val googleTaskDao: GoogleTaskDao) : TaskAdapter() {
override fun supportsParentingOrManualSort() = true
override fun supportsManualSorting() = true

@ -45,11 +45,52 @@ open class TaskAdapter {
open fun getIndent(task: TaskContainer): Int = task.getIndent()
open fun canMove(source: TaskContainer, from: Int, target: TaskContainer, to: Int): Boolean = false
open fun canMove(source: TaskContainer, from: Int, target: TaskContainer, to: Int): Boolean {
if (target.isGoogleTask) {
return if (!source.hasChildren() || to <= 0 || to >= count - 1) {
true
} else if (from < to) {
when {
target.hasChildren() -> false
target.hasParent() -> !getTask(to + 1).hasParent()
else -> true
}
} else {
when {
target.hasChildren() -> true
target.hasParent() -> target.parent == source.id && target.secondarySort == 0L
else -> true
}
}
} else {
return !taskIsChild(source, to)
}
}
open fun maxIndent(previousPosition: Int, task: TaskContainer): Int = 0
open fun maxIndent(previousPosition: Int, task: TaskContainer): Int {
val previous = getTask(previousPosition)
return if (previous.isGoogleTask) {
if (task.hasChildren()) 0 else 1
} else {
previous.indent + 1
}
}
open fun minIndent(nextPosition: Int, task: TaskContainer): Int = 0
fun minIndent(nextPosition: Int, task: TaskContainer): Int {
(nextPosition until count).forEach {
if (isHeader(it)) {
return 0
}
val next = getTask(it)
if (next.isGoogleTask) {
return if (task.hasChildren() || !next.hasParent()) 0 else 1
}
if (!taskIsChild(task, it)) {
return next.indent
}
}
return 0
}
fun isSelected(task: TaskContainer): Boolean = selected.contains(task.id)
@ -89,4 +130,31 @@ open class TaskAdapter {
open fun onTaskDeleted(task: Task) {}
open fun supportsHiddenTasks(): Boolean = true
private fun taskIsChild(source: TaskContainer, destinationIndex: Int): Boolean {
(destinationIndex downTo 0).forEach {
if (isHeader(it)) {
return false
}
when (getTask(it).parent) {
0L -> return false
source.parent -> return false
source.id -> return true
}
}
return false
}
internal fun findParent(indent: Int, to: Int): TaskContainer? {
if (indent == 0 || to == 0) {
return null
}
for (i in to - 1 downTo 0) {
val previous = getTask(i)
if (indent > previous.getIndent()) {
return previous
}
}
return null
}
}

@ -5,6 +5,8 @@ import android.view.ViewGroup
import androidx.core.util.Pair
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.ItemTouchHelper.*
import androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags
import androidx.recyclerview.widget.ListUpdateCallback
import androidx.recyclerview.widget.RecyclerView
import com.todoroo.andlib.utility.AndroidUtilities
@ -113,7 +115,7 @@ class DragAndDropRecyclerAdapter(
private var to = -1
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
super.onSelectedChanged(viewHolder, actionState)
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
if (actionState == ACTION_STATE_DRAG) {
taskList.startActionMode()
(viewHolder as TaskViewHolder?)!!.isMoving = true
dragging = true
@ -123,12 +125,11 @@ class DragAndDropRecyclerAdapter(
}
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
return if (adapter.isHeader(viewHolder.adapterPosition)) {
makeMovementFlags(0, 0)
} else if (adapter.supportsParentingOrManualSort() && adapter.numSelected == 0) {
makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT, 0)
} else {
makeMovementFlags(0, 0)
return when {
!dragAndDropEnabled() -> NO_MOVEMENT
adapter.isHeader(viewHolder.adapterPosition) -> NO_MOVEMENT
adapter.numSelected > 0 -> NO_MOVEMENT
else -> ALLOW_DRAGGING
}
}
@ -177,7 +178,7 @@ class DragAndDropRecyclerAdapter(
val vh = viewHolder as TaskViewHolder
val task = vh.task
val shiftSize = vh.shiftSize
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
if (actionState == ACTION_STATE_DRAG) {
val currentIndent = viewHolder.indent
val maxIndent = vh.maxIndent
val minIndent = vh.minIndent
@ -255,6 +256,8 @@ class DragAndDropRecyclerAdapter(
companion object {
private const val LONG_LIST_SIZE = 500
private val NO_MOVEMENT = makeMovementFlags(0, 0)
private val ALLOW_DRAGGING = makeMovementFlags(UP or DOWN or LEFT or RIGHT, 0)
}
init {

Loading…
Cancel
Save