mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
7.4 KiB
Kotlin
186 lines
7.4 KiB
Kotlin
package com.todoroo.astrid.service
|
|
|
|
import android.content.Context
|
|
import com.todoroo.andlib.utility.DateUtilities
|
|
import com.todoroo.astrid.api.CaldavFilter
|
|
import com.todoroo.astrid.api.Filter
|
|
import com.todoroo.astrid.api.GtasksFilter
|
|
import com.todoroo.astrid.data.Task
|
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
import org.tasks.BuildConfig
|
|
import org.tasks.LocalBroadcastManager
|
|
import org.tasks.caldav.VtodoCache
|
|
import org.tasks.data.*
|
|
import org.tasks.db.DbUtils.dbchunk
|
|
import org.tasks.preferences.Preferences
|
|
import org.tasks.sync.SyncAdapters
|
|
import javax.inject.Inject
|
|
|
|
class TaskMover @Inject constructor(
|
|
@param:ApplicationContext private val context: Context,
|
|
private val taskDao: TaskDao,
|
|
private val caldavDao: CaldavDao,
|
|
private val googleTaskDao: GoogleTaskDao,
|
|
private val googleTaskListDao: GoogleTaskListDao,
|
|
private val preferences: Preferences,
|
|
private val localBroadcastManager: LocalBroadcastManager,
|
|
private val syncAdapters: SyncAdapters,
|
|
private val vtodoCache: VtodoCache,
|
|
) {
|
|
|
|
suspend fun getSingleFilter(tasks: List<Long>): Filter? {
|
|
val caldavCalendars = caldavDao.getCalendars(tasks)
|
|
val googleTaskLists = googleTaskDao.getLists(tasks)
|
|
if (caldavCalendars.isEmpty()) {
|
|
if (googleTaskLists.size == 1) {
|
|
return GtasksFilter(googleTaskListDao.getByRemoteId(googleTaskLists[0]))
|
|
}
|
|
} else if (googleTaskLists.isEmpty()) {
|
|
if (caldavCalendars.size == 1) {
|
|
return CaldavFilter(caldavDao.getCalendar(caldavCalendars[0]))
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
suspend fun move(ids: List<Long>, selectedList: Filter) {
|
|
val tasks = ids
|
|
.dbchunk()
|
|
.flatMap { taskDao.getChildren(it) }
|
|
.let { taskDao.fetch(ids.minus(it.toSet())) }
|
|
.filterNot { it.readOnly }
|
|
val taskIds = tasks.map { it.id }
|
|
taskDao.setParent(0, ids.intersect(taskIds.toSet()).toList())
|
|
tasks.forEach { performMove(it, selectedList) }
|
|
if (selectedList is CaldavFilter) {
|
|
caldavDao.updateParents(selectedList.uuid)
|
|
}
|
|
taskIds.dbchunk().forEach {
|
|
taskDao.touch(it)
|
|
}
|
|
localBroadcastManager.broadcastRefresh()
|
|
syncAdapters.sync()
|
|
}
|
|
|
|
suspend fun migrateLocalTasks() {
|
|
val list = caldavDao.getLocalList(context)
|
|
move(taskDao.getLocalTasks(), CaldavFilter(list))
|
|
}
|
|
|
|
private suspend fun performMove(task: Task, selectedList: Filter) {
|
|
googleTaskDao.getByTaskId(task.id)?.let {
|
|
moveGoogleTask(task, it, selectedList)
|
|
return
|
|
}
|
|
caldavDao.getTask(task.id)?.let {
|
|
moveCaldavTask(task, it, selectedList)
|
|
return
|
|
}
|
|
moveLocalTask(task, selectedList)
|
|
}
|
|
|
|
private suspend fun moveGoogleTask(task: Task, googleTask: CaldavTask, selected: Filter) {
|
|
if (selected is GtasksFilter && googleTask.calendar == selected.remoteId) {
|
|
return
|
|
}
|
|
val id = task.id
|
|
val children = taskDao.getChildren(id)
|
|
caldavDao.markDeleted(children + id, DateUtilities.now())
|
|
when(selected) {
|
|
is GtasksFilter -> {
|
|
val listId = selected.remoteId
|
|
googleTaskDao.insertAndShift(
|
|
task = task,
|
|
caldavTask = CaldavTask(id, listId, remoteId = null),
|
|
top = preferences.addTasksToTop()
|
|
)
|
|
children.takeIf { it.isNotEmpty() }
|
|
?.map { CaldavTask(task = it, calendar = listId, remoteId = null) }
|
|
?.let { googleTaskDao.insert(it) }
|
|
}
|
|
is CaldavFilter -> {
|
|
val listId = selected.uuid
|
|
val newParent = CaldavTask(id, listId)
|
|
caldavDao.insert(task, newParent, preferences.addTasksToTop())
|
|
children.map {
|
|
val newChild = CaldavTask(it, listId)
|
|
newChild.remoteParent = newParent.remoteId
|
|
newChild
|
|
}.let { caldavDao.insert(it) }
|
|
}
|
|
else -> require(!BuildConfig.DEBUG)
|
|
}
|
|
}
|
|
|
|
private suspend fun moveCaldavTask(task: Task, caldavTask: CaldavTask, selected: Filter) {
|
|
if (selected is CaldavFilter
|
|
&& caldavTask.calendar == selected.uuid) {
|
|
return
|
|
}
|
|
val id = task.id
|
|
val childIds = taskDao.getChildren(id)
|
|
val toDelete = arrayListOf(id)
|
|
var children: List<CaldavTask> = emptyList()
|
|
if (childIds.isNotEmpty()) {
|
|
children = caldavDao.getTasks(childIds)
|
|
toDelete.addAll(childIds)
|
|
}
|
|
caldavDao.markDeleted(toDelete, DateUtilities.now())
|
|
when (selected) {
|
|
is CaldavFilter -> {
|
|
val from = caldavDao.getCalendar(caldavTask.calendar!!)
|
|
val id1 = caldavTask.task
|
|
val listId = selected.uuid
|
|
val newParent = CaldavTask(id1, listId, caldavTask.remoteId, caldavTask.`object`)
|
|
vtodoCache.move(from!!, selected.calendar, caldavTask)
|
|
caldavDao.insert(task, newParent, preferences.addTasksToTop())
|
|
children.takeIf { it.isNotEmpty() }
|
|
?.map {
|
|
val newChild = CaldavTask(it.task, listId, it.remoteId, it.`object`)
|
|
vtodoCache.move(from, selected.calendar, it)
|
|
newChild.remoteParent = it.remoteParent
|
|
newChild
|
|
}
|
|
?.let { caldavDao.insert(it) }
|
|
}
|
|
is GtasksFilter -> moveToGoogleTasks(id, childIds, selected)
|
|
else -> require(!BuildConfig.DEBUG)
|
|
}
|
|
}
|
|
|
|
private suspend fun moveLocalTask(task: Task, selected: Filter) {
|
|
when (selected) {
|
|
is GtasksFilter -> moveToGoogleTasks(task.id, taskDao.getChildren(task.id), selected)
|
|
is CaldavFilter -> {
|
|
val id = task.id
|
|
val listId = selected.uuid
|
|
val tasks: MutableMap<Long, CaldavTask> = HashMap()
|
|
val root = CaldavTask(id, listId)
|
|
val children = taskDao.getChildren(id).mapNotNull { taskDao.fetch(it) }
|
|
for (child in children) {
|
|
val newTask = CaldavTask(child.id, listId)
|
|
val parent = child.parent
|
|
newTask.remoteParent = (if (parent == id) root else tasks[parent])!!.remoteId
|
|
tasks[child.id] = newTask
|
|
}
|
|
caldavDao.insert(task, root, preferences.addTasksToTop())
|
|
caldavDao.insert(tasks.values)
|
|
}
|
|
else -> require(!BuildConfig.DEBUG)
|
|
}
|
|
}
|
|
|
|
private suspend fun moveToGoogleTasks(id: Long, children: List<Long>, filter: GtasksFilter) {
|
|
val task = taskDao.fetch(id) ?: return
|
|
taskDao.setParent(id, children)
|
|
val listId = filter.remoteId
|
|
googleTaskDao.insertAndShift(
|
|
task,
|
|
CaldavTask(id, listId, remoteId = null),
|
|
preferences.addTasksToTop()
|
|
)
|
|
children.takeIf { it.isNotEmpty() }
|
|
?.map { CaldavTask(it, listId, remoteId = null) }
|
|
?.let { googleTaskDao.insert(it) }
|
|
}
|
|
} |