diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskMover.java b/app/src/main/java/com/todoroo/astrid/service/TaskMover.java deleted file mode 100644 index 05b50b636..000000000 --- a/app/src/main/java/com/todoroo/astrid/service/TaskMover.java +++ /dev/null @@ -1,229 +0,0 @@ -package com.todoroo.astrid.service; - -import static com.google.common.collect.FluentIterable.from; -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.Lists.transform; -import static com.todoroo.andlib.utility.DateUtilities.now; -import static java.util.Collections.emptyList; - -import android.content.Context; -import androidx.annotation.NonNull; -import com.todoroo.astrid.api.CaldavFilter; -import com.todoroo.astrid.api.Filter; -import com.todoroo.astrid.api.GtasksFilter; -import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Task; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.inject.Inject; -import org.tasks.BuildConfig; -import org.tasks.LocalBroadcastManager; -import org.tasks.data.CaldavCalendar; -import org.tasks.data.CaldavDao; -import org.tasks.data.CaldavTask; -import org.tasks.data.GoogleTask; -import org.tasks.data.GoogleTaskDao; -import org.tasks.data.GoogleTaskListDao; -import org.tasks.injection.ForApplication; -import org.tasks.preferences.Preferences; - -public class TaskMover { - - private final Context context; - private final TaskDao taskDao; - private final CaldavDao caldavDao; - private final GoogleTaskDao googleTaskDao; - private final GoogleTaskListDao googleTaskListDao; - private final Preferences preferences; - private final LocalBroadcastManager localBroadcastManager; - - @Inject - public TaskMover( - @ForApplication Context context, - TaskDao taskDao, - CaldavDao caldavDao, - GoogleTaskDao googleTaskDao, - GoogleTaskListDao googleTaskListDao, - Preferences preferences, - LocalBroadcastManager localBroadcastManager) { - this.context = context; - this.taskDao = taskDao; - this.caldavDao = caldavDao; - this.googleTaskDao = googleTaskDao; - this.googleTaskListDao = googleTaskListDao; - this.preferences = preferences; - this.localBroadcastManager = localBroadcastManager; - } - - public Filter getSingleFilter(List tasks) { - List caldavCalendars = caldavDao.getCalendars(tasks); - List googleTaskLists = googleTaskDao.getLists(tasks); - if (caldavCalendars.isEmpty()) { - if (googleTaskLists.size() == 1) { - return new GtasksFilter(googleTaskListDao.getByRemoteId(googleTaskLists.get(0))); - } - } else if (googleTaskLists.isEmpty()) { - if (caldavCalendars.size() == 1) { - return new CaldavFilter(caldavDao.getCalendar(caldavCalendars.get(0))); - } - } - return null; - } - - public void move(List tasks, @NonNull Filter selectedList) { - tasks = new ArrayList<>(tasks); - tasks.removeAll(googleTaskDao.findChildrenInList(tasks)); - tasks.removeAll(taskDao.findChildrenInList(tasks)); - taskDao.setParent(0, tasks); - for (Task task : taskDao.fetch(tasks)) { - performMove(task, selectedList); - } - if (selectedList instanceof CaldavFilter) { - caldavDao.updateParents((((CaldavFilter) selectedList).getUuid())); - } - taskDao.touch(tasks); - localBroadcastManager.broadcastRefresh(); - } - - public void migrateLocalTasks() { - CaldavCalendar list = caldavDao.getLocalList(context); - move(taskDao.getLocalTasks(), new CaldavFilter(list)); - } - - private void performMove(Task task, @NonNull Filter selectedList) { - long id = task.getId(); - - GoogleTask googleTask = googleTaskDao.getByTaskId(id); - if (googleTask != null) { - moveGoogleTask(task, googleTask, selectedList); - return; - } - - CaldavTask caldavTask = caldavDao.getTask(id); - if (caldavTask != null) { - moveCaldavTask(task, caldavTask, selectedList); - return; - } - - moveLocalTask(task, selectedList); - } - - private void moveGoogleTask(Task task, GoogleTask googleTask, @NonNull Filter selected) { - if (selected instanceof GtasksFilter - && googleTask.getListId().equals(((GtasksFilter) selected).getRemoteId())) { - return; - } - - long id = googleTask.getTask(); - List children = googleTaskDao.getChildren(id); - List childIds = from(children).transform(GoogleTask::getTask).toList(); - googleTaskDao.markDeleted(id, now()); - - if (selected instanceof GtasksFilter) { - String listId = ((GtasksFilter) selected).getRemoteId(); - googleTaskDao.insertAndShift(new GoogleTask(id, listId), preferences.addTasksToTop()); - if (!children.isEmpty()) { - googleTaskDao.insert( - transform( - children, - child -> { - GoogleTask newChild = new GoogleTask(child.getTask(), listId); - newChild.setOrder(child.getOrder()); - newChild.setParent(id); - return newChild; - })); - } - } else if (selected instanceof CaldavFilter) { - String listId = ((CaldavFilter) selected).getUuid(); - CaldavTask newParent = new CaldavTask(id, listId); - caldavDao.insert(task, newParent, preferences.addTasksToTop()); - caldavDao.insert( - transform( - childIds, - child -> { - CaldavTask newChild = new CaldavTask(child, listId); - newChild.setRemoteParent(newParent.getRemoteId()); - return newChild; - })); - } else if (BuildConfig.DEBUG) { - throw new IllegalArgumentException(); - } - } - - private void moveCaldavTask(Task task, CaldavTask caldavTask, @NonNull Filter selected) { - if (selected instanceof CaldavFilter - && caldavTask.getCalendar().equals(((CaldavFilter) selected).getUuid())) { - return; - } - - long id = task.getId(); - List childIds = taskDao.getChildren(id); - List toDelete = newArrayList(id); - List children = emptyList(); - if (!childIds.isEmpty()) { - children = caldavDao.getTasks(childIds); - toDelete.addAll(childIds); - } - caldavDao.markDeleted(toDelete, now()); - - if (selected instanceof CaldavFilter) { - long id1 = caldavTask.getTask(); - String listId = ((CaldavFilter) selected).getUuid(); - CaldavTask newParent = - new CaldavTask(id1, listId, caldavTask.getRemoteId(), caldavTask.getObject()); - newParent.setVtodo(caldavTask.getVtodo()); - caldavDao.insert(task, newParent, preferences.addTasksToTop()); - caldavDao.insert( - transform( - children, - child -> { - CaldavTask newChild = - new CaldavTask(child.getTask(), listId, child.getRemoteId(), child.getObject()); - newChild.setVtodo(child.getVtodo()); - newChild.setRemoteParent(child.getRemoteParent()); - return newChild; - })); - } else if (selected instanceof GtasksFilter) { - moveToGoogleTasks(id, childIds, (GtasksFilter) selected); - } else if (BuildConfig.DEBUG) { - throw new IllegalArgumentException(); - } - } - - private void moveLocalTask(Task task, @NonNull Filter selected) { - if (selected instanceof GtasksFilter) { - moveToGoogleTasks(task.getId(), taskDao.getChildren(task.getId()), (GtasksFilter) selected); - } else if (selected instanceof CaldavFilter) { - long id = task.getId(); - String listId = ((CaldavFilter) selected).getUuid(); - Map tasks = new HashMap<>(); - CaldavTask root = new CaldavTask(id, listId); - for (Task child : taskDao.fetchChildren(task.getId())) { - CaldavTask newTask = new CaldavTask(child.getId(), listId); - long parent = child.getParent(); - newTask.setRemoteParent((parent == id ? root : tasks.get(parent)).getRemoteId()); - tasks.put(child.getId(), newTask); - } - caldavDao.insert(task, root, preferences.addTasksToTop()); - caldavDao.insert(tasks.values()); - } else if (BuildConfig.DEBUG) { - throw new IllegalArgumentException(); - } - } - - private void moveToGoogleTasks(long id, List children, GtasksFilter filter) { - taskDao.setParent(0, children); - String listId = filter.getRemoteId(); - googleTaskDao.insertAndShift(new GoogleTask(id, listId), preferences.addTasksToTop()); - List newChildren = new ArrayList<>(); - for (int i = 0; i < children.size(); i++) { - GoogleTask newChild = new GoogleTask(children.get(i), listId); - newChild.setOrder(i); - newChild.setParent(id); - newChildren.add(newChild); - } - googleTaskDao.insert(newChildren); - } -} diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskMover.kt b/app/src/main/java/com/todoroo/astrid/service/TaskMover.kt new file mode 100644 index 000000000..f0b060173 --- /dev/null +++ b/app/src/main/java/com/todoroo/astrid/service/TaskMover.kt @@ -0,0 +1,179 @@ +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.dao.TaskDao +import com.todoroo.astrid.data.Task +import org.tasks.BuildConfig +import org.tasks.LocalBroadcastManager +import org.tasks.data.* +import org.tasks.injection.ForApplication +import org.tasks.preferences.Preferences +import java.util.* +import javax.inject.Inject + +class TaskMover @Inject constructor( + @param:ForApplication 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) { + + fun getSingleFilter(tasks: List): 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 + } + + fun move(tasks: List, selectedList: Filter) { + var tasks = tasks + tasks = ArrayList(tasks) + tasks.removeAll(googleTaskDao.findChildrenInList(tasks)) + tasks.removeAll(taskDao.findChildrenInList(tasks)) + taskDao.setParent(0, tasks) + for (task in taskDao.fetch(tasks)) { + performMove(task, selectedList) + } + if (selectedList is CaldavFilter) { + caldavDao.updateParents(selectedList.uuid) + } + taskDao.touch(tasks) + localBroadcastManager.broadcastRefresh() + } + + fun migrateLocalTasks() { + val list = caldavDao.getLocalList(context) + move(taskDao.getLocalTasks(), CaldavFilter(list)) + } + + private 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 fun moveGoogleTask(task: Task, googleTask: GoogleTask, selected: Filter) { + if (selected is GtasksFilter && googleTask.listId == selected.remoteId) { + return + } + val id = googleTask.task + val children = googleTaskDao.getChildren(id) + val childIds = children.map(GoogleTask::task) + googleTaskDao.markDeleted(id, DateUtilities.now()) + when(selected) { + is GtasksFilter -> { + val listId = selected.remoteId + googleTaskDao.insertAndShift(GoogleTask(id, listId), preferences.addTasksToTop()) + children.takeIf { it.isNotEmpty() } + ?.map { + val newChild = GoogleTask(it.task, listId) + newChild.order = it.order + newChild.parent = id + newChild + } + ?.apply(googleTaskDao::insert) + } + is CaldavFilter -> { + val listId = selected.uuid + val newParent = CaldavTask(id, listId) + caldavDao.insert(task, newParent, preferences.addTasksToTop()) + childIds.map { + val newChild = CaldavTask(it, listId) + newChild.remoteParent = newParent.remoteId + newChild + }.apply(caldavDao::insert) + } + else -> require(!BuildConfig.DEBUG) + } + } + + private 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 = emptyList() + if (childIds.isNotEmpty()) { + children = caldavDao.getTasks(childIds) + toDelete.addAll(childIds) + } + caldavDao.markDeleted(toDelete, DateUtilities.now()) + when (selected) { + is CaldavFilter -> { + val id1 = caldavTask.task + val listId = selected.uuid + val newParent = CaldavTask(id1, listId, caldavTask.remoteId, caldavTask.`object`) + newParent.vtodo = caldavTask.vtodo + caldavDao.insert(task, newParent, preferences.addTasksToTop()) + children.takeIf { it.isNotEmpty() } + ?.map { + val newChild = CaldavTask(it.task, listId, it.remoteId, it.`object`) + newChild.vtodo = it.vtodo + newChild.remoteParent = it.remoteParent + newChild + } + ?.apply(caldavDao::insert) + } + is GtasksFilter -> moveToGoogleTasks(id, childIds, selected) + else -> require(!BuildConfig.DEBUG) + } + } + + private 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 = HashMap() + val root = CaldavTask(id, listId) + for (child in taskDao.fetchChildren(task.id)) { + 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 fun moveToGoogleTasks(id: Long, children: List, filter: GtasksFilter) { + taskDao.setParent(0, children) + val listId = filter.remoteId + googleTaskDao.insertAndShift(GoogleTask(id, listId), preferences.addTasksToTop()) + children.takeIf { it.isNotEmpty() } + ?.mapIndexed { index, task -> + val newChild = GoogleTask(task, listId) + newChild.order = index.toLong() + newChild.parent = id + newChild + } + ?.apply(googleTaskDao::insert) + } +} \ No newline at end of file