ui: use event everywhere
Replace all prior uses of the StateFlow + finish method pattern with the new event class.
This commit is contained in:
parent
f0d62e8176
commit
1df15a32cd
10 changed files with 67 additions and 81 deletions
|
@ -129,12 +129,12 @@ class MainFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
collect(navModel.mainNavigationAction, ::handleMainNavigation)
|
collect(navModel.mainNavigationAction.flow, ::handleMainNavigation)
|
||||||
collect(navModel.exploreNavigationItem, ::handleExploreNavigation)
|
collect(navModel.exploreNavigationItem.flow, ::handleExploreNavigation)
|
||||||
collect(navModel.exploreArtistNavigationItem, ::handleArtistNavigationPicker)
|
collect(navModel.exploreArtistNavigationItem.flow, ::handleArtistNavigationPicker)
|
||||||
collectImmediately(playbackModel.song, ::updateSong)
|
collectImmediately(playbackModel.song, ::updateSong)
|
||||||
collect(playbackModel.artistPickerSong, ::handlePlaybackArtistPicker)
|
collect(playbackModel.artistPickerSong.flow, ::handlePlaybackArtistPicker)
|
||||||
collect(playbackModel.genrePickerSong, ::handlePlaybackGenrePicker)
|
collect(playbackModel.genrePickerSong.flow, ::handlePlaybackGenrePicker)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
|
@ -273,7 +273,7 @@ class MainFragment :
|
||||||
is MainNavigationAction.Directions -> findNavController().navigate(action.directions)
|
is MainNavigationAction.Directions -> findNavController().navigate(action.directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
navModel.finishMainNavigation()
|
navModel.mainNavigationAction.consume()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleExploreNavigation(item: Music?) {
|
private fun handleExploreNavigation(item: Music?) {
|
||||||
|
@ -287,7 +287,7 @@ class MainFragment :
|
||||||
navModel.mainNavigateTo(
|
navModel.mainNavigateTo(
|
||||||
MainNavigationAction.Directions(
|
MainNavigationAction.Directions(
|
||||||
MainFragmentDirections.actionPickNavigationArtist(item.uid)))
|
MainFragmentDirections.actionPickNavigationArtist(item.uid)))
|
||||||
navModel.finishExploreNavigation()
|
navModel.exploreArtistNavigationItem.consume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ class MainFragment :
|
||||||
navModel.mainNavigateTo(
|
navModel.mainNavigateTo(
|
||||||
MainNavigationAction.Directions(
|
MainNavigationAction.Directions(
|
||||||
MainFragmentDirections.actionPickPlaybackArtist(song.uid)))
|
MainFragmentDirections.actionPickPlaybackArtist(song.uid)))
|
||||||
playbackModel.finishPlaybackArtistPicker()
|
playbackModel.artistPickerSong.consume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ class MainFragment :
|
||||||
navModel.mainNavigateTo(
|
navModel.mainNavigateTo(
|
||||||
MainNavigationAction.Directions(
|
MainNavigationAction.Directions(
|
||||||
MainFragmentDirections.actionPickPlaybackGenre(song.uid)))
|
MainFragmentDirections.actionPickPlaybackGenre(song.uid)))
|
||||||
playbackModel.finishPlaybackGenrePicker()
|
playbackModel.genrePickerSong.consume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ class AlbumDetailFragment :
|
||||||
collectImmediately(detailModel.albumList, ::updateList)
|
collectImmediately(detailModel.albumList, ::updateList)
|
||||||
collectImmediately(
|
collectImmediately(
|
||||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||||
collect(navModel.exploreNavigationItem, ::handleNavigation)
|
collect(navModel.exploreNavigationItem.flow, ::handleNavigation)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ class AlbumDetailFragment :
|
||||||
if (unlikelyToBeNull(detailModel.currentAlbum.value) == item.album) {
|
if (unlikelyToBeNull(detailModel.currentAlbum.value) == item.album) {
|
||||||
logD("Navigating to a song in this album")
|
logD("Navigating to a song in this album")
|
||||||
scrollToAlbumSong(item)
|
scrollToAlbumSong(item)
|
||||||
navModel.finishExploreNavigation()
|
navModel.exploreNavigationItem.consume()
|
||||||
} else {
|
} else {
|
||||||
logD("Navigating to another album")
|
logD("Navigating to another album")
|
||||||
findNavController()
|
findNavController()
|
||||||
|
@ -219,7 +219,7 @@ class AlbumDetailFragment :
|
||||||
if (unlikelyToBeNull(detailModel.currentAlbum.value) == item) {
|
if (unlikelyToBeNull(detailModel.currentAlbum.value) == item) {
|
||||||
logD("Navigating to the top of this album")
|
logD("Navigating to the top of this album")
|
||||||
binding.detailRecycler.scrollToPosition(0)
|
binding.detailRecycler.scrollToPosition(0)
|
||||||
navModel.finishExploreNavigation()
|
navModel.exploreNavigationItem.consume()
|
||||||
} else {
|
} else {
|
||||||
logD("Navigating to another album")
|
logD("Navigating to another album")
|
||||||
findNavController()
|
findNavController()
|
||||||
|
|
|
@ -99,7 +99,7 @@ class ArtistDetailFragment :
|
||||||
collectImmediately(detailModel.artistList, ::updateList)
|
collectImmediately(detailModel.artistList, ::updateList)
|
||||||
collectImmediately(
|
collectImmediately(
|
||||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||||
collect(navModel.exploreNavigationItem, ::handleNavigation)
|
collect(navModel.exploreNavigationItem.flow, ::handleNavigation)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ class ArtistDetailFragment :
|
||||||
if (item.uid == detailModel.currentArtist.value?.uid) {
|
if (item.uid == detailModel.currentArtist.value?.uid) {
|
||||||
logD("Navigating to the top of this artist")
|
logD("Navigating to the top of this artist")
|
||||||
binding.detailRecycler.scrollToPosition(0)
|
binding.detailRecycler.scrollToPosition(0)
|
||||||
navModel.finishExploreNavigation()
|
navModel.exploreNavigationItem.consume()
|
||||||
} else {
|
} else {
|
||||||
logD("Navigating to another artist")
|
logD("Navigating to another artist")
|
||||||
findNavController()
|
findNavController()
|
||||||
|
|
|
@ -98,7 +98,7 @@ class GenreDetailFragment :
|
||||||
collectImmediately(detailModel.genreList, ::updateList)
|
collectImmediately(detailModel.genreList, ::updateList)
|
||||||
collectImmediately(
|
collectImmediately(
|
||||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||||
collect(navModel.exploreNavigationItem, ::handleNavigation)
|
collect(navModel.exploreNavigationItem.flow, ::handleNavigation)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ class GenreDetailFragment :
|
||||||
.navigate(GenreDetailFragmentDirections.actionShowArtist(item.uid))
|
.navigate(GenreDetailFragmentDirections.actionShowArtist(item.uid))
|
||||||
}
|
}
|
||||||
is Genre -> {
|
is Genre -> {
|
||||||
navModel.finishExploreNavigation()
|
navModel.exploreNavigationItem.consume()
|
||||||
}
|
}
|
||||||
null -> {}
|
null -> {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,11 +155,11 @@ class HomeFragment :
|
||||||
binding.homeFab.setOnClickListener { playbackModel.shuffleAll() }
|
binding.homeFab.setOnClickListener { playbackModel.shuffleAll() }
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
collect(homeModel.shouldRecreate.flow, ::handleRecreate)
|
collect(homeModel.recreateTabs.flow, ::handleRecreate)
|
||||||
collectImmediately(homeModel.currentTabMode, ::updateCurrentTab)
|
collectImmediately(homeModel.currentTabMode, ::updateCurrentTab)
|
||||||
collectImmediately(homeModel.songsList, homeModel.isFastScrolling, ::updateFab)
|
collectImmediately(homeModel.songsList, homeModel.isFastScrolling, ::updateFab)
|
||||||
collectImmediately(musicModel.indexerState, ::updateIndexerState)
|
collectImmediately(musicModel.indexerState, ::updateIndexerState)
|
||||||
collect(navModel.exploreNavigationItem, ::handleNavigation)
|
collect(navModel.exploreNavigationItem.flow, ::handleNavigation)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ class HomeFragment :
|
||||||
binding.homePager.currentItem = 0
|
binding.homePager.currentItem = 0
|
||||||
// Make sure tabs are set up to also follow the new ViewPager configuration.
|
// Make sure tabs are set up to also follow the new ViewPager configuration.
|
||||||
setupPager(binding)
|
setupPager(binding)
|
||||||
homeModel.shouldRecreate.consume()
|
homeModel.recreateTabs.consume()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateIndexerState(state: Indexer.State?) {
|
private fun updateIndexerState(state: Indexer.State?) {
|
||||||
|
|
|
@ -109,7 +109,7 @@ constructor(
|
||||||
* flag is true, all tabs (and their respective ViewPager2 fragments) will be re-created from
|
* flag is true, all tabs (and their respective ViewPager2 fragments) will be re-created from
|
||||||
* scratch.
|
* scratch.
|
||||||
*/
|
*/
|
||||||
val shouldRecreate: Event<Unit>
|
val recreateTabs: Event<Unit>
|
||||||
get() = _shouldRecreate
|
get() = _shouldRecreate
|
||||||
|
|
||||||
private val _isFastScrolling = MutableStateFlow(false)
|
private val _isFastScrolling = MutableStateFlow(false)
|
||||||
|
|
|
@ -31,6 +31,8 @@ import org.oxycblt.auxio.music.*
|
||||||
import org.oxycblt.auxio.playback.persist.PersistenceRepository
|
import org.oxycblt.auxio.playback.persist.PersistenceRepository
|
||||||
import org.oxycblt.auxio.playback.queue.Queue
|
import org.oxycblt.auxio.playback.queue.Queue
|
||||||
import org.oxycblt.auxio.playback.state.*
|
import org.oxycblt.auxio.playback.state.*
|
||||||
|
import org.oxycblt.auxio.util.Event
|
||||||
|
import org.oxycblt.auxio.util.MutableEvent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An [ViewModel] that provides a safe UI frontend for the current playback state.
|
* An [ViewModel] that provides a safe UI frontend for the current playback state.
|
||||||
|
@ -74,22 +76,22 @@ constructor(
|
||||||
val isShuffled: StateFlow<Boolean>
|
val isShuffled: StateFlow<Boolean>
|
||||||
get() = _isShuffled
|
get() = _isShuffled
|
||||||
|
|
||||||
private val _artistPlaybackPickerSong = MutableStateFlow<Song?>(null)
|
private val _artistPlaybackPickerSong = MutableEvent<Song>()
|
||||||
/**
|
/**
|
||||||
* Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing a
|
* Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing a
|
||||||
* [Song] from one of it's [Artist]s.
|
* [Song] from one of it's [Artist]s.
|
||||||
*
|
*
|
||||||
* @see playFromArtist
|
* @see playFromArtist
|
||||||
*/
|
*/
|
||||||
val artistPickerSong: StateFlow<Song?>
|
val artistPickerSong: Event<Song>
|
||||||
get() = _artistPlaybackPickerSong
|
get() = _artistPlaybackPickerSong
|
||||||
|
|
||||||
private val _genrePlaybackPickerSong = MutableStateFlow<Song?>(null)
|
private val _genrePlaybackPickerSong = MutableEvent<Song>()
|
||||||
/**
|
/**
|
||||||
* Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing a
|
* Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing a
|
||||||
* [Song] from one of it's [Genre]s.
|
* [Song] from one of it's [Genre]s.
|
||||||
*/
|
*/
|
||||||
val genrePickerSong: StateFlow<Song?>
|
val genrePickerSong: Event<Song>
|
||||||
get() = _genrePlaybackPickerSong
|
get() = _genrePlaybackPickerSong
|
||||||
|
|
||||||
/** The current action to show on the playback bar. */
|
/** The current action to show on the playback bar. */
|
||||||
|
@ -192,20 +194,10 @@ constructor(
|
||||||
} else if (song.artists.size == 1) {
|
} else if (song.artists.size == 1) {
|
||||||
playImpl(song, song.artists[0])
|
playImpl(song, song.artists[0])
|
||||||
} else {
|
} else {
|
||||||
_artistPlaybackPickerSong.value = song
|
_artistPlaybackPickerSong.put(song)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark the [Artist] playback choice process as complete. This should occur when the [Artist]
|
|
||||||
* choice dialog is opened after this flag is detected.
|
|
||||||
*
|
|
||||||
* @see playFromArtist
|
|
||||||
*/
|
|
||||||
fun finishPlaybackArtistPicker() {
|
|
||||||
_artistPlaybackPickerSong.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PLay a [Song] from one of it's [Genre]s.
|
* PLay a [Song] from one of it's [Genre]s.
|
||||||
*
|
*
|
||||||
|
@ -219,20 +211,10 @@ constructor(
|
||||||
} else if (song.genres.size == 1) {
|
} else if (song.genres.size == 1) {
|
||||||
playImpl(song, song.genres[0])
|
playImpl(song, song.genres[0])
|
||||||
} else {
|
} else {
|
||||||
_genrePlaybackPickerSong.value = song
|
_genrePlaybackPickerSong.put(song)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark the [Genre] playback choice process as complete. This should occur when the [Genre]
|
|
||||||
* choice dialog is opened after this flag is detected.
|
|
||||||
*
|
|
||||||
* @see playFromGenre
|
|
||||||
*/
|
|
||||||
fun finishPlaybackGenrePicker() {
|
|
||||||
_genrePlaybackPickerSong.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Play an [Album].
|
* Play an [Album].
|
||||||
*
|
*
|
||||||
|
|
|
@ -115,7 +115,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
||||||
collectImmediately(searchModel.searchResults, ::updateSearchResults)
|
collectImmediately(searchModel.searchResults, ::updateSearchResults)
|
||||||
collectImmediately(
|
collectImmediately(
|
||||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||||
collect(navModel.exploreNavigationItem, ::handleNavigation)
|
collect(navModel.exploreNavigationItem.flow, ::handleNavigation)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,38 +20,38 @@ package org.oxycblt.auxio.ui
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
|
import org.oxycblt.auxio.util.Event
|
||||||
|
import org.oxycblt.auxio.util.MutableEvent
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
/** A [ViewModel] that handles complicated navigation functionality. */
|
/** A [ViewModel] that handles complicated navigation functionality. */
|
||||||
class NavigationViewModel : ViewModel() {
|
class NavigationViewModel : ViewModel() {
|
||||||
private val _mainNavigationAction = MutableStateFlow<MainNavigationAction?>(null)
|
private val _mainNavigationAction = MutableEvent<MainNavigationAction>()
|
||||||
/**
|
/**
|
||||||
* Flag for navigation within the main navigation graph. Only intended for use by MainFragment.
|
* Flag for navigation within the main navigation graph. Only intended for use by MainFragment.
|
||||||
*/
|
*/
|
||||||
val mainNavigationAction: StateFlow<MainNavigationAction?>
|
val mainNavigationAction: Event<MainNavigationAction>
|
||||||
get() = _mainNavigationAction
|
get() = _mainNavigationAction
|
||||||
|
|
||||||
private val _exploreNavigationItem = MutableStateFlow<Music?>(null)
|
private val _exploreNavigationItem = MutableEvent<Music>()
|
||||||
/**
|
/**
|
||||||
* Flag for navigation within the explore navigation graph. Observe this to coordinate
|
* Flag for navigation within the explore navigation graph. Observe this to coordinate
|
||||||
* navigation to a specific [Music] item.
|
* navigation to a specific [Music] item.
|
||||||
*/
|
*/
|
||||||
val exploreNavigationItem: StateFlow<Music?>
|
val exploreNavigationItem: Event<Music>
|
||||||
get() = _exploreNavigationItem
|
get() = _exploreNavigationItem
|
||||||
|
|
||||||
private val _exploreArtistNavigationItem = MutableStateFlow<Music?>(null)
|
private val _exploreArtistNavigationItem = MutableEvent<Music>()
|
||||||
/**
|
/**
|
||||||
* Variation of [exploreNavigationItem] for situations where the choice of parent [Artist] to
|
* Variation of [exploreNavigationItem] for situations where the choice of parent [Artist] to
|
||||||
* navigate to is ambiguous. Only intended for use by MainFragment, as the resolved choice will
|
* navigate to is ambiguous. Only intended for use by MainFragment, as the resolved choice will
|
||||||
* eventually be assigned to [exploreNavigationItem].
|
* eventually be assigned to [exploreNavigationItem].
|
||||||
*/
|
*/
|
||||||
val exploreArtistNavigationItem: StateFlow<Music?>
|
val exploreArtistNavigationItem: Event<Music>
|
||||||
get() = _exploreArtistNavigationItem
|
get() = _exploreArtistNavigationItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,21 +62,12 @@ class NavigationViewModel : ViewModel() {
|
||||||
* @param action The [MainNavigationAction] to perform.
|
* @param action The [MainNavigationAction] to perform.
|
||||||
*/
|
*/
|
||||||
fun mainNavigateTo(action: MainNavigationAction) {
|
fun mainNavigateTo(action: MainNavigationAction) {
|
||||||
if (_mainNavigationAction.value != null) {
|
if (_mainNavigationAction.flow.value != null) {
|
||||||
logD("Already navigating, not doing main action")
|
logD("Already navigating, not doing main action")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logD("Navigating with action $action")
|
logD("Navigating with action $action")
|
||||||
_mainNavigationAction.value = action
|
_mainNavigationAction.put(action)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark that the navigation process within the main navigation graph (initiated by
|
|
||||||
* [mainNavigateTo]) was completed.
|
|
||||||
*/
|
|
||||||
fun finishMainNavigation() {
|
|
||||||
logD("Finishing main navigation process")
|
|
||||||
_mainNavigationAction.value = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,12 +76,12 @@ class NavigationViewModel : ViewModel() {
|
||||||
* @param music The [Music] to navigate to.
|
* @param music The [Music] to navigate to.
|
||||||
*/
|
*/
|
||||||
fun exploreNavigateTo(music: Music) {
|
fun exploreNavigateTo(music: Music) {
|
||||||
if (_exploreNavigationItem.value != null) {
|
if (_exploreNavigationItem.flow.value != null) {
|
||||||
logD("Already navigating, not doing explore action")
|
logD("Already navigating, not doing explore action")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logD("Navigating to ${music.rawName}")
|
logD("Navigating to ${music.rawName}")
|
||||||
_exploreNavigationItem.value = music
|
_exploreNavigationItem.put(music)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,7 +105,7 @@ class NavigationViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun exploreNavigateToParentArtistImpl(item: Music, artists: List<Artist>) {
|
private fun exploreNavigateToParentArtistImpl(item: Music, artists: List<Artist>) {
|
||||||
if (_exploreArtistNavigationItem.value != null) {
|
if (_exploreArtistNavigationItem.flow.value != null) {
|
||||||
logD("Already navigating, not doing explore action")
|
logD("Already navigating, not doing explore action")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -123,19 +114,9 @@ class NavigationViewModel : ViewModel() {
|
||||||
exploreNavigateTo(artists[0])
|
exploreNavigateTo(artists[0])
|
||||||
} else {
|
} else {
|
||||||
logD("Navigating to a choice of ${artists.map { it.rawName }}")
|
logD("Navigating to a choice of ${artists.map { it.rawName }}")
|
||||||
_exploreArtistNavigationItem.value = item
|
_exploreArtistNavigationItem.put(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark that the navigation process within the explore navigation graph (initiated by
|
|
||||||
* [exploreNavigateTo]) was completed.
|
|
||||||
*/
|
|
||||||
fun finishExploreNavigation() {
|
|
||||||
logD("Finishing explore navigation process")
|
|
||||||
_exploreNavigationItem.value = null
|
|
||||||
_exploreArtistNavigationItem.value = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,17 +28,40 @@ import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper around [StateFlow] exposing a one-time consumable event.
|
||||||
|
*
|
||||||
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
|
*/
|
||||||
interface Event<T> {
|
interface Event<T> {
|
||||||
|
/** The inner [StateFlow] contained by the [Event]. */
|
||||||
val flow: StateFlow<T?>
|
val flow: StateFlow<T?>
|
||||||
|
/**
|
||||||
|
* Consume whatever value is currently contained by this instance.
|
||||||
|
*
|
||||||
|
* @return A value placed into this instance prior, or null if there isn't any.
|
||||||
|
*/
|
||||||
fun consume(): T?
|
fun consume(): T?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper around [StateFlow] exposing a one-time consumable event that can be modified by it's
|
||||||
|
* owner.
|
||||||
|
*
|
||||||
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
|
*/
|
||||||
class MutableEvent<T> : Event<T> {
|
class MutableEvent<T> : Event<T> {
|
||||||
override val flow = MutableStateFlow<T?>(null)
|
override val flow = MutableStateFlow<T?>(null)
|
||||||
|
override fun consume() = flow.value?.also { flow.value = null }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place a new value into this instance, replacing any prior value.
|
||||||
|
*
|
||||||
|
* @param v The value to update with.
|
||||||
|
*/
|
||||||
fun put(v: T) {
|
fun put(v: T) {
|
||||||
flow.value = v
|
flow.value = v
|
||||||
}
|
}
|
||||||
override fun consume() = flow.value?.also { flow.value = null }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue