Skip to content

Commit 37b86be

Browse files
david-allisonmikehardy
authored andcommitted
fix(custom-study): not attached to an activity
* positiveButton { } closed the dialog * so setFragmentResult() threw as there was no fragment manager Fixed by: * setting the click handler manually, so `dismiss` isn't called * move `dismiss` into the call, for clarity that the dialog is dismissed Fixes 17757
1 parent e25af62 commit 37b86be

File tree

1 file changed

+44
-23
lines changed

1 file changed

+44
-23
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialog.kt

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ class CustomStudyDialog(
247247
* Build an input dialog that is used to get a parameter related to custom study from the user
248248
* @param contextMenuOption the option of the dialog
249249
*/
250+
@NeedsTest("17757: fragment not dismissed before result is output")
250251
private fun buildInputDialog(contextMenuOption: ContextMenuOption): AlertDialog {
251252
/*
252253
TODO: Try to change to a standard input dialog (currently the thing holding us back is having the extra
@@ -275,21 +276,45 @@ class CustomStudyDialog(
275276
}
276277

277278
// Set material dialog parameters
279+
@Suppress("RedundantValueArgument") // click = null
278280
val dialog =
279281
AlertDialog
280282
.Builder(requireActivity())
281283
.customView(view = v, paddingStart = 64, paddingEnd = 64, paddingTop = 32, paddingBottom = 32)
282-
.positiveButton(R.string.dialog_ok) {
283-
// Get the value selected by user
284-
val n =
285-
editText.textAsIntOrNull() ?: return@positiveButton Unit.also {
286-
Timber.w("Non-numeric user input was provided")
287-
Timber.d("value: %s", editText.text.toString())
288-
}
289-
requireActivity().launchCatchingTask { customStudy(contextMenuOption, n) }
290-
}.negativeButton(R.string.dialog_cancel) {
284+
.positiveButton(R.string.dialog_ok, click = null)
285+
.negativeButton(R.string.dialog_cancel) {
291286
requireActivity().dismissAllDialogFragments()
292-
}.create() // Added .create() because we wanted to access alertDialog positive button enable state
287+
}.create()
288+
289+
var allowSubmit = true
290+
// we set the listener here so 'ok' doesn't immediately close the dialog.
291+
// if it did, we would not have had time to execute the method, and would not be
292+
// able to output a fragment result
293+
dialog.setOnShowListener {
294+
dialog.positiveButton.setOnClickListener {
295+
// prevent race conditions
296+
if (!allowSubmit) return@setOnClickListener
297+
allowSubmit = false
298+
299+
// Get the value selected by user
300+
val n =
301+
editText.textAsIntOrNull() ?: run {
302+
Timber.w("Non-numeric user input was provided")
303+
Timber.d("value: %s", editText.text.toString())
304+
allowSubmit = true
305+
return@setOnClickListener
306+
}
307+
308+
requireActivity().launchCatchingTask {
309+
try {
310+
customStudy(contextMenuOption, n)
311+
} finally {
312+
requireActivity().dismissAllDialogFragments()
313+
}
314+
}
315+
}
316+
}
317+
293318
editText.doAfterTextChanged {
294319
dialog.positiveButton.isEnabled = editText.textAsIntOrNull() != null
295320
}
@@ -318,21 +343,17 @@ class CustomStudyDialog(
318343
}
319344
}
320345

321-
try {
322-
undoableOp {
323-
collection.sched.customStudy(request)
346+
undoableOp {
347+
collection.sched.customStudy(request)
348+
}
349+
val action =
350+
when (contextMenuOption) {
351+
EXTEND_NEW, EXTEND_REV -> CustomStudyAction.EXTEND_STUDY_LIMITS
352+
STUDY_FORGOT, STUDY_AHEAD, STUDY_PREVIEW -> CustomStudyAction.CUSTOM_STUDY_SESSION
353+
STUDY_TAGS -> TODO("This branch has not been covered before")
324354
}
325-
val action =
326-
when (contextMenuOption) {
327-
EXTEND_NEW, EXTEND_REV -> CustomStudyAction.EXTEND_STUDY_LIMITS
328-
STUDY_FORGOT, STUDY_AHEAD, STUDY_PREVIEW -> CustomStudyAction.CUSTOM_STUDY_SESSION
329-
STUDY_TAGS -> TODO("This branch has not been covered before")
330-
}
331355

332-
setFragmentResult(CustomStudyAction.REQUEST_KEY, bundleOf(CustomStudyAction.BUNDLE_KEY to action.ordinal))
333-
} finally {
334-
requireActivity().dismissAllDialogFragments()
335-
}
356+
setFragmentResult(CustomStudyAction.REQUEST_KEY, bundleOf(CustomStudyAction.BUNDLE_KEY to action.ordinal))
336357

337358
// save the default values (not in upstream)
338359
when (contextMenuOption) {

0 commit comments

Comments
 (0)