@@ -25,23 +25,25 @@ import android.widget.TextView
2525import androidx.activity.addCallback
2626import androidx.core.os.bundleOf
2727import androidx.fragment.app.viewModels
28+ import androidx.lifecycle.Lifecycle
2829import androidx.lifecycle.lifecycleScope
30+ import androidx.lifecycle.repeatOnLifecycle
2931import com.google.android.material.appbar.MaterialToolbar
30- import com.ichi2.anki.CollectionManager.withCol
3132import com.ichi2.anki.R
3233import com.ichi2.anki.SingleFragmentActivity
3334import com.ichi2.anki.common.annotations.NeedsTest
35+ import com.ichi2.anki.common.utils.android.isRobolectric
3436import com.ichi2.anki.dialogs.DeckSelectionDialog
3537import com.ichi2.anki.dialogs.DiscardChangesDialog
36- import com.ichi2.anki.launchCatchingTask
3738import com.ichi2.anki.model.SelectableDeck
3839import com.ichi2.anki.pages.viewmodel.ImageOcclusionArgs
3940import com.ichi2.anki.pages.viewmodel.ImageOcclusionViewModel
4041import com.ichi2.anki.pages.viewmodel.ImageOcclusionViewModel.Companion.IO_ARGS_KEY
41- import com.ichi2.anki.requireAnkiActivity
42- import com.ichi2.anki.selectedDeckIfNotFiltered
4342import com.ichi2.anki.startDeckSelection
43+ import com.ichi2.utils.HandlerUtils
44+ import kotlinx.coroutines.flow.Flow
4445import kotlinx.coroutines.launch
46+ import kotlinx.coroutines.runBlocking
4547import timber.log.Timber
4648
4749/* *
@@ -80,11 +82,6 @@ class ImageOcclusion :
8082 deckNameView = view.findViewById(R .id.deck_name)
8183 deckNameView.setOnClickListener { startDeckSelection(all = false , filtered = false , skipEmptyDefault = false ) }
8284
83- requireAnkiActivity().launchCatchingTask {
84- val selectedDeck = withCol { selectedDeckIfNotFiltered() }
85- deckNameView.text = selectedDeck.name
86- }
87-
8885 @NeedsTest(" #17393 verify that the added image occlusion cards are put in the correct deck" )
8986 view.findViewById<MaterialToolbar >(R .id.toolbar).setOnMenuItemClickListener {
9087 if (it.itemId == R .id.action_save) {
@@ -93,6 +90,8 @@ class ImageOcclusion :
9390 }
9491 return @setOnMenuItemClickListener true
9592 }
93+
94+ setupFlows()
9695 }
9796
9897 override fun onCreateWebViewClient (savedInstanceState : Bundle ? ): PageWebViewClient =
@@ -113,13 +112,7 @@ class ImageOcclusion :
113112 override fun onDeckSelected (deck : SelectableDeck ? ) {
114113 if (deck == null ) return
115114 require(deck is SelectableDeck .Deck )
116- deckNameView.text = deck.name
117- val deckDidChange = viewModel.handleDeckSelection(deck.deckId)
118- if (deckDidChange) {
119- viewLifecycleOwner.lifecycleScope.launch {
120- withCol { decks.select(viewModel.selectedDeckId) }
121- }
122- }
115+ viewModel.handleDeckSelection(deck.deckId)
123116 }
124117
125118 // HACK: detect a successful save; #19443 will provide a better method
@@ -134,6 +127,29 @@ class ImageOcclusion :
134127 }
135128 }
136129
130+ private fun setupFlows () {
131+ fun onDeckNameChanged (name : String ) {
132+ deckNameView.text = name
133+ }
134+
135+ viewModel.deckNameFlow.launchCollectionInLifecycleScope(::onDeckNameChanged)
136+ }
137+
138+ // TODO: Move this to an extension method once we have context parameters
139+ private fun <T > Flow<T>.launchCollectionInLifecycleScope (block : suspend (T ) -> Unit ) {
140+ lifecycleScope.launch {
141+ lifecycle.repeatOnLifecycle(Lifecycle .State .RESUMED ) {
142+ this @launchCollectionInLifecycleScope.collect {
143+ if (isRobolectric) {
144+ HandlerUtils .postOnNewHandler { runBlocking { block(it) } }
145+ } else {
146+ block(it)
147+ }
148+ }
149+ }
150+ }
151+ }
152+
137153 companion object {
138154 /* *
139155 * @param args arguments for either adding or editing a note
0 commit comments