[Android] Fix the audio player UI when swiping an item while filtering

Nicolas Pomepuy git at videolan.org
Tue Mar 25 14:59:34 UTC 2025


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Thu Mar 20 11:49:35 2025 +0100| [67e6e2a341f327e42b82d2b1d7582e039f87b549] | committer: Duncan McNamara

Fix the audio player UI when swiping an item while filtering

Fixes #3174

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

 .../org/videolan/vlc/gui/audio/PlaylistAdapter.kt    |  5 +++--
 .../src/org/videolan/vlc/util/FilterDelegate.kt      |  6 +++---
 .../src/org/videolan/vlc/viewmodels/PlaylistModel.kt | 20 ++++++++++++++++++--
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/application/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt b/application/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt
index 20a9555d7b..7046e54b80 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt
@@ -206,13 +206,14 @@ class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<MediaWrappe
         model?.let {
             val media = getItem(position)
             val message = String.format(AppContextProvider.appResources.getString(R.string.remove_playlist_item), media.title)
+            val originalPosition = it.getOriginalPosition(position)
             if (player is Fragment) {
                 UiTools.snackerWithCancel(player.requireActivity(), message, overAudioPlayer = true, action = {}) {
-                    model?.run { insertMedia(it.getOriginalPosition(position), media) }
+                    model?.run { insertMedia(originalPosition, media) }
                 }
             } else if (player is Activity) {
                 UiTools.snackerWithCancel(player, message, action = {}) {
-                    model?.run { insertMedia(it.getOriginalPosition(position), media) }
+                    model?.run { insertMedia(originalPosition, media) }
                 }
             }
             remove(position)
diff --git a/application/vlc-android/src/org/videolan/vlc/util/FilterDelegate.kt b/application/vlc-android/src/org/videolan/vlc/util/FilterDelegate.kt
index 8d6774ec8e..8b173c9735 100644
--- a/application/vlc-android/src/org/videolan/vlc/util/FilterDelegate.kt
+++ b/application/vlc-android/src/org/videolan/vlc/util/FilterDelegate.kt
@@ -7,10 +7,10 @@ import org.videolan.medialibrary.interfaces.media.MediaWrapper
 import org.videolan.medialibrary.media.MediaLibraryItem
 import org.videolan.resources.AppContextProvider
 import org.videolan.vlc.media.MediaUtils
-import java.util.*
+import java.util.Locale
 
-open class FilterDelegate<T : MediaLibraryItem>(protected val dataset: MutableLiveData<out List<T>>) {
-    private var sourceSet: List<T>? = null
+open class FilterDelegate<T : MediaLibraryItem>(val dataset: MutableLiveData<out List<T>>) {
+    var sourceSet: List<T>? = null
 
     protected fun initSource() : List<T>? {
         if (sourceSet === null) sourceSet = (dataset.value)
diff --git a/application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt b/application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
index 218ffaeec8..799615bdd1 100644
--- a/application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
+++ b/application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
@@ -62,6 +62,7 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
     val playerState = MutableLiveData<PlayerState>()
     val connected : Boolean
         get() = service !== null
+    var lastQuery: CharSequence? = null
 
     private val filter by lazy(LazyThreadSafetyMode.NONE) { PlaylistFilterDelegate(dataset) }
 
@@ -85,7 +86,13 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
 
     override fun update() {
         service?.run {
-            dataset.value = media.toMutableList()
+            if (filtering) {
+                originalDataset = media.toMutableList()
+                filter.sourceSet = originalDataset
+                dataset.value = filter.dataset.value?.toMutableList() ?: media.toMutableList()
+                filterActor.trySend(lastQuery)
+            } else
+                dataset.value = media.toMutableList()
             playerState.value = PlayerState(isPlaying, title, artist)
         }
     }
@@ -93,7 +100,15 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
     val hasMedia
         get() = service?.hasMedia() ?: false
 
-    fun insertMedia(position: Int, media: MediaWrapper) = service?.insertItem(position, media)
+    fun insertMedia(position: Int, media: MediaWrapper) {
+        service?.insertItem(position, media)
+        if (filtering) {
+            service?.let {
+                originalDataset = it.media.toMutableList()
+                filter.sourceSet = originalDataset
+            }
+        }
+    }
 
     /**
      * Get original position even if current list is filtered
@@ -111,6 +126,7 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
 
     @MainThread
     fun filter(query: CharSequence?) {
+        lastQuery = query
         val filtering = query != null
         if (this.filtering != filtering) {
             this.filtering = filtering



More information about the Android mailing list