diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/BackendUndo.kt b/AnkiDroid/src/main/java/com/ichi2/anki/BackendUndo.kt index 76f3179f4e51..4693050130f5 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/BackendUndo.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/BackendUndo.kt @@ -16,13 +16,15 @@ package com.ichi2.anki +import androidx.fragment.app.FragmentActivity +import com.ichi2.anki.CollectionManager.TR import com.ichi2.anki.UIUtils.showSimpleSnackbar import com.ichi2.libanki.undoNew import com.ichi2.libanki.undoableOp import com.ichi2.utils.BlocksSchemaUpgrade import net.ankiweb.rsdroid.BackendException -suspend fun AnkiActivity.backendUndoAndShowPopup(): Boolean { +suspend fun FragmentActivity.backendUndoAndShowPopup(): Boolean { return try { val changes = withProgress() { undoableOp { @@ -31,7 +33,7 @@ suspend fun AnkiActivity.backendUndoAndShowPopup(): Boolean { } showSimpleSnackbar( this, - col.tr.undoActionUndone(changes.operation), + TR.undoActionUndone(changes.operation), false ) true diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CoroutineHelpers.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CoroutineHelpers.kt index 0762ae7020c9..8fa70366548c 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CoroutineHelpers.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CoroutineHelpers.kt @@ -18,6 +18,8 @@ package com.ichi2.anki import android.content.Context import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity import androidx.lifecycle.coroutineScope import anki.collection.Progress import com.ichi2.anki.UIUtils.showSimpleSnackbar @@ -36,27 +38,35 @@ import kotlin.coroutines.suspendCoroutine * Errors from the backend contain localized text that is often suitable to show to the user as-is. * Other errors should ideally be handled in the block. */ -fun AnkiActivity.launchCatchingTask( +fun FragmentActivity.launchCatchingTask( + errorMessage: String? = null, block: suspend CoroutineScope.() -> Unit ): Job { + val extraInfo = errorMessage ?: "" return lifecycle.coroutineScope.launch { try { block() } catch (exc: CancellationException) { // do nothing } catch (exc: BackendInterruptedException) { - Timber.e("caught: %s", exc) + Timber.e("caught: %s %s", exc, extraInfo) showSimpleSnackbar(this@launchCatchingTask, exc.localizedMessage, false) } catch (exc: BackendException) { - Timber.e("caught: %s", exc) + Timber.e("caught: %s %s", exc, extraInfo) showError(this@launchCatchingTask, exc.localizedMessage!!) } catch (exc: Exception) { - Timber.e("caught: %s", exc) + Timber.e("caught: %s %s", exc, extraInfo) showError(this@launchCatchingTask, exc.toString()) } } } +/** See [FragmentActivity.launchCatchingTask] */ +fun Fragment.launchCatchingTask( + errorMessage: String? = null, + block: suspend CoroutineScope.() -> Unit +): Job = requireActivity().launchCatchingTask(errorMessage, block) + private fun showError(context: Context, msg: String) { AlertDialog.Builder(context) .setTitle(R.string.vague_error) @@ -90,7 +100,7 @@ suspend fun Backend.withProgress( * Run the provided operation, showing a progress window until it completes. * Progress info is polled from the backend. */ -suspend fun AnkiActivity.withProgress( +suspend fun FragmentActivity.withProgress( extractProgress: ProgressContext.() -> Unit, onCancel: ((Backend) -> Unit)? = { it.setWantsAbort() }, op: suspend () -> T @@ -117,7 +127,7 @@ suspend fun AnkiActivity.withProgress( * Run the provided operation, showing a progress window with the provided * message until the operation completes. */ -suspend fun AnkiActivity.withProgress( +suspend fun FragmentActivity.withProgress( message: String = resources.getString(R.string.dialog_processing), op: suspend () -> T ): T = withProgressDialog( @@ -130,7 +140,7 @@ suspend fun AnkiActivity.withProgress( } private suspend fun withProgressDialog( - context: AnkiActivity, + context: FragmentActivity, onCancel: (() -> Unit)?, @Suppress("Deprecation") // ProgressDialog deprecation op: suspend (android.app.ProgressDialog) -> T diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsFragment.kt index 97df3cf0cd4e..7650ea4dd47d 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsFragment.kt @@ -50,6 +50,7 @@ import com.ichi2.themes.StyledProgressDialog.Companion.show import com.ichi2.utils.FragmentFactoryUtils.instantiate import com.ichi2.utils.HtmlUtils.convertNewlinesToHtml import com.ichi2.utils.KotlinCleanup +import net.ankiweb.rsdroid.BackendFactory import timber.log.Timber class StudyOptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener { @@ -255,7 +256,17 @@ class StudyOptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener { when (item.itemId) { R.id.action_undo -> { Timber.i("StudyOptionsFragment:: Undo button pressed") - Undo().runWithHandler(mUndoListener) + if (BackendFactory.defaultLegacySchema) { + Undo().runWithHandler(mUndoListener) + } else { + launchCatchingTask { + if (requireActivity().backendUndoAndShowPopup()) { + openReviewer() + } else { + Undo().runWithHandler(mUndoListener) + } + } + } return true } R.id.action_deck_or_study_options -> {