diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt b/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt index 65fd3c485..baed1cf75 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt +++ b/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt @@ -61,19 +61,19 @@ class TaskDeleter @Inject constructor( localBroadcastManager.broadcastRefreshList() } - fun delete(list: GoogleTaskAccount) = runBlocking { + suspend fun delete(list: GoogleTaskAccount) { val tasks = deletionDao.delete(list) delete(tasks) localBroadcastManager.broadcastRefreshList() } - fun delete(list: CaldavCalendar) = runBlocking { + suspend fun delete(list: CaldavCalendar) { val tasks = deletionDao.delete(list) delete(tasks) localBroadcastManager.broadcastRefreshList() } - fun delete(list: CaldavAccount) = runBlocking { + suspend fun delete(list: CaldavAccount) { val tasks = deletionDao.delete(list) delete(tasks) localBroadcastManager.broadcastRefreshList() diff --git a/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt b/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt index 861608fb7..07ed5442d 100644 --- a/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt @@ -7,9 +7,11 @@ import android.view.MenuItem import android.view.View import android.widget.TextView import androidx.appcompat.widget.Toolbar +import androidx.lifecycle.lifecycleScope import butterknife.BindView import butterknife.ButterKnife import butterknife.OnClick +import kotlinx.coroutines.launch import org.tasks.R import org.tasks.dialogs.ColorPalettePicker import org.tasks.dialogs.ColorPalettePicker.Companion.newColorPalette @@ -54,7 +56,7 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic } toolbar.title = toolbarTitle toolbar.navigationIcon = getDrawable(R.drawable.ic_outline_save_24px) - toolbar.setNavigationOnClickListener { save() } + toolbar.setNavigationOnClickListener { lifecycleScope.launch { save() } } if (!isNew) { toolbar.inflateMenu(R.menu.menu_tag_settings) } @@ -73,10 +75,10 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic protected abstract val layout: Int protected abstract fun hasChanges(): Boolean - protected abstract fun save() + protected abstract suspend fun save() protected abstract val isNew: Boolean protected abstract val toolbarTitle: String? - protected abstract fun delete() + protected abstract suspend fun delete() protected open fun discard() { if (!hasChanges()) { finish() @@ -127,7 +129,7 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic protected open fun promptDelete() { dialogBuilder .newDialog(R.string.delete_tag_confirmation, toolbarTitle) - .setPositiveButton(R.string.delete) { _, _ -> delete() } + .setPositiveButton(R.string.delete) { _, _ -> lifecycleScope.launch { delete() } } .setNegativeButton(android.R.string.cancel, null) .show() } diff --git a/app/src/main/java/org/tasks/activities/CreateListViewModel.kt b/app/src/main/java/org/tasks/activities/CreateListViewModel.kt index ced9d0769..cd3169439 100644 --- a/app/src/main/java/org/tasks/activities/CreateListViewModel.kt +++ b/app/src/main/java/org/tasks/activities/CreateListViewModel.kt @@ -7,7 +7,7 @@ import org.tasks.ui.CompletableViewModel class CreateListViewModel @ViewModelInject constructor( private val invoker: GtasksInvoker) : CompletableViewModel() { - fun createList(account: String, name: String) { + suspend fun createList(account: String, name: String) { run { invoker.forAccount(account).createGtaskList(name)!! } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/activities/DeleteListViewModel.kt b/app/src/main/java/org/tasks/activities/DeleteListViewModel.kt index dbade9183..224e01e1f 100644 --- a/app/src/main/java/org/tasks/activities/DeleteListViewModel.kt +++ b/app/src/main/java/org/tasks/activities/DeleteListViewModel.kt @@ -7,7 +7,7 @@ import org.tasks.ui.ActionViewModel class DeleteListViewModel @ViewModelInject constructor( private val invoker: GtasksInvoker) : ActionViewModel() { - fun deleteList(list: GoogleTaskList) { + suspend fun deleteList(list: GoogleTaskList) { run { invoker.forAccount(list.account!!).deleteGtaskList(list.remoteId) } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt b/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt index e9543f498..11d9c1c85 100644 --- a/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt @@ -37,6 +37,7 @@ import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.Strings import org.tasks.data.Filter +import org.tasks.data.FilterDao import org.tasks.data.FilterDaoBlocking import org.tasks.filters.FilterCriteriaProvider import org.tasks.locale.Locale @@ -46,7 +47,7 @@ import kotlin.math.max @AndroidEntryPoint class FilterSettingsActivity : BaseListSettingsActivity() { - @Inject lateinit var filterDao: FilterDaoBlocking + @Inject lateinit var filterDao: FilterDao @Inject lateinit var locale: Locale @Inject lateinit var database: Database @Inject lateinit var filterCriteriaProvider: FilterCriteriaProvider @@ -224,7 +225,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() { nameLayout.error = null } - override fun save() { + override suspend fun save() { val newName = newName if (Strings.isNullOrEmpty(newName)) { nameLayout.error = getString(R.string.name_cannot_be_empty) @@ -277,7 +278,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() { override val layout: Int get() = R.layout.filter_settings_activity - override fun delete() { + override suspend fun delete() { filterDao.delete(filter!!.id) setResult( Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED).putExtra(TOKEN_FILTER, filter)) diff --git a/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt b/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt index 2b665bca2..548109d5e 100644 --- a/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt @@ -15,7 +15,6 @@ import com.google.api.services.tasks.model.TaskList import com.todoroo.astrid.activity.MainActivity import com.todoroo.astrid.activity.TaskListFragment import com.todoroo.astrid.api.GtasksFilter -import com.todoroo.astrid.gtasks.GtasksListService import com.todoroo.astrid.gtasks.api.GtasksInvoker import com.todoroo.astrid.service.TaskDeleter import dagger.hilt.android.AndroidEntryPoint @@ -24,15 +23,14 @@ import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.data.GoogleTaskAccount import org.tasks.data.GoogleTaskList -import org.tasks.data.GoogleTaskListDaoBlocking +import org.tasks.data.GoogleTaskListDao import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { @Inject @ApplicationContext lateinit var context: Context - @Inject lateinit var googleTaskListDao: GoogleTaskListDaoBlocking - @Inject lateinit var gtasksListService: GtasksListService + @Inject lateinit var googleTaskListDao: GoogleTaskListDao @Inject lateinit var taskDeleter: TaskDeleter @Inject lateinit var gtasksInvoker: GtasksInvoker @@ -93,7 +91,7 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { private fun requestInProgress() = progressView.visibility == View.VISIBLE - override fun save() { + override suspend fun save() { if (requestInProgress()) { return } @@ -141,7 +139,7 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { } } - override fun delete() { + override suspend fun delete() { showProgressIndicator() deleteListViewModel.deleteList(gtasksList) } @@ -167,7 +165,7 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { private fun nameChanged() = newName != gtasksList.title - private fun onListCreated(taskList: TaskList) { + private suspend fun onListCreated(taskList: TaskList) { gtasksList.remoteId = taskList.id gtasksList.title = taskList.title gtasksList.setColor(selectedColor) @@ -176,10 +174,9 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { setResult( Activity.RESULT_OK, Intent().putExtra(MainActivity.OPEN_FILTER, GtasksFilter(gtasksList))) finish() - return } - private fun onListDeleted(deleted: Boolean) { + private suspend fun onListDeleted(deleted: Boolean) { if (deleted) { taskDeleter.delete(gtasksList) setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED)) @@ -187,7 +184,7 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { } } - private fun onListRenamed(taskList: TaskList) { + private suspend fun onListRenamed(taskList: TaskList) { gtasksList.title = taskList.title gtasksList.setColor(selectedColor) gtasksList.setIcon(selectedIcon) @@ -197,7 +194,6 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { Intent(TaskListFragment.ACTION_RELOAD) .putExtra(MainActivity.OPEN_FILTER, GtasksFilter(gtasksList))) finish() - return } private fun requestFailed(error: Throwable) { diff --git a/app/src/main/java/org/tasks/activities/PlaceSettingsActivity.kt b/app/src/main/java/org/tasks/activities/PlaceSettingsActivity.kt index bb2fdde14..f7e70d1f1 100644 --- a/app/src/main/java/org/tasks/activities/PlaceSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/PlaceSettingsActivity.kt @@ -12,7 +12,7 @@ import com.todoroo.astrid.activity.TaskListFragment import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.Strings.isNullOrEmpty -import org.tasks.data.LocationDaoBlocking +import org.tasks.data.LocationDao import org.tasks.data.Place import org.tasks.filters.PlaceFilter import org.tasks.location.MapFragment @@ -28,7 +28,7 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen @BindView(R.id.name) lateinit var name: TextInputEditText @BindView(R.id.name_layout) lateinit var nameLayout: TextInputLayout - @Inject lateinit var locationDao: LocationDaoBlocking + @Inject lateinit var locationDao: LocationDao @Inject lateinit var map: MapFragment private lateinit var place: Place @@ -71,7 +71,7 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen nameLayout.error = null } - override fun save() { + override suspend fun save() { val newName: String = name.text.toString() if (isNullOrEmpty(newName)) { @@ -96,7 +96,7 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen override val toolbarTitle: String? get() = place.address ?: place.displayName - override fun delete() { + override suspend fun delete() { locationDao.deleteGeofencesByPlace(place.uid!!) locationDao.delete(place) setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED)) diff --git a/app/src/main/java/org/tasks/activities/RenameListViewModel.kt b/app/src/main/java/org/tasks/activities/RenameListViewModel.kt index 6e09b81ab..905fd9a10 100644 --- a/app/src/main/java/org/tasks/activities/RenameListViewModel.kt +++ b/app/src/main/java/org/tasks/activities/RenameListViewModel.kt @@ -8,7 +8,7 @@ import org.tasks.ui.CompletableViewModel class RenameListViewModel @ViewModelInject constructor( private val invoker: GtasksInvoker) : CompletableViewModel() { - fun renameList(list: GoogleTaskList, name: String) { + suspend fun renameList(list: GoogleTaskList, name: String) { run { invoker.forAccount(list.account!!).renameGtaskList(list.remoteId, name)!! } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/activities/TagSettingsActivity.kt b/app/src/main/java/org/tasks/activities/TagSettingsActivity.kt index 9d9feec57..9021043b1 100644 --- a/app/src/main/java/org/tasks/activities/TagSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/TagSettingsActivity.kt @@ -21,15 +21,15 @@ import com.todoroo.astrid.helper.UUIDHelper import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.Strings.isNullOrEmpty -import org.tasks.data.TagDaoBlocking +import org.tasks.data.TagDao import org.tasks.data.TagData -import org.tasks.data.TagDataDaoBlocking +import org.tasks.data.TagDataDao import javax.inject.Inject @AndroidEntryPoint class TagSettingsActivity : BaseListSettingsActivity() { - @Inject lateinit var tagDataDao: TagDataDaoBlocking - @Inject lateinit var tagDao: TagDaoBlocking + @Inject lateinit var tagDataDao: TagDataDao + @Inject lateinit var tagDao: TagDao @BindView(R.id.name) lateinit var name: TextInputEditText @@ -78,12 +78,12 @@ class TagSettingsActivity : BaseListSettingsActivity() { private val newName: String get() = name.text.toString().trim { it <= ' ' } - private fun clashes(newName: String): Boolean { + private suspend fun clashes(newName: String): Boolean { return ((isNewTag || !newName.equals(tagData.name, ignoreCase = true)) && tagDataDao.getTagByName(newName) != null) } - override fun save() { + override suspend fun save() { val newName = newName if (isNullOrEmpty(newName)) { nameLayout.error = getString(R.string.name_cannot_be_empty) @@ -132,7 +132,7 @@ class TagSettingsActivity : BaseListSettingsActivity() { override val layout: Int get() = R.layout.activity_tag_settings - override fun delete() { + override suspend fun delete() { val uuid = tagData.remoteId tagDataDao.delete(tagData) setResult( diff --git a/app/src/main/java/org/tasks/caldav/AddCaldavAccountViewModel.kt b/app/src/main/java/org/tasks/caldav/AddCaldavAccountViewModel.kt index 71fd8736d..8bb780ac6 100644 --- a/app/src/main/java/org/tasks/caldav/AddCaldavAccountViewModel.kt +++ b/app/src/main/java/org/tasks/caldav/AddCaldavAccountViewModel.kt @@ -5,7 +5,7 @@ import org.tasks.ui.CompletableViewModel class AddCaldavAccountViewModel @ViewModelInject constructor( private val client: CaldavClient) : CompletableViewModel() { - fun addAccount(url: String, username: String, password: String) { + suspend fun addAccount(url: String, username: String, password: String) { run { client.setForeground().forUrl(url, username, password).homeSet } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/caldav/BaseCaldavAccountSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/BaseCaldavAccountSettingsActivity.kt index f771341f9..e68d50370 100644 --- a/app/src/main/java/org/tasks/caldav/BaseCaldavAccountSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/BaseCaldavAccountSettingsActivity.kt @@ -12,6 +12,7 @@ import android.view.View import android.view.inputmethod.InputMethodManager import androidx.annotation.StringRes import androidx.appcompat.widget.Toolbar +import androidx.lifecycle.lifecycleScope import at.bitfire.dav4jvm.exception.HttpException import butterknife.ButterKnife import butterknife.OnFocusChange @@ -20,12 +21,13 @@ import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.Snackbar import com.todoroo.astrid.data.Task import com.todoroo.astrid.service.TaskDeleter +import kotlinx.coroutines.launch import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.billing.Inventory import org.tasks.billing.PurchaseActivity import org.tasks.data.CaldavAccount -import org.tasks.data.CaldavDaoBlocking +import org.tasks.data.CaldavDao import org.tasks.databinding.ActivityCaldavAccountSettingsBinding import org.tasks.dialogs.DialogBuilder import org.tasks.injection.ThemedInjectingAppCompatActivity @@ -39,7 +41,7 @@ import java.net.URISyntaxException import javax.inject.Inject abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.OnMenuItemClickListener { - @Inject lateinit var caldavDao: CaldavDaoBlocking + @Inject lateinit var caldavDao: CaldavDao @Inject lateinit var encryption: KeyStoreEncryption @Inject lateinit var dialogBuilder: DialogBuilder @Inject lateinit var taskDeleter: TaskDeleter @@ -169,9 +171,9 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv protected abstract val newPassword: String? - private fun save() { + private fun save() = lifecycleScope.launch { if (requestInProgress()) { - return + return@launch } val username = newUsername val url = newURL @@ -217,7 +219,7 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv failed = true } when { - failed -> return + failed -> return@launch caldavAccount == null -> { showProgressIndicator() addAccount(url, username, password!!) @@ -235,9 +237,9 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv } } - protected abstract fun addAccount(url: String, username: String, password: String) - protected abstract fun updateAccount(url: String, username: String, password: String?) - protected abstract fun updateAccount() + protected abstract suspend fun addAccount(url: String, username: String, password: String) + protected abstract suspend fun updateAccount(url: String, username: String, password: String?) + protected abstract suspend fun updateAccount() protected abstract val helpUrl: String? protected fun requestFailed(t: Throwable) { @@ -313,12 +315,12 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv dialogBuilder .newDialog() .setMessage(R.string.logout_warning, caldavAccount!!.name) - .setPositiveButton(R.string.remove) { _, _ -> removeAccount() } + .setPositiveButton(R.string.remove) { _, _ -> lifecycleScope.launch { removeAccount() } } .setNegativeButton(android.R.string.cancel, null) .show() } - protected open fun removeAccount() { + protected open suspend fun removeAccount() { taskDeleter.delete(caldavAccount!!) setResult(Activity.RESULT_OK) finish() diff --git a/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt index bba813695..11c4e6803 100644 --- a/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt @@ -24,13 +24,14 @@ import org.tasks.Strings.isNullOrEmpty import org.tasks.activities.BaseListSettingsActivity import org.tasks.data.CaldavAccount import org.tasks.data.CaldavCalendar -import org.tasks.data.CaldavDaoBlocking +import org.tasks.data.CaldavDao +import org.tasks.data.runBlocking import org.tasks.ui.DisplayableException import java.net.ConnectException import javax.inject.Inject abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { - @Inject lateinit var caldavDao: CaldavDaoBlocking + @Inject lateinit var caldavDao: CaldavDao @Inject lateinit var taskDeleter: TaskDeleter @BindView(R.id.root_layout) @@ -58,7 +59,7 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { caldavAccount = if (caldavCalendar == null) { intent.getParcelableExtra(EXTRA_CALDAV_ACCOUNT)!! } else { - caldavDao.getAccountByUuid(caldavCalendar!!.account!!)!! + runBlocking { caldavDao.getAccountByUuid(caldavCalendar!!.account!!)!! } } if (savedInstanceState == null) { if (caldavCalendar != null) { @@ -86,7 +87,7 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { nameLayout.error = null } - override fun save() { + override suspend fun save() { if (requestInProgress()) { return } @@ -108,12 +109,12 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { } } - protected abstract fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) + protected abstract suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) - protected abstract fun updateNameAndColor( + protected abstract suspend fun updateNameAndColor( account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) - protected abstract fun deleteCalendar( + protected abstract suspend fun deleteCalendar( caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) private fun showProgressIndicator() { @@ -153,7 +154,7 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { snackbar.show() } - protected fun createSuccessful(url: String?) { + protected suspend fun createSuccessful(url: String?) { val caldavCalendar = CaldavCalendar() caldavCalendar.uuid = UUIDHelper.newUUID() caldavCalendar.account = caldavAccount.uuid @@ -166,10 +167,9 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { Activity.RESULT_OK, Intent().putExtra(MainActivity.OPEN_FILTER, CaldavFilter(caldavCalendar))) finish() - return } - protected fun updateCalendar() { + protected suspend fun updateCalendar() { caldavCalendar!!.name = newName caldavCalendar!!.color = selectedColor caldavCalendar!!.setIcon(selectedIcon) @@ -179,7 +179,6 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { Intent(TaskListFragment.ACTION_RELOAD) .putExtra(MainActivity.OPEN_FILTER, CaldavFilter(caldavCalendar))) finish() - return } override fun hasChanges(): Boolean { @@ -219,12 +218,12 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { } } - override fun delete() { + override suspend fun delete() { showProgressIndicator() deleteCalendar(caldavAccount, caldavCalendar!!) } - protected fun onDeleted(deleted: Boolean) { + protected suspend fun onDeleted(deleted: Boolean) { if (deleted) { taskDeleter.delete(caldavCalendar!!) setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED)) diff --git a/app/src/main/java/org/tasks/caldav/CaldavAccountSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/CaldavAccountSettingsActivity.kt index 4ee3fd244..321f81896 100644 --- a/app/src/main/java/org/tasks/caldav/CaldavAccountSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/CaldavAccountSettingsActivity.kt @@ -24,7 +24,7 @@ class CaldavAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Toolb override val description: Int get() = R.string.caldav_account_description - private fun addAccount(principal: String) { + private suspend fun addAccount(principal: String) { hideProgressIndicator() Timber.d("Found principal: %s", principal) val newAccount = CaldavAccount() @@ -38,7 +38,7 @@ class CaldavAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Toolb finish() } - private fun updateAccount(principal: String?) { + private suspend fun updateAccount(principal: String?) { hideProgressIndicator() caldavAccount!!.name = newName caldavAccount!!.url = principal @@ -53,17 +53,14 @@ class CaldavAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Toolb finish() } - override fun addAccount(url: String, username: String, password: String) { - addCaldavAccountViewModel.addAccount(url, username, password) - } + override suspend fun addAccount(url: String, username: String, password: String) = + addCaldavAccountViewModel.addAccount(url, username, password) - override fun updateAccount(url: String, username: String, password: String?) { - updateCaldavAccountViewModel.updateCaldavAccount(url, username, password) - } + override suspend fun updateAccount(url: String, username: String, password: String?) = + updateCaldavAccountViewModel.updateCaldavAccount(url, username, password) - override fun updateAccount() { - updateAccount(caldavAccount!!.url) - } + override suspend fun updateAccount() = + updateAccount(caldavAccount!!.url) override val newPassword: String? get() { diff --git a/app/src/main/java/org/tasks/caldav/CaldavCalendarSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/CaldavCalendarSettingsActivity.kt index 75229efc0..e0e413ed0 100644 --- a/app/src/main/java/org/tasks/caldav/CaldavCalendarSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/CaldavCalendarSettingsActivity.kt @@ -2,7 +2,9 @@ package org.tasks.caldav import android.os.Bundle import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch import org.tasks.R import org.tasks.data.CaldavAccount import org.tasks.data.CaldavCalendar @@ -18,18 +20,22 @@ class CaldavCalendarSettingsActivity : BaseCaldavCalendarSettingsActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + createCalendarViewModel.observe(this, this::createSuccessful, this::requestFailed) deleteCalendarViewModel.observe(this, this::onDeleted, this::requestFailed) - updateCalendarViewModel.observe(this, { updateCalendar() }, this::requestFailed) + updateCalendarViewModel.observe( + this, + { updateCalendar() }, + this::requestFailed) } - override fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) = + override suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) = createCalendarViewModel.createCalendar(caldavAccount, name, color) - override fun updateNameAndColor( + override suspend fun updateNameAndColor( account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) = updateCalendarViewModel.updateCalendar(account, calendar, name, color) - override fun deleteCalendar(caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) = + override suspend fun deleteCalendar(caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) = deleteCalendarViewModel.deleteCalendar(caldavAccount, caldavCalendar) } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/caldav/CreateCalendarViewModel.kt b/app/src/main/java/org/tasks/caldav/CreateCalendarViewModel.kt index 778b83a29..54c519c53 100644 --- a/app/src/main/java/org/tasks/caldav/CreateCalendarViewModel.kt +++ b/app/src/main/java/org/tasks/caldav/CreateCalendarViewModel.kt @@ -6,7 +6,7 @@ import org.tasks.ui.CompletableViewModel class CreateCalendarViewModel @ViewModelInject constructor( private val client: CaldavClient): CompletableViewModel() { - fun createCalendar(account: CaldavAccount, name: String, color: Int) { + suspend fun createCalendar(account: CaldavAccount, name: String, color: Int) { run { client.forAccount(account).makeCollection(name, color) } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/caldav/DeleteCalendarViewModel.kt b/app/src/main/java/org/tasks/caldav/DeleteCalendarViewModel.kt index f7de26816..c6703273b 100644 --- a/app/src/main/java/org/tasks/caldav/DeleteCalendarViewModel.kt +++ b/app/src/main/java/org/tasks/caldav/DeleteCalendarViewModel.kt @@ -7,7 +7,7 @@ import org.tasks.ui.ActionViewModel class DeleteCalendarViewModel @ViewModelInject constructor( private val client: CaldavClient) : ActionViewModel() { - fun deleteCalendar(account: CaldavAccount, calendar: CaldavCalendar) { + suspend fun deleteCalendar(account: CaldavAccount, calendar: CaldavCalendar) { run { client.forCalendar(account, calendar).deleteCollection() } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt index 03ed4dfb0..1d398ef56 100644 --- a/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt @@ -6,6 +6,7 @@ import org.tasks.R import org.tasks.data.CaldavAccount import org.tasks.data.CaldavCalendar import org.tasks.data.CaldavDao +import org.tasks.data.runBlocking @AndroidEntryPoint class LocalListSettingsActivity : BaseCaldavCalendarSettingsActivity() { @@ -17,16 +18,16 @@ class LocalListSettingsActivity : BaseCaldavCalendarSettingsActivity() { super.onCreate(savedInstanceState) toolbar.menu.findItem(R.id.delete)?.isVisible = - caldavDao.getCalendarsByAccount(CaldavDao.LOCAL).size > 1 + runBlocking { caldavDao.getCalendarsByAccount(CaldavDao.LOCAL).size > 1 } } - override fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) = + override suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) = createSuccessful(null) - override fun updateNameAndColor( + override suspend fun updateNameAndColor( account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) = updateCalendar() - override fun deleteCalendar(caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) = + override suspend fun deleteCalendar(caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) = onDeleted(true) } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/caldav/UpdateCaldavAccountViewModel.kt b/app/src/main/java/org/tasks/caldav/UpdateCaldavAccountViewModel.kt index 5358243ab..3a7b0957c 100644 --- a/app/src/main/java/org/tasks/caldav/UpdateCaldavAccountViewModel.kt +++ b/app/src/main/java/org/tasks/caldav/UpdateCaldavAccountViewModel.kt @@ -5,7 +5,7 @@ import org.tasks.ui.CompletableViewModel class UpdateCaldavAccountViewModel @ViewModelInject constructor( private val client: CaldavClient) : CompletableViewModel() { - fun updateCaldavAccount(url: String, username: String, password: String?) { + suspend fun updateCaldavAccount(url: String, username: String, password: String?) { run { client.forUrl(url, username, password).homeSet } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/caldav/UpdateCalendarViewModel.kt b/app/src/main/java/org/tasks/caldav/UpdateCalendarViewModel.kt index 6e6563de5..996272f1b 100644 --- a/app/src/main/java/org/tasks/caldav/UpdateCalendarViewModel.kt +++ b/app/src/main/java/org/tasks/caldav/UpdateCalendarViewModel.kt @@ -7,7 +7,7 @@ import org.tasks.ui.CompletableViewModel class UpdateCalendarViewModel @ViewModelInject constructor( private val client: CaldavClient) : CompletableViewModel() { - fun updateCalendar(account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) { + suspend fun updateCalendar(account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) { run { client.forCalendar(account, calendar).updateCollection(name, color) } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.kt b/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.kt index e5155bae4..532db4009 100644 --- a/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.kt +++ b/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.kt @@ -2,13 +2,12 @@ package org.tasks.etesync import androidx.core.util.Pair import androidx.hilt.lifecycle.ViewModelInject -import com.etesync.journalmanager.UserInfoManager import com.etesync.journalmanager.UserInfoManager.UserInfo import org.tasks.ui.CompletableViewModel class AddEteSyncAccountViewModel @ViewModelInject constructor( private val client: EteSyncClient): CompletableViewModel>() { - fun addAccount(url: String, username: String, password: String) { + suspend fun addAccount(url: String, username: String, password: String) { run { client.setForeground() val token = client.forUrl(url, username, null, null).getToken(password) diff --git a/app/src/main/java/org/tasks/etesync/CreateCalendarViewModel.kt b/app/src/main/java/org/tasks/etesync/CreateCalendarViewModel.kt index 4ee2ef8e5..cc13de013 100644 --- a/app/src/main/java/org/tasks/etesync/CreateCalendarViewModel.kt +++ b/app/src/main/java/org/tasks/etesync/CreateCalendarViewModel.kt @@ -6,7 +6,7 @@ import org.tasks.ui.CompletableViewModel class CreateCalendarViewModel @ViewModelInject constructor( private val client: EteSyncClient) : CompletableViewModel() { - fun createCalendar(account: CaldavAccount, name: String, color: Int) { + suspend fun createCalendar(account: CaldavAccount, name: String, color: Int) { run { client.forAccount(account).makeCollection(name, color) } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/CreateUserInfoViewModel.kt b/app/src/main/java/org/tasks/etesync/CreateUserInfoViewModel.kt index 549448c3a..12e7ac367 100644 --- a/app/src/main/java/org/tasks/etesync/CreateUserInfoViewModel.kt +++ b/app/src/main/java/org/tasks/etesync/CreateUserInfoViewModel.kt @@ -6,7 +6,7 @@ import org.tasks.ui.CompletableViewModel class CreateUserInfoViewModel @ViewModelInject constructor( private val client: EteSyncClient): CompletableViewModel() { - fun createUserInfo(caldavAccount: CaldavAccount, derivedKey: String) { + suspend fun createUserInfo(caldavAccount: CaldavAccount, derivedKey: String) { run { client.forAccount(caldavAccount).createUserInfo(derivedKey) derivedKey diff --git a/app/src/main/java/org/tasks/etesync/DeleteCalendarViewModel.kt b/app/src/main/java/org/tasks/etesync/DeleteCalendarViewModel.kt index 61a9d7e4f..fcb497352 100644 --- a/app/src/main/java/org/tasks/etesync/DeleteCalendarViewModel.kt +++ b/app/src/main/java/org/tasks/etesync/DeleteCalendarViewModel.kt @@ -7,7 +7,7 @@ import org.tasks.ui.ActionViewModel class DeleteCalendarViewModel @ViewModelInject constructor( private val client: EteSyncClient) : ActionViewModel() { - fun deleteCalendar(account: CaldavAccount, calendar: CaldavCalendar) { + suspend fun deleteCalendar(account: CaldavAccount, calendar: CaldavCalendar) { run { client.forAccount(account).deleteCollection(calendar) } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt b/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt index b43a520ee..911da597a 100644 --- a/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt +++ b/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt @@ -8,6 +8,7 @@ import android.view.MenuItem import android.view.View import androidx.activity.viewModels import androidx.appcompat.widget.Toolbar +import androidx.lifecycle.lifecycleScope import at.bitfire.dav4jvm.exception.HttpException import butterknife.ButterKnife import butterknife.OnTextChanged @@ -19,6 +20,7 @@ import com.etesync.journalmanager.Exceptions.VersionTooNewException import com.etesync.journalmanager.UserInfoManager import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.data.CaldavAccount @@ -57,7 +59,7 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O toolbar.inflateMenu(R.menu.menu_help) toolbar.setOnMenuItemClickListener(this) themeColor.apply(toolbar) - createUserInfoViewModel.observe(this, this::returnDerivedKey, this::requestFailed) + createUserInfoViewModel.observe(this, { returnDerivedKey(it) }, this::requestFailed) if (createUserInfoViewModel.inProgress) { showProgressIndicator() } @@ -82,21 +84,21 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O return } - private fun save() { + private fun save() = lifecycleScope.launch { if (requestInProgress()) { - return + return@launch } val encryptionPassword = newEncryptionPassword val derivedKey = caldavAccount!!.getEncryptionPassword(encryption) if (isNullOrEmpty(encryptionPassword) && isNullOrEmpty(derivedKey)) { binding.encryptionPasswordLayout.error = getString(R.string.encryption_password_required) - return + return@launch } if (userInfo == null) { val repeatEncryptionPassword = binding.repeatEncryptionPassword.text.toString().trim { it <= ' ' } if (encryptionPassword != repeatEncryptionPassword) { binding.repeatEncryptionPasswordLayout.error = getString(R.string.passwords_do_not_match) - return + return@launch } } val key = if (isNullOrEmpty(encryptionPassword)) derivedKey else deriveKey(caldavAccount!!.username!!, encryptionPassword) @@ -106,10 +108,10 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O CryptoManager(version, key, "userInfo") } catch (e: VersionTooNewException) { requestFailed(e) - return + return@launch } catch (e: IntegrityException) { requestFailed(e) - return + return@launch } if (userInfo == null) { showProgressIndicator() diff --git a/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt b/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt index 6c71ed502..57713db40 100644 --- a/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt +++ b/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt @@ -7,6 +7,7 @@ import android.view.View import androidx.activity.viewModels import androidx.appcompat.widget.Toolbar import androidx.core.util.Pair +import androidx.lifecycle.lifecycleScope import butterknife.OnCheckedChanged import com.etesync.journalmanager.Crypto.CryptoManager import com.etesync.journalmanager.Exceptions.IntegrityException @@ -17,6 +18,7 @@ import com.todoroo.astrid.helper.UUIDHelper import dagger.hilt.android.AndroidEntryPoint import io.reactivex.Completable import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.launch import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.caldav.BaseCaldavAccountSettingsActivity @@ -55,19 +57,19 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool override val description: Int get() = R.string.etesync_account_description - private fun addAccount(userInfoAndToken: Pair) { + private suspend fun addAccount(userInfoAndToken: Pair) { caldavAccount = CaldavAccount() caldavAccount!!.accountType = CaldavAccount.TYPE_ETESYNC caldavAccount!!.uuid = UUIDHelper.newUUID() applyTo(caldavAccount!!, userInfoAndToken) } - private fun updateAccount(userInfoAndToken: Pair) { + private suspend fun updateAccount(userInfoAndToken: Pair) { caldavAccount!!.error = "" applyTo(caldavAccount!!, userInfoAndToken) } - private fun applyTo(account: CaldavAccount, userInfoAndToken: Pair) { + private suspend fun applyTo(account: CaldavAccount, userInfoAndToken: Pair) { hideProgressIndicator() account.name = newName account.url = newURL @@ -116,19 +118,17 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool return super.needsValidation() || isNullOrEmpty(caldavAccount!!.encryptionKey) } - override fun addAccount(url: String, username: String, password: String) { + override suspend fun addAccount(url: String, username: String, password: String) = addAccountViewModel.addAccount(url, username, password) - } - override fun updateAccount(url: String, username: String, password: String?) { + override suspend fun updateAccount(url: String, username: String, password: String?) = updateAccountViewModel.updateAccount( url, username, if (PASSWORD_MASK == password) null else password, caldavAccount!!.getPassword(encryption)) - } - override fun updateAccount() { + override suspend fun updateAccount() { caldavAccount!!.name = newName saveAccountAndFinish() } @@ -148,16 +148,18 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if (requestCode == REQUEST_ENCRYPTION_PASSWORD) { if (resultCode == Activity.RESULT_OK) { - val key = data!!.getStringExtra(EncryptionSettingsActivity.EXTRA_DERIVED_KEY)!! - caldavAccount!!.encryptionKey = encryption.encrypt(key) - saveAccountAndFinish() + lifecycleScope.launch { + val key = data!!.getStringExtra(EncryptionSettingsActivity.EXTRA_DERIVED_KEY)!! + caldavAccount!!.encryptionKey = encryption.encrypt(key) + saveAccountAndFinish() + } } } else { super.onActivityResult(requestCode, resultCode, data) } } - private fun saveAccountAndFinish() { + private suspend fun saveAccountAndFinish() { if (caldavAccount!!.id == Task.NO_ID) { caldavDao.insert(caldavAccount!!) } else { @@ -167,7 +169,7 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool finish() } - override fun removeAccount() { + override suspend fun removeAccount() { if (caldavAccount != null) { Completable.fromAction { eteSyncClient.forAccount(caldavAccount!!).invalidateToken() } .subscribeOn(Schedulers.io()) diff --git a/app/src/main/java/org/tasks/etesync/EteSyncCalendarSettingsActivity.kt b/app/src/main/java/org/tasks/etesync/EteSyncCalendarSettingsActivity.kt index 7c89d6c88..175e7037a 100644 --- a/app/src/main/java/org/tasks/etesync/EteSyncCalendarSettingsActivity.kt +++ b/app/src/main/java/org/tasks/etesync/EteSyncCalendarSettingsActivity.kt @@ -21,13 +21,13 @@ class EteSyncCalendarSettingsActivity : BaseCaldavCalendarSettingsActivity() { updateCalendarViewModel.observe(this, { updateCalendar() }, this::requestFailed) } - override fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) = + override suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) = createCalendarViewModel.createCalendar(caldavAccount, name, color) - override fun updateNameAndColor( + override suspend fun updateNameAndColor( account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) = updateCalendarViewModel.updateCalendar(account, calendar, name, color) - override fun deleteCalendar(caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) = + override suspend fun deleteCalendar(caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) = deleteCalendarViewModel.deleteCalendar(caldavAccount, caldavCalendar) } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/UpdateCalendarViewModel.kt b/app/src/main/java/org/tasks/etesync/UpdateCalendarViewModel.kt index 27d9f7374..2d9eb8b6d 100644 --- a/app/src/main/java/org/tasks/etesync/UpdateCalendarViewModel.kt +++ b/app/src/main/java/org/tasks/etesync/UpdateCalendarViewModel.kt @@ -7,7 +7,7 @@ import org.tasks.ui.CompletableViewModel class UpdateCalendarViewModel @ViewModelInject constructor( private val client: EteSyncClient): CompletableViewModel() { - fun updateCalendar(account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) { + suspend fun updateCalendar(account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int) { run { client.forAccount(account).updateCollection(calendar, name, color) } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.kt b/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.kt index b0867c156..e67a06639 100644 --- a/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.kt +++ b/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.kt @@ -8,7 +8,7 @@ import org.tasks.ui.CompletableViewModel class UpdateEteSyncAccountViewModel @ViewModelInject constructor( private val client: EteSyncClient) : CompletableViewModel>() { - fun updateAccount(url: String, user: String, pass: String?, token: String) { + suspend fun updateAccount(url: String, user: String, pass: String?, token: String) { run { client.setForeground() if (isNullOrEmpty(pass)) { diff --git a/app/src/main/java/org/tasks/ui/ActionViewModel.kt b/app/src/main/java/org/tasks/ui/ActionViewModel.kt index c286ee1e6..907d1b0c0 100644 --- a/app/src/main/java/org/tasks/ui/ActionViewModel.kt +++ b/app/src/main/java/org/tasks/ui/ActionViewModel.kt @@ -1,14 +1,8 @@ package org.tasks.ui -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.observe -import com.todoroo.andlib.utility.AndroidUtilities -import io.reactivex.Completable -import io.reactivex.android.schedulers.AndroidSchedulers +import androidx.lifecycle.* import io.reactivex.disposables.CompositeDisposable -import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.launch open class ActionViewModel : ViewModel() { private val completed = MutableLiveData() @@ -20,25 +14,26 @@ open class ActionViewModel : ViewModel() { fun observe( lifecycleOwner: LifecycleOwner, - completeObserver: (Boolean) -> Unit, + completeObserver: suspend (Boolean) -> Any, errorObserver: (Throwable) -> Unit) { - completed.observe(lifecycleOwner, completeObserver) + completed.observe(lifecycleOwner) { + lifecycleOwner.lifecycleScope.launch { + completeObserver.invoke(it) + } + } error.observe(lifecycleOwner, errorObserver) } - protected fun run(action: () -> Unit) { - AndroidUtilities.assertMainThread() + protected suspend fun run(action: suspend () -> Unit) { if (!inProgress) { inProgress = true - disposables.add( - Completable.fromAction(action) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .doFinally { - AndroidUtilities.assertMainThread() - inProgress = false - } - .subscribe({ completed.setValue(true) }) { value: Throwable -> error.setValue(value) }) + try { + action.invoke() + completed.value = true + } catch (e: Exception) { + error.value = e + } + inProgress = false } } diff --git a/app/src/main/java/org/tasks/ui/CompletableViewModel.kt b/app/src/main/java/org/tasks/ui/CompletableViewModel.kt index 062044b47..ca2f3edb4 100644 --- a/app/src/main/java/org/tasks/ui/CompletableViewModel.kt +++ b/app/src/main/java/org/tasks/ui/CompletableViewModel.kt @@ -1,14 +1,8 @@ package org.tasks.ui -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.observe -import com.todoroo.andlib.utility.AndroidUtilities -import io.reactivex.Single -import io.reactivex.android.schedulers.AndroidSchedulers +import androidx.lifecycle.* import io.reactivex.disposables.CompositeDisposable -import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.launch abstract class CompletableViewModel : ViewModel() { private val data = MutableLiveData() @@ -20,25 +14,25 @@ abstract class CompletableViewModel : ViewModel() { fun observe( lifecycleOwner: LifecycleOwner, - dataObserver: (T) -> Unit, + dataObserver: suspend (T) -> Unit, errorObserver: (Throwable) -> Unit) { - data.observe(lifecycleOwner, dataObserver) + data.observe(lifecycleOwner) { + lifecycleOwner.lifecycleScope.launch { + dataObserver.invoke(it) + } + } error.observe(lifecycleOwner, errorObserver) } - protected fun run(callable: () -> T) { - AndroidUtilities.assertMainThread() + protected suspend fun run(callable: suspend () -> T) { if (!inProgress) { inProgress = true - disposables.add( - Single.fromCallable(callable) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .doFinally { - AndroidUtilities.assertMainThread() - inProgress = false - } - .subscribe({ value: T -> data.setValue(value) }) { value: Throwable -> error.setValue(value) }) + try { + data.value = callable.invoke() + } catch (e: Exception) { + error.value = e + } + inProgress = false } }