Skip to content

Commit

Permalink
Fix bug around restoring InsertFieldDialog
Browse files Browse the repository at this point in the history
  • Loading branch information
lukstbit authored and mikehardy committed Jun 11, 2022
1 parent 6555165 commit def1491
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 65 deletions.
31 changes: 14 additions & 17 deletions AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@ import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.ichi2.anim.ActivityTransitionAnimation.Direction.*
import com.ichi2.anki.dialogs.ConfirmationDialog
import com.ichi2.anki.dialogs.DeckSelectionDialog
import com.ichi2.anki.dialogs.*
import com.ichi2.anki.dialogs.DeckSelectionDialog.DeckSelectionListener
import com.ichi2.anki.dialogs.DeckSelectionDialog.SelectableDeck
import com.ichi2.anki.dialogs.DiscardChangesDialog
import com.ichi2.anki.dialogs.InsertFieldDialog.InsertFieldListener
import com.ichi2.anki.dialogs.InsertFieldDialogFactory
import com.ichi2.anki.dialogs.InsertFieldDialog.Companion.REQUEST_FIELD_INSERT
import com.ichi2.anki.exception.ConfirmModSchemaException
import com.ichi2.annotations.NeedsTest
import com.ichi2.async.TaskListenerWithContext
import com.ichi2.libanki.*
import com.ichi2.libanki.Collection
Expand Down Expand Up @@ -428,20 +426,13 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener {
}
}

@NeedsTest(
"the kotlin migration made this method crash due to a recursive call when the dialog would return its data"
)
private fun showInsertFieldDialog() {
if (mTemplateEditor.mFieldNames == null) {
return
mTemplateEditor.mFieldNames?.let { fieldNames ->
mTemplateEditor.showDialogFragment(InsertFieldDialog.newInstance(fieldNames))
}
val insertFieldDialogFactory = InsertFieldDialogFactory(
object : InsertFieldListener {
override fun insertField(field: String?) {
insertField(field)
}
}).attachToActivity<InsertFieldDialogFactory>(mTemplateEditor)
val insertFieldDialog = insertFieldDialogFactory
.newInsertFieldDialog()
.withArguments(mTemplateEditor.mFieldNames!!)
mTemplateEditor.showDialogFragment(insertFieldDialog)
}

@Suppress("unused")
Expand All @@ -463,6 +454,12 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
initTabLayoutMediator()
parentFragmentManager.setFragmentResultListener(REQUEST_FIELD_INSERT, viewLifecycleOwner) { key, bundle ->
if (key == REQUEST_FIELD_INSERT) {
// this is guaranteed to be non null, as we put a non null value on the other side
insertField(bundle.getString(InsertFieldDialog.KEY_INSERTED_FIELD)!!)
}
}
}

private fun initTabLayoutMediator() {
Expand Down
41 changes: 28 additions & 13 deletions AnkiDroid/src/main/java/com/ichi2/anki/dialogs/InsertFieldDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,30 @@ package com.ichi2.anki.dialogs
import android.os.Bundle
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.MaterialDialog
import com.ichi2.anki.CardTemplateEditor
import com.ichi2.anki.R
import java.util.*

/**
* This is a reusable convenience class which makes it easy to show a insert field dialog as a DialogFragment.
* Create a new instance with required fields list, then show it via the fragment manager as usual.
* Dialog fragment used to show the fields that the user can insert in the card editor. This
* fragment can notify other fragments from the same activity about an inserted field.
*
* @see [CardTemplateEditor.CardTemplateFragment]
*/
class InsertFieldDialog(private val insertFieldListener: InsertFieldListener) : DialogFragment() {
class InsertFieldDialog : DialogFragment() {
private lateinit var mDialog: MaterialDialog
private lateinit var mFieldList: List<String>
fun withArguments(fieldItems: List<String>): InsertFieldDialog {
val args = Bundle()
args.putStringArrayList("fieldItems", ArrayList(fieldItems))
this.arguments = args
return this
}

/**
* A dialog for inserting field in card template editor
*/
override fun onCreateDialog(savedInstanceState: Bundle?): MaterialDialog {
super.onCreate(savedInstanceState)
mFieldList = requireArguments().getStringArrayList("fieldItems")!!
mFieldList = requireArguments().getStringArrayList(KEY_FIELD_ITEMS)!!
val adapter: RecyclerView.Adapter<*> = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val root = layoutInflater.inflate(R.layout.material_dialog_list_item, parent, false)
Expand All @@ -70,11 +68,28 @@ class InsertFieldDialog(private val insertFieldListener: InsertFieldListener) :
}

private fun selectFieldAndClose(textView: TextView) {
insertFieldListener.insertField(textView.text.toString())
parentFragmentManager.setFragmentResult(
REQUEST_FIELD_INSERT,
bundleOf(KEY_INSERTED_FIELD to textView.text.toString())
)
mDialog.dismiss()
}

interface InsertFieldListener {
fun insertField(field: String?)
companion object {
/**
* Other fragments sharing the activity can use this with
* [androidx.fragment.app.FragmentManager.setFragmentResultListener] to get a result back.
*/
const val REQUEST_FIELD_INSERT = "request_field_insert"

/**
* This fragment requires that a list of fields names to be passed in.
*/
const val KEY_INSERTED_FIELD = "key_inserted_field"
private const val KEY_FIELD_ITEMS = "key_field_items"

fun newInstance(fieldItems: List<String>): InsertFieldDialog = InsertFieldDialog().apply {
arguments = bundleOf(KEY_FIELD_ITEMS to ArrayList(fieldItems))
}
}
}

This file was deleted.

0 comments on commit def1491

Please sign in to comment.