From 1846559fd7dac62f96394adf1e007950ac4c9a2a Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Tue, 30 Jun 2020 11:50:29 -0500 Subject: [PATCH] Use coroutines in task edit fragment --- .../astrid/activity/TaskEditFragment.kt | 92 +++++++++---------- .../org/tasks/ui/TaskEditControlFragment.kt | 10 -- 2 files changed, 43 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.kt b/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.kt index a63964f9a..a437cc39b 100755 --- a/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.kt +++ b/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.kt @@ -21,29 +21,28 @@ import android.view.inputmethod.InputMethodManager import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener -import com.google.common.base.Predicates -import com.google.common.collect.Iterables import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.api.Filter -import com.todoroo.astrid.dao.TaskDaoBlocking +import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.data.Task import com.todoroo.astrid.notes.CommentsController import com.todoroo.astrid.repeats.RepeatControlSet import com.todoroo.astrid.service.TaskDeleter import com.todoroo.astrid.timers.TimerPlugin import dagger.hilt.android.AndroidEntryPoint -import io.reactivex.Completable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.analytics.Firebase import org.tasks.data.UserActivity -import org.tasks.data.UserActivityDaoBlocking +import org.tasks.data.UserActivityDao import org.tasks.databinding.FragmentTaskEditBinding import org.tasks.date.DateTimeUtils.newDateTime import org.tasks.dialogs.DialogBuilder @@ -60,8 +59,8 @@ import kotlin.math.abs @AndroidEntryPoint class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener { - @Inject lateinit var taskDao: TaskDaoBlocking - @Inject lateinit var userActivityDao: UserActivityDaoBlocking + @Inject lateinit var taskDao: TaskDao + @Inject lateinit var userActivityDao: UserActivityDao @Inject lateinit var taskDeleter: TaskDeleter @Inject lateinit var notificationManager: NotificationManager @Inject lateinit var dialogBuilder: DialogBuilder @@ -239,31 +238,27 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener { /** Save task model from values in UI components */ fun save() { val fragments = taskEditControlSetFragmentManager.getFragmentsInPersistOrder(childFragmentManager) - if (hasChanges(fragments)) { - val isNewTask = model.isNew - val taskListFragment = (activity as MainActivity?)!!.taskListFragment - val title = title - model.title = if (isNullOrEmpty(title)) getString(R.string.no_title) else title - if (completed != model.isCompleted) { - model.completionDate = if (completed) DateUtilities.now() else 0 - } - for (fragment in Iterables.filter(fragments, Predicates.not { obj: TaskEditControlFragment? -> obj!!.requiresId() })) { - fragment.applyBlocking(model) - } - Completable.fromAction { - AndroidUtilities.assertNotMainThread() + lifecycleScope.launch(NonCancellable) { + if (hasChanges(fragments)) { + val isNewTask = model.isNew + val taskListFragment = (activity as MainActivity?)!!.taskListFragment + val title = title + model.title = if (isNullOrEmpty(title)) getString(R.string.no_title) else title + if (completed != model.isCompleted) { + model.completionDate = if (completed) DateUtilities.now() else 0 + } + val partition = fragments.partition { it.requiresId() } + partition.second.forEach { it.apply(model) } if (isNewTask) { taskDao.createNew(model) } - for (fragment in Iterables.filter(fragments) { obj: TaskEditControlFragment? -> obj!!.requiresId() }) { - fragment.applyBlocking(model) - } + partition.first.forEach { it.apply(model) } taskDao.save(model, null) if (isNewTask) { taskListFragment!!.onTaskCreated(model.uuid) if (!isNullOrEmpty(model.calendarURI)) { taskListFragment.makeSnackbar(R.string.calendar_event_created, model.title) - .setAction(R.string.action_open) { v: View? -> + .setAction(R.string.action_open) { val uri = model.calendarURI val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uri)) taskListFragment.startActivity(intent) @@ -271,13 +266,10 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener { .show() } } + callback!!.removeTaskEditFragment() + } else { + discard() } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe() - callback!!.removeTaskEditFragment() - } else { - discard() } } @@ -299,7 +291,7 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener { private val title: String get() = binding.title.text.toString().trim { it <= ' ' } - private fun hasChanges(fragments: List): Boolean { + private suspend fun hasChanges(fragments: List): Boolean { val newTitle = title if (newTitle != model.title || !model.isNew && completed != model.isCompleted @@ -307,11 +299,7 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener { return true } try { - for (fragment in fragments) { - if (fragment.hasChangesBlocking(model)) { - return true - } - } + return fragments.any { it.hasChanges(model) } } catch (e: Exception) { firebase.reportException(e) } @@ -324,15 +312,17 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener { * ====================================================================== */ fun discardButtonClick() { - if (hasChanges( - taskEditControlSetFragmentManager.getFragmentsInPersistOrder(childFragmentManager))) { - dialogBuilder - .newDialog(R.string.discard_confirmation) - .setPositiveButton(R.string.keep_editing, null) - .setNegativeButton(R.string.discard) { _, _ -> discard() } - .show() - } else { - discard() + val fragments = taskEditControlSetFragmentManager.getFragmentsInPersistOrder(childFragmentManager) + lifecycleScope.launch { + if (hasChanges(fragments)) { + dialogBuilder + .newDialog(R.string.discard_confirmation) + .setPositiveButton(R.string.keep_editing, null) + .setNegativeButton(R.string.discard) { _, _ -> discard() } + .show() + } else { + discard() + } } } @@ -378,8 +368,12 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener { userActivity.message = message userActivity.targetId = model.uuid userActivity.created = DateUtilities.now() - userActivityDao.createNew(userActivity) - commentsController.reloadView() + lifecycleScope.launch { + withContext(NonCancellable) { + userActivityDao.createNew(userActivity) + } + commentsController.reloadView() + } } interface TaskEditFragmentCallbackHandler { diff --git a/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt b/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt index 62fe64c7f..af1871d6b 100644 --- a/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt +++ b/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt @@ -60,18 +60,8 @@ abstract class TaskEditControlFragment : Fragment() { return false } - @Deprecated("use coroutines") - fun applyBlocking(task: Task) = runBlocking { - apply(task) - } - abstract suspend fun apply(task: Task) - @Deprecated("use coroutines") - fun hasChangesBlocking(original: Task) = runBlocking { - hasChanges(original) - } - open suspend fun hasChanges(original: Task): Boolean { return false }