Skip to content

Commit

Permalink
refactor: CustomStudyListener => FragmentResultApi
Browse files Browse the repository at this point in the history
Fixes 17665
  • Loading branch information
Aditya13s authored and david-allison committed Jan 6, 2025
1 parent 1a96697 commit 3077325
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 98 deletions.
32 changes: 17 additions & 15 deletions AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ import com.ichi2.anki.dialogs.SyncErrorDialog
import com.ichi2.anki.dialogs.SyncErrorDialog.Companion.newInstance
import com.ichi2.anki.dialogs.SyncErrorDialog.SyncErrorDialogListener
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyListener
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialogFactory
import com.ichi2.anki.export.ActivityExportingDelegate
import com.ichi2.anki.export.ExportDialogFragment
Expand Down Expand Up @@ -240,7 +240,6 @@ open class DeckPicker :
ImportDialogListener,
MediaCheckDialogListener,
OnRequestPermissionsResultCallback,
CustomStudyListener,
ChangeManager.Subscriber,
SyncCompletionListener,
ImportColpkgListener,
Expand Down Expand Up @@ -493,7 +492,7 @@ open class DeckPicker :
return
}
exportingDelegate = ActivityExportingDelegate(this) { getColUnsafe }
customStudyDialogFactory = CustomStudyDialogFactory({ getColUnsafe }, this).attachToActivity(this)
customStudyDialogFactory = CustomStudyDialogFactory { getColUnsafe }.attachToActivity(this)

// Then set theme and content view
super.onCreate(savedInstanceState)
Expand Down Expand Up @@ -599,6 +598,21 @@ open class DeckPicker :

checkWebviewVersion(this)

supportFragmentManager.setFragmentResultListener(CustomStudyAction.REQUEST_KEY, this) { requestKey, bundle ->
when (CustomStudyAction.fromBundle(bundle)) {
CustomStudyAction.CUSTOM_STUDY_SESSION -> {
updateDeckList()
openStudyOptions(false)
}
CustomStudyAction.EXTEND_STUDY_LIMITS -> {
if (fragmented) {
fragment!!.refreshInterface()
}
updateDeckList()
}
}
}

supportFragmentManager.setFragmentResultListener(DeckPickerContextMenu.REQUEST_KEY_CONTEXT_MENU, this) { requestKey, arguments ->
when (requestKey) {
DeckPickerContextMenu.REQUEST_KEY_CONTEXT_MENU ->
Expand Down Expand Up @@ -2475,18 +2489,6 @@ open class DeckPicker :
reviewLauncher.launch(intent)
}

override fun onCreateCustomStudySession() {
updateDeckList()
openStudyOptions(false)
}

override fun onExtendStudyLimits() {
if (fragmented) {
fragment!!.refreshInterface()
}
updateDeckList()
}

private fun handleEmptyCards() {
launchCatchingTask {
val emptyCids =
Expand Down
27 changes: 12 additions & 15 deletions AnkiDroid/src/main/java/com/ichi2/anki/SingleFragmentActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import androidx.fragment.app.FragmentContainerView
import androidx.fragment.app.commit
import com.ichi2.anki.android.input.ShortcutGroup
import com.ichi2.anki.android.input.ShortcutGroupProvider
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialogFactory
import com.ichi2.utils.ExtendedFragmentFactory
import com.ichi2.utils.FragmentFactoryUtils
Expand All @@ -41,9 +41,7 @@ import kotlin.reflect.jvm.jvmName
*
* [getIntent] can be used as an easy way to build a [SingleFragmentActivity]
*/
open class SingleFragmentActivity :
AnkiActivity(),
CustomStudyDialog.CustomStudyListener {
open class SingleFragmentActivity : AnkiActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
if (showedActivityFailedScreen(savedInstanceState)) {
return
Expand All @@ -52,7 +50,7 @@ open class SingleFragmentActivity :
// This page *may* host the CustomStudyDialog (CongratsPage)
// CustomStudyDialog requires a custom factory install during lifecycle or it can
// crash during lifecycle resume after background kill
val customStudyDialogFactory = CustomStudyDialogFactory({ this.getColUnsafe }, this)
val customStudyDialogFactory = CustomStudyDialogFactory { this.getColUnsafe }
customStudyDialogFactory.attachToActivity<ExtendedFragmentFactory>(this)

super.onCreate(savedInstanceState)
Expand Down Expand Up @@ -81,6 +79,15 @@ open class SingleFragmentActivity :
supportFragmentManager.commit {
replace(R.id.fragment_container, fragment, FRAGMENT_TAG)
}

supportFragmentManager.setFragmentResultListener(CustomStudyAction.REQUEST_KEY, this) { requestKey, bundle ->
when (CustomStudyAction.fromBundle(bundle)) {
CustomStudyAction.CUSTOM_STUDY_SESSION,
CustomStudyAction.EXTEND_STUDY_LIMITS,
->
openStudyOptionsAndFinish()
}
}
}

override fun dispatchKeyEvent(event: KeyEvent): Boolean {
Expand Down Expand Up @@ -124,16 +131,6 @@ open class SingleFragmentActivity :
this.finish()
}

override fun onExtendStudyLimits() {
Timber.v("CustomStudyListener::onExtendStudyLimits()")
openStudyOptionsAndFinish()
}

override fun onCreateCustomStudySession() {
Timber.v("CustomStudyListener::onCreateCustomStudySession()")
openStudyOptionsAndFinish()
}

// END CustomStudyListener temporary implementation - should refactor out
}

Expand Down
27 changes: 11 additions & 16 deletions AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import androidx.lifecycle.lifecycleScope
import anki.collection.OpChanges
import com.ichi2.anki.CollectionManager.withCol
import com.ichi2.anki.StudyOptionsFragment.StudyOptionsListener
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyListener
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialogFactory
import com.ichi2.libanki.ChangeManager
import com.ichi2.ui.RtlCompliantActionProvider
Expand All @@ -36,15 +36,14 @@ import kotlinx.coroutines.launch
class StudyOptionsActivity :
AnkiActivity(),
StudyOptionsListener,
CustomStudyListener,
ChangeManager.Subscriber {
private var undoState = UndoState()

override fun onCreate(savedInstanceState: Bundle?) {
if (showedActivityFailedScreen(savedInstanceState)) {
return
}
val customStudyDialogFactory = CustomStudyDialogFactory({ this.getColUnsafe }, this)
val customStudyDialogFactory = CustomStudyDialogFactory { this.getColUnsafe }
customStudyDialogFactory.attachToActivity<ExtendedFragmentFactory>(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.studyoptions)
Expand All @@ -53,6 +52,15 @@ class StudyOptionsActivity :
loadStudyOptionsFragment()
}
setResult(RESULT_OK)

supportFragmentManager.setFragmentResultListener(CustomStudyAction.REQUEST_KEY, this) { requestKey, bundle ->
when (CustomStudyAction.fromBundle(bundle)) {
CustomStudyAction.CUSTOM_STUDY_SESSION,
CustomStudyAction.EXTEND_STUDY_LIMITS,
->
currentFragment!!.refreshInterface()
}
}
}

private fun loadStudyOptionsFragment() {
Expand Down Expand Up @@ -118,19 +126,6 @@ class StudyOptionsActivity :
currentFragment!!.refreshInterface()
}

/**
* Callback methods from CustomStudyDialog
*/
override fun onCreateCustomStudySession() {
// Sched already reset by CollectionTask in CustomStudyDialog
currentFragment!!.refreshInterface()
}

override fun onExtendStudyLimits() {
// Sched needs to be reset so provide true argument
currentFragment!!.refreshInterface()
}

override fun opExecuted(
changes: OpChanges,
handler: Any?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ import android.widget.TextView
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AlertDialog
import androidx.core.content.edit
import androidx.core.os.bundleOf
import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.setFragmentResult
import anki.scheduler.CustomStudyDefaultsResponse
import anki.scheduler.customStudyRequest
import com.ichi2.anki.CollectionManager.TR
Expand Down Expand Up @@ -111,18 +113,10 @@ import timber.log.Timber
* * [https://github.com/ankitects/anki/blob/main/qt/aqt/customstudy.py](https://github.com/ankitects/anki/blob/main/qt/aqt/customstudy.py)
*/
@KotlinCleanup("remove 'collection' parameter and use withCol { }")
@KotlinCleanup("remove 'customStudyListener' parameter and use FragmentResult")
class CustomStudyDialog(
private val collection: Collection,
private val customStudyListener: CustomStudyListener?,
) : AnalyticsDialogFragment(),
TagsDialogListener {
interface CustomStudyListener {
fun onCreateCustomStudySession()

fun onExtendStudyLimits()
}

/** ID of the [Deck] which this dialog was created for */
private val dialogDeckId: DeckId
get() = requireArguments().getLong(ARG_DID)
Expand Down Expand Up @@ -200,7 +194,7 @@ class CustomStudyDialog(
-> {
// User asked for a standard custom study option
val d =
CustomStudyDialog(collection, customStudyListener)
CustomStudyDialog(collection)
.withArguments(dialogDeckId, item)
requireActivity().showDialogFragment(d)
}
Expand Down Expand Up @@ -328,12 +322,14 @@ class CustomStudyDialog(
undoableOp {
collection.sched.customStudy(request)
}
when (contextMenuOption) {
EXTEND_NEW, EXTEND_REV ->
customStudyListener?.onExtendStudyLimits()
STUDY_FORGOT, STUDY_AHEAD, STUDY_PREVIEW -> customStudyListener?.onCreateCustomStudySession()
STUDY_TAGS -> TODO("This branch has not been covered before")
}
val action =
when (contextMenuOption) {
EXTEND_NEW, EXTEND_REV -> CustomStudyAction.EXTEND_STUDY_LIMITS
STUDY_FORGOT, STUDY_AHEAD, STUDY_PREVIEW -> CustomStudyAction.CUSTOM_STUDY_SESSION
STUDY_TAGS -> TODO("This branch has not been covered before")
}

setFragmentResult(CustomStudyAction.REQUEST_KEY, bundleOf(CustomStudyAction.BUNDLE_KEY to action.ordinal))
} finally {
requireActivity().dismissAllDialogFragments()
}
Expand Down Expand Up @@ -480,7 +476,33 @@ class CustomStudyDialog(
Timber.d("rebuildDynamicDeck()")
withProgress {
withCol { sched.rebuildDyn(decks.selected()) }
customStudyListener?.onCreateCustomStudySession()
setFragmentResult(
CustomStudyAction.REQUEST_KEY,
bundleOf(
CustomStudyAction.BUNDLE_KEY to CustomStudyAction.CUSTOM_STUDY_SESSION.ordinal,
),
)
}
}

/**
* Represents actions for managing custom study sessions and extending study limits.
* These actions are passed between fragments and activities via the FragmentResult API.
*/
enum class CustomStudyAction {
EXTEND_STUDY_LIMITS,
CUSTOM_STUDY_SESSION,
;

companion object {
const val REQUEST_KEY = "CustomStudyDialog"
const val BUNDLE_KEY = "action"

/** Extracts a [CustomStudyAction] from a [Bundle] */
fun fromBundle(bundle: Bundle): CustomStudyAction =
bundle.getInt(CustomStudyAction.BUNDLE_KEY).let { actionOrdinal ->
entries.first { it.ordinal == actionOrdinal }
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@
package com.ichi2.anki.dialogs.customstudy

import androidx.fragment.app.Fragment
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyListener
import com.ichi2.libanki.Collection
import com.ichi2.utils.ExtendedFragmentFactory
import java.util.function.Supplier

class CustomStudyDialogFactory(
val collectionSupplier: Supplier<Collection>,
private val customStudyListener: CustomStudyListener?,
) : ExtendedFragmentFactory() {
override fun instantiate(
classLoader: ClassLoader,
Expand All @@ -37,5 +35,5 @@ class CustomStudyDialogFactory(
}
}

fun newCustomStudyDialog(): CustomStudyDialog = CustomStudyDialog(collectionSupplier.get(), customStudyListener)
fun newCustomStudyDialog(): CustomStudyDialog = CustomStudyDialog(collectionSupplier.get())
}
24 changes: 11 additions & 13 deletions AnkiDroid/src/main/java/com/ichi2/anki/pages/CongratsPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.flowWithLifecycle
Expand All @@ -36,6 +37,7 @@ import com.ichi2.anki.OnErrorListener
import com.ichi2.anki.R
import com.ichi2.anki.StudyOptionsActivity
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog
import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction
import com.ichi2.anki.launchCatchingIO
import com.ichi2.anki.launchCatchingTask
import com.ichi2.anki.preferences.sharedPrefs
Expand All @@ -55,7 +57,6 @@ import kotlin.math.round

class CongratsPage :
PageFragment(),
CustomStudyDialog.CustomStudyListener,
ChangeManager.Subscriber {
private val viewModel by viewModels<CongratsViewModel>()

Expand Down Expand Up @@ -110,6 +111,14 @@ class CongratsPage :
true
}
}

setFragmentResultListener(CustomStudyAction.REQUEST_KEY) { requestKey, bundle ->
when (CustomStudyAction.fromBundle(bundle)) {
CustomStudyAction.CUSTOM_STUDY_SESSION,
CustomStudyAction.EXTEND_STUDY_LIMITS,
-> openStudyOptionsAndFinish()
}
}
}

override val bridgeCommands =
Expand All @@ -130,23 +139,12 @@ class CongratsPage :
private fun onStudyMore() {
val col = CollectionManager.getColUnsafe()
val dialogFragment =
CustomStudyDialog(CollectionManager.getColUnsafe(), this).withArguments(
CustomStudyDialog(CollectionManager.getColUnsafe()).withArguments(
col.decks.selected(),
)
dialogFragment.show(childFragmentManager, null)
}

/******************************** CustomStudyListener methods ********************************/
override fun onExtendStudyLimits() {
Timber.v("CustomStudyListener::onExtendStudyLimits()")
openStudyOptionsAndFinish()
}

override fun onCreateCustomStudySession() {
Timber.v("CustomStudyListener::onCreateCustomStudySession()")
openStudyOptionsAndFinish()
}

companion object {
fun getIntent(context: Context): Intent = getIntent(context, path = "congrats", clazz = CongratsPage::class)

Expand Down
Loading

0 comments on commit 3077325

Please sign in to comment.