@@ -351,8 +351,6 @@ class TaskRepository(
351351 pushLocalTasks(
352352 localTaskListId = taskList.id,
353353 remoteTaskListId = remoteTaskListId,
354- localParentTaskId = null ,
355- remoteParentTaskId = null ,
356354 localOnlyTasks,
357355 )
358356 } ? : emptyList()
@@ -407,53 +405,44 @@ class TaskRepository(
407405 private suspend fun pushLocalTasks (
408406 localTaskListId : Long ,
409407 remoteTaskListId : String ,
410- localParentTaskId : Long? ,
411- remoteParentTaskId : String? ,
412408 tasks : List <LocalTask >
413409 ): List <LocalTask > {
414- val tasksToSync = computeTaskPositions(tasks.filter { it.parentTaskLocalId == localParentTaskId })
415- var previousTaskId: String? = null
416- return buildList {
410+ // iterate on tasks grouped by parent, top-level tasks being processed first
411+ val allTasksToSync = tasks.groupBy(LocalTask ::parentTaskLocalId)
412+ .toSortedMap(compareBy<Any ?> { it != null }) // null comes first
413+ .toMutableMap()
414+ val syncedTasks = mutableMapOf<Long , LocalTask >()
415+ val syncFailedTaskIds = mutableListOf<Long >()
416+ allTasksToSync.onEach { (localParentTaskId, tasksToSync) ->
417+ // don't try syncing sub tasks if parent task failed, it would break hierarchy on remote side
418+ if (localParentTaskId in syncFailedTaskIds) return @onEach
419+
420+ var previousTaskId: String? = null
417421 tasksToSync.onEach { localTask ->
418422 val remoteTask = withContext(Dispatchers .IO ) {
419423 try {
420424 tasksApi.insert(
421425 taskListId = remoteTaskListId,
422426 task = localTask.asTask(),
423- parentTaskId = remoteParentTaskId ,
427+ parentTaskId = syncedTasks[localParentTaskId]?.remoteId ,
424428 previousTaskId = previousTaskId,
425429 ).also { remoteTask ->
426- // ensure up to date local parent after sync
427- val localParentTask = remoteTask.parent?.let { taskDao.getByRemoteId(it) }
428- add(
429- remoteTask.asTaskEntity(
430- parentListLocalId = localTaskListId,
431- parentTaskLocalId = localParentTask?.id,
432- taskLocalId = localTask.id,
433- )
430+ syncedTasks[localTask.id] = remoteTask.asTaskEntity(
431+ parentListLocalId = localTaskListId,
432+ parentTaskLocalId = localParentTaskId,
433+ taskLocalId = localTask.id,
434434 )
435435 }
436436 } catch (_: Exception ) {
437+ syncFailedTaskIds + = localTask.id
437438 null
438439 }
439440 }
440441 // FIXME if one of the task sync fails, it breaks sibling order
441442 previousTaskId = remoteTask?.id
442-
443- // don't try syncing sub tasks if parent task failed, it would break hierarchy on remote side
444- if (remoteTask != null ) {
445- addAll(
446- pushLocalTasks(
447- localTaskListId = localTaskListId,
448- remoteTaskListId = remoteTaskListId,
449- localParentTaskId = localTask.id,
450- remoteParentTaskId = remoteTask.id,
451- tasks = tasks,
452- )
453- )
454- }
455443 }
456444 }
445+ return syncedTasks.values.toList()
457446 }
458447
459448 suspend fun createTaskList (title : String ): Long {
0 commit comments