ui: split off selection from home
Split off selection functionality from the home fragment to a new selection viewmodel. It's going to be used elsewhere, so may as well.
This commit is contained in:
parent
f1ae870eea
commit
761dab9239
14 changed files with 42 additions and 30 deletions
|
|
@ -59,7 +59,7 @@ abstract class DetailAdapter<L : DetailAdapter.Listener>(
|
|||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =
|
||||
throw IllegalStateException()
|
||||
throw NotImplementedError()
|
||||
|
||||
override fun onBindViewHolder(
|
||||
holder: RecyclerView.ViewHolder,
|
||||
|
|
|
|||
|
|
@ -60,10 +60,6 @@ class HomeViewModel(application: Application) :
|
|||
val genres: StateFlow<List<Genre>>
|
||||
get() = _genres
|
||||
|
||||
private val _selected = MutableStateFlow(listOf<Music>())
|
||||
val selected: StateFlow<List<Music>>
|
||||
get() = _selected
|
||||
|
||||
var tabs: List<MusicMode> = visibleTabs
|
||||
private set
|
||||
|
||||
|
|
@ -88,19 +84,6 @@ class HomeViewModel(application: Application) :
|
|||
musicStore.addCallback(this)
|
||||
}
|
||||
|
||||
/** Select a music item. */
|
||||
fun select(item: Music) {
|
||||
val items = _selected.value.toMutableList()
|
||||
if (items.remove(item)) {
|
||||
logD("Unselecting item $item")
|
||||
_selected.value = items
|
||||
} else {
|
||||
logD("Selecting item $item")
|
||||
items.add(item)
|
||||
_selected.value = items
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the current tab based off of the new ViewPager position. */
|
||||
fun updateCurrentTab(pos: Int) {
|
||||
logD("Updating current tab to ${tabs[pos]}")
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class AlbumListFragment : HomeListFragment<Album>() {
|
|||
}
|
||||
|
||||
collectImmediately(homeModel.albums, homeAdapter::replaceList)
|
||||
collectImmediately(homeModel.selected, homeAdapter::updateSelection)
|
||||
collectImmediately(selectionModel.selected, homeAdapter::updateSelection)
|
||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::handleParent)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class ArtistListFragment : HomeListFragment<Artist>() {
|
|||
}
|
||||
|
||||
collectImmediately(homeModel.artists, homeAdapter::replaceList)
|
||||
collectImmediately(homeModel.selected, homeAdapter::updateSelection)
|
||||
collectImmediately(selectionModel.selected, homeAdapter::updateSelection)
|
||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::handleParent)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class GenreListFragment : HomeListFragment<Genre>() {
|
|||
}
|
||||
|
||||
collectImmediately(homeModel.genres, homeAdapter::replaceList)
|
||||
collectImmediately(homeModel.selected, homeAdapter::updateSelection)
|
||||
collectImmediately(selectionModel.selected, homeAdapter::updateSelection)
|
||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::handlePlayback)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ package org.oxycblt.auxio.home.list
|
|||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
|
||||
import org.oxycblt.auxio.home.HomeViewModel
|
||||
import org.oxycblt.auxio.music.Music
|
||||
import org.oxycblt.auxio.ui.SelectionViewModel
|
||||
import org.oxycblt.auxio.ui.fastscroll.FastScrollRecyclerView
|
||||
import org.oxycblt.auxio.ui.fragment.MenuFragment
|
||||
import org.oxycblt.auxio.ui.recycler.Item
|
||||
|
|
@ -39,6 +41,7 @@ abstract class HomeListFragment<T : Item> :
|
|||
FastScrollRecyclerView.PopupProvider,
|
||||
FastScrollRecyclerView.OnFastScrollListener {
|
||||
protected val homeModel: HomeViewModel by androidActivityViewModels()
|
||||
protected val selectionModel: SelectionViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateBinding(inflater: LayoutInflater) =
|
||||
FragmentHomeListBinding.inflate(inflater)
|
||||
|
|
@ -69,7 +72,7 @@ abstract class HomeListFragment<T : Item> :
|
|||
|
||||
override fun onItemClick(item: Item) {
|
||||
check(item is Music) { "Unexpected datatype: ${item::class.java}" }
|
||||
if (homeModel.selected.value.isEmpty()) {
|
||||
if (selectionModel.selected.value.isEmpty()) {
|
||||
onItemClick(item)
|
||||
} else {
|
||||
onSelect(item)
|
||||
|
|
@ -78,6 +81,6 @@ abstract class HomeListFragment<T : Item> :
|
|||
|
||||
override fun onSelect(item: Item) {
|
||||
check(item is Music) { "Unexpected datatype: ${item::class.java}" }
|
||||
homeModel.select(item)
|
||||
selectionModel.select(item)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class SongListFragment : HomeListFragment<Song>() {
|
|||
}
|
||||
|
||||
collectImmediately(homeModel.songs, homeAdapter::replaceList)
|
||||
collectImmediately(homeModel.selected, homeAdapter::updateSelection)
|
||||
collectImmediately(selectionModel.selected, homeAdapter::updateSelection)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::handlePlayback)
|
||||
}
|
||||
|
|
|
|||
26
app/src/main/java/org/oxycblt/auxio/ui/SelectionViewModel.kt
Normal file
26
app/src/main/java/org/oxycblt/auxio/ui/SelectionViewModel.kt
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package org.oxycblt.auxio.ui
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.oxycblt.auxio.music.Music
|
||||
import org.oxycblt.auxio.util.logD
|
||||
|
||||
class SelectionViewModel : ViewModel() {
|
||||
private val _selected = MutableStateFlow(listOf<Music>())
|
||||
val selected: StateFlow<List<Music>>
|
||||
get() = _selected
|
||||
|
||||
/** Select a music item. */
|
||||
fun select(item: Music) {
|
||||
val items = _selected.value.toMutableList()
|
||||
if (items.remove(item)) {
|
||||
logD("Unselecting item $item")
|
||||
_selected.value = items
|
||||
} else {
|
||||
logD("Selecting item $item")
|
||||
items.add(item)
|
||||
_selected.value = items
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
style="@style/Widget.Auxio.Button.Secondary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/spacing_medium"
|
||||
android:layout_marginTop="@dimen/spacing_mid_medium"
|
||||
android:layout_marginEnd="@dimen/spacing_small"
|
||||
android:text="@string/lbl_play"
|
||||
app:layout_constraintEnd_toStartOf="@+id/detail_shuffle_button"
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@
|
|||
style="@style/Widget.Auxio.Button.Secondary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/spacing_medium"
|
||||
android:layout_marginTop="@dimen/spacing_mid_medium"
|
||||
android:layout_marginEnd="@dimen/spacing_small"
|
||||
android:text="@string/lbl_play"
|
||||
app:layout_constraintEnd_toStartOf="@+id/detail_shuffle_button"
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/spacing_medium"
|
||||
android:layout_marginTop="@dimen/spacing_medium"
|
||||
android:layout_marginTop="@dimen/spacing_mid_medium"
|
||||
android:layout_marginEnd="@dimen/spacing_small"
|
||||
android:text="@string/lbl_play"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/detail_cover"
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/spacing_medium"
|
||||
android:layout_marginTop="@dimen/spacing_medium"
|
||||
android:layout_marginTop="@dimen/spacing_mid_medium"
|
||||
android:layout_marginEnd="@dimen/spacing_small"
|
||||
android:text="@string/lbl_play"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/detail_cover"
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
style="@style/Widget.Auxio.Button.Secondary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/spacing_medium"
|
||||
android:layout_marginTop="@dimen/spacing_mid_medium"
|
||||
android:layout_marginEnd="@dimen/spacing_small"
|
||||
android:text="@string/lbl_play"
|
||||
app:layout_constraintEnd_toStartOf="@+id/detail_shuffle_button"
|
||||
|
|
|
|||
Loading…
Reference in a new issue