[Android] Refactor the PlaylistViewModel to listen to the item changes
Nicolas Pomepuy
git at videolan.org
Fri Nov 18 12:29:45 UTC 2022
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Thu Nov 3 11:04:19 2022 +0100| [1b3a45c365501b7fb1f20fbc2c3501cad0168f56] | committer: Nicolas Pomepuy
Refactor the PlaylistViewModel to listen to the item changes
> https://code.videolan.org/videolan/vlc-android/commit/1b3a45c365501b7fb1f20fbc2c3501cad0168f56
---
.../videolan/vlc/gui/HeaderMediaListActivity.kt | 59 ++++++++++++----------
.../vlc/viewmodels/mobile/PlaylistViewModel.kt | 33 ++++++++++--
2 files changed, 61 insertions(+), 31 deletions(-)
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt b/application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt
index 4fba33ae6b..8fd7970834 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt
@@ -123,14 +123,29 @@ open class HeaderMediaListActivity : AudioPlayerContainerActivity(), IEventsHand
if (::itemTouchHelperCallback.isInitialized) itemTouchHelperCallback.swipeEnabled = true
}
+ viewModel.playlistLiveData.observe(this) { playlist ->
+ (playlist as? Album)?.let {
+ binding.btnFavorite.setVisible()
+ binding.btnFavorite.setImageDrawable(ContextCompat.getDrawable(this, if (it.isFavorite) R.drawable.ic_header_media_favorite else R.drawable.ic_header_media_favorite_outline))
+ } ?: binding.btnFavorite.setGone()
+
+ var totalDuration = 0L
+ for (item in playlist.tracks)
+ totalDuration += item.length
+ binding.totalDuration = totalDuration
+
+ if (playlist is Album) {
+ val releaseYear = playlist.releaseYear
+ binding.releaseYear = if (releaseYear > 0) releaseYear.toString() else ""
+ if (releaseYear <= 0) binding.releaseDate.visibility = View.GONE
+ }
+ }
+
viewModel.tracksProvider.liveHeaders.observe(this) {
binding.songs.invalidateItemDecorations()
}
audioBrowserAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_MEDIA, this, this, isPlaylist)
- var totalDuration = 0L
- for (item in viewModel.playlist.tracks)
- totalDuration += item.length
- binding.totalDuration = totalDuration
+
if (isPlaylist) {
audioBrowserAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_MEDIA, this, this, isPlaylist)
itemTouchHelperCallback = SwipeDragItemTouchHelperCallback(audioBrowserAdapter)
@@ -140,25 +155,18 @@ open class HeaderMediaListActivity : AudioPlayerContainerActivity(), IEventsHand
} else {
audioBrowserAdapter = AudioAlbumTracksAdapter(MediaLibraryItem.TYPE_MEDIA, this, this)
binding.songs.addItemDecoration(RecyclerSectionItemDecoration(resources.getDimensionPixelSize(R.dimen.recycler_section_header_height), true, viewModel.tracksProvider))
- if (viewModel.playlist is Album) {
- val releaseYear = (viewModel.playlist as Album).releaseYear
- binding.releaseYear = if (releaseYear > 0) releaseYear.toString() else ""
- if (releaseYear <= 0) binding.releaseDate.visibility = View.GONE
- }
+
}
binding.btnShuffle.setOnClickListener {
- MediaUtils.playTracks(this, viewModel.playlist, SecureRandom().nextInt(min(playlist.tracksCount, MEDIALIBRARY_PAGE_SIZE)), true)
+ viewModel.playlist?.let { MediaUtils.playTracks(this, it, SecureRandom().nextInt(min(playlist.tracksCount, MEDIALIBRARY_PAGE_SIZE)), true) }
}
binding.btnAddPlaylist.setOnClickListener {
- addToPlaylist(viewModel.playlist.tracks.toList())
+ viewModel.playlist?.let { addToPlaylist(it.tracks.toList()) }
}
- updateFavoriteState()
-
binding.btnFavorite.setOnClickListener {
lifecycleScope.launch {
viewModel.toggleFavorite()
- updateFavoriteState()
}
}
@@ -200,20 +208,15 @@ open class HeaderMediaListActivity : AudioPlayerContainerActivity(), IEventsHand
binding.playBtn.setOnClickListener(this)
}
- private fun updateFavoriteState() {
- (viewModel.playlist as? Album)?.let {
- binding.btnFavorite.setVisible()
- binding.btnFavorite.setImageDrawable(ContextCompat.getDrawable(this, if (it.isFavorite) R.drawable.ic_header_media_favorite else R.drawable.ic_header_media_favorite_outline))
- } ?: binding.btnFavorite.setGone()
- }
-
override fun onStop() {
super.onStop()
stopActionMode()
}
public override fun onSaveInstanceState(outState: Bundle) {
- outState.putParcelable(AudioBrowserFragment.TAG_ITEM, viewModel.playlist)
+ viewModel.playlist?.let {
+ outState.putParcelable(AudioBrowserFragment.TAG_ITEM, it)
+ }
super.onSaveInstanceState(outState)
}
@@ -518,11 +521,13 @@ open class HeaderMediaListActivity : AudioPlayerContainerActivity(), IEventsHand
itemTouchHelperCallback.swipeEnabled = false
lifecycleScope.launchWhenStarted {
val tracks = withContext(Dispatchers.IO) { playlist.tracks }
- withContext(Dispatchers.IO) {
- for ((index, playlistIndex) in indexes.sortedBy { it }.withIndex()) {
- val trueIndex = viewModel.playlist.tracks.indexOf(list[index])
- itemsRemoved[trueIndex] = tracks[playlistIndex].id
- playlist.remove(trueIndex)
+ viewModel.playlist?.let { playlist ->
+ withContext(Dispatchers.IO) {
+ for ((index, playlistIndex) in indexes.sortedBy { it }.withIndex()) {
+ val trueIndex = playlist.tracks.indexOf(list[index])
+ itemsRemoved[trueIndex] = tracks[playlistIndex].id
+ (playlist as Playlist).remove(trueIndex)
+ }
}
}
var removedMessage = if (indexes.size>1) getString(R.string.removed_from_playlist_anonymous) else getString(R.string.remove_playlist_item,list.first().title)
diff --git a/application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/PlaylistViewModel.kt b/application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/PlaylistViewModel.kt
index 1d09431d7d..37eda77218 100644
--- a/application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/PlaylistViewModel.kt
+++ b/application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/PlaylistViewModel.kt
@@ -21,10 +21,12 @@
package org.videolan.vlc.viewmodels.mobile
import android.content.Context
+import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.videolan.medialibrary.interfaces.media.Album
import org.videolan.medialibrary.interfaces.media.MediaWrapper
@@ -35,13 +37,17 @@ import org.videolan.vlc.providers.medialibrary.MedialibraryProvider
import org.videolan.vlc.providers.medialibrary.TracksProvider
import org.videolan.vlc.viewmodels.MedialibraryViewModel
-class PlaylistViewModel(context: Context, val playlist: MediaLibraryItem) : MedialibraryViewModel(context) {
+class PlaylistViewModel(context: Context, private val initialPlaylist: MediaLibraryItem) : MedialibraryViewModel(context) {
- val tracksProvider = TracksProvider(playlist, context, this)
+ val tracksProvider = TracksProvider(initialPlaylist, context, this)
override val providers : Array<MedialibraryProvider<out MediaLibraryItem>> = arrayOf(tracksProvider)
+ var playlistLiveData: MutableLiveData<MediaLibraryItem> = MutableLiveData()
+
+ val playlist:MediaLibraryItem?
+ get() = playlistLiveData.value
init {
- when (playlist) {
+ when (initialPlaylist) {
is Playlist -> watchPlaylists()
is Album -> {
watchAlbums()
@@ -50,6 +56,25 @@ class PlaylistViewModel(context: Context, val playlist: MediaLibraryItem) : Medi
else -> watchMedia()
}
viewModelScope.registerCallBacks { refresh() }
+ viewModelScope.launch {
+ refreshPlaylistItem()
+ }
+ }
+
+ override fun refresh() {
+ viewModelScope.launch {
+ refreshPlaylistItem()
+ super.refresh()
+ }
+ }
+
+ private suspend fun refreshPlaylistItem() {
+ withContext(Dispatchers.IO) {
+ when (initialPlaylist) {
+ is Album -> playlistLiveData.postValue(medialibrary.getAlbum(initialPlaylist.id))
+ is Playlist -> playlistLiveData.postValue(medialibrary.getPlaylist(initialPlaylist.id, true))
+ }
+ }
}
class Factory(val context: Context, val playlist: MediaLibraryItem): ViewModelProvider.NewInstanceFactory() {
@@ -66,7 +91,7 @@ class PlaylistViewModel(context: Context, val playlist: MediaLibraryItem) : Medi
suspend fun toggleFavorite() = withContext(Dispatchers.IO){
when (playlist) {
- is Album -> playlist.setFavorite(!playlist.isFavorite)
+ is Album -> (playlist as Album).setFavorite(!(playlist as Album).isFavorite)
else ->{}
}
}
More information about the Android
mailing list