[Android] Force the MediaItemDetailsFragment to update when editing a network fav

Nicolas Pomepuy git at videolan.org
Wed Feb 9 14:56:39 UTC 2022


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Wed Feb  9 10:37:58 2022 +0100| [de70cde387c61046a91cd32e3d262ec666117054] | committer: Nicolas Pomepuy

Force the MediaItemDetailsFragment to update when editing a network fav

> https://code.videolan.org/videolan/vlc-android/commit/de70cde387c61046a91cd32e3d262ec666117054
---

 .../television/ui/MediaItemDetailsFragment.kt      | 49 +++++++++++++++++++---
 .../vlc/repository/BrowserFavRepository.kt         |  2 +-
 .../src/org/videolan/vlc/util/Browserutils.kt      | 13 ++++++
 3 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/application/television/src/main/java/org/videolan/television/ui/MediaItemDetailsFragment.kt b/application/television/src/main/java/org/videolan/television/ui/MediaItemDetailsFragment.kt
index c563da7f3..5e4aceb3c 100644
--- a/application/television/src/main/java/org/videolan/television/ui/MediaItemDetailsFragment.kt
+++ b/application/television/src/main/java/org/videolan/television/ui/MediaItemDetailsFragment.kt
@@ -21,10 +21,12 @@
 package org.videolan.television.ui
 
 import android.annotation.TargetApi
+import android.app.Application
 import android.content.Intent
 import android.os.Build
 import android.os.Bundle
 import android.os.Parcelable
+import android.util.Log
 import android.widget.Toast
 import androidx.core.content.ContextCompat
 import androidx.core.net.toUri
@@ -32,10 +34,13 @@ import androidx.fragment.app.activityViewModels
 import androidx.leanback.app.BackgroundManager
 import androidx.leanback.app.DetailsSupportFragment
 import androidx.leanback.widget.*
-import androidx.lifecycle.ViewModel
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.MediatorLiveData
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.lifecycleScope
 import kotlinx.coroutines.*
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.actor
 import org.videolan.libvlc.util.AndroidUtil
 import org.videolan.medialibrary.MLServiceLocator
 import org.videolan.medialibrary.interfaces.media.MediaWrapper
@@ -64,9 +69,7 @@ import org.videolan.vlc.gui.helpers.UiTools.addToPlaylist
 import org.videolan.vlc.gui.video.VideoPlayerActivity
 import org.videolan.vlc.media.MediaUtils
 import org.videolan.vlc.repository.BrowserFavRepository
-import org.videolan.vlc.util.FileUtils
-import org.videolan.vlc.util.getScreenWidth
-import org.videolan.vlc.util.isSchemeNetwork
+import org.videolan.vlc.util.*
 
 private const val TAG = "MediaItemDetailsFragment"
 private const val ID_PLAY = 1
@@ -149,6 +152,14 @@ class MediaItemDetailsFragment : DetailsSupportFragment(), CoroutineScope by Mai
             updateMetadata(it)
         }
 
+        viewModel.browserFavUpdated.observe(this) { newMedia ->
+            val intent = Intent(requireActivity(), DetailsActivity::class.java)
+            intent.putExtra(org.videolan.television.ui.EXTRA_MEDIA, newMedia)
+            intent.putExtra(EXTRA_ITEM, MediaItemDetails(newMedia.title, newMedia.artist, newMedia.album, newMedia.location, newMedia.artworkURL))
+            startActivity(intent)
+            requireActivity().finish()
+        }
+
         mediaMetadataModel.nextEpisode.observe(this) {
             if (it != null) {
                 actionsAdapter.set(ID_NEXT_EPISODE, Action(ID_NEXT_EPISODE.toLong(), getString(R.string.next_episode)))
@@ -349,6 +360,7 @@ class MediaItemDetailsFragment : DetailsSupportFragment(), CoroutineScope by Mai
                     Toast.makeText(activity, R.string.favorite_added, Toast.LENGTH_SHORT).show()
                 }
                 ID_FAVORITE_EDIT -> {
+                    viewModel.listenForNetworkFav = true
                     requireActivity().startActivity(Intent(activity, DialogActivity::class.java).setAction(DialogActivity.KEY_SERVER).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).apply {
                         putExtra(EXTRA_MEDIA, viewModel.media)
                     })
@@ -437,10 +449,37 @@ class MediaItemDetailsFragment : DetailsSupportFragment(), CoroutineScope by Mai
     }
 }
 
-class MediaItemDetailsModel : ViewModel() {
+class MediaItemDetailsModel(context: Application) : AndroidViewModel(context), CoroutineScope by MainScope() {
     lateinit var mediaItemDetails: MediaItemDetails
     lateinit var media: MediaWrapper
     var mediaStarted = false
+    private val repository = BrowserFavRepository.getInstance(context)
+    // Triggered when the current BrowserFav is updated to be able to relaunch the whole activity
+    val browserFavUpdated: MediatorLiveData<MediaWrapper> = MediatorLiveData()
+    private val oldList = ArrayList<MediaWrapper>()
+    var listenForNetworkFav = false
+    private val updateActor = actor<MediaWrapper>(capacity = Channel.CONFLATED) {
+        for (entry in channel) {
+            browserFavUpdated.value = entry
+        }
+    }
+
+    init {
+        browserFavUpdated.addSource(repository.networkFavs) { favList ->
+            val convertFavorites = convertFavorites(favList)
+            if (oldList.isEmpty()) oldList.addAll(convertFavorites)
+            if (listenForNetworkFav)
+                convertFavorites.forEach { media ->
+                    if (oldList.none { it.uri == media.uri && it.title == media.title }) {
+                        oldList.clear()
+                        oldList.addAll(convertFavorites)
+                        // we convert this new entry to a [MediaWrapper] and re-launch the activity with this new item
+                        listenForNetworkFav = false
+                       updateActor.offer(media)
+                    }
+                }
+        }
+    }
 }
 
 class VideoDetailsOverviewRow(val item: MediaMetadata) : DetailsOverviewRow(item)
diff --git a/application/vlc-android/src/org/videolan/vlc/repository/BrowserFavRepository.kt b/application/vlc-android/src/org/videolan/vlc/repository/BrowserFavRepository.kt
index 827a32d00..4f5ba67c7 100644
--- a/application/vlc-android/src/org/videolan/vlc/repository/BrowserFavRepository.kt
+++ b/application/vlc-android/src/org/videolan/vlc/repository/BrowserFavRepository.kt
@@ -44,7 +44,7 @@ class BrowserFavRepository(private val browserFavDao: BrowserFavDao) {
 
     private val networkMonitor = NetworkMonitor.getInstance(AppContextProvider.appContext)
 
-    private val networkFavs by lazy { browserFavDao.getAllNetwrokFavs() }
+    val networkFavs by lazy { browserFavDao.getAllNetwrokFavs() }
 
     val browserFavorites by lazy { browserFavDao.getAll() }
 
diff --git a/application/vlc-android/src/org/videolan/vlc/util/Browserutils.kt b/application/vlc-android/src/org/videolan/vlc/util/Browserutils.kt
index 9bc64f44d..34e03c4d4 100644
--- a/application/vlc-android/src/org/videolan/vlc/util/Browserutils.kt
+++ b/application/vlc-android/src/org/videolan/vlc/util/Browserutils.kt
@@ -63,3 +63,16 @@ fun convertFavorites(browserFavs: List<BrowserFav>?) = browserFavs?.filter {
         setStateFlags(MediaLibraryItem.FLAG_FAVORITE)
     }
 } ?: emptyList()
+
+/**
+ * Converts a [BrowserFav] to a [MediaWrapper]
+ * @return a [MediaWrapper]
+ */
+fun convertFavorite(browserFav: BrowserFav): MediaWrapper? {
+    return  MLServiceLocator.getAbstractMediaWrapper(browserFav.uri).apply {
+        setDisplayTitle(Uri.decode(browserFav.title))
+        type = MediaWrapper.TYPE_DIR
+        browserFav.iconUrl?.let { artworkURL = Uri.decode(it) }
+        setStateFlags(MediaLibraryItem.FLAG_FAVORITE)
+    }
+}



More information about the Android mailing list