[Android] Refresh stream list when a media is modified

Nicolas Pomepuy git at videolan.org
Wed Jan 24 13:35:27 UTC 2024


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Tue Dec 12 07:32:59 2023 +0100| [fd69b284eebff18e6e8e9f5884528f0ec5c566c6] | committer: Duncan McNamara

Refresh stream list when a media is modified

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

 .../videolan/vlc/webserver/RemoteAccessServer.kt    | 19 +++++++++++++++++--
 buildsystem/network-sharing-server/src/App.vue      |  4 ++++
 .../network-sharing-server/src/pages/BrowseList.vue | 21 ++++++++++++++++++---
 .../network-sharing-server/src/stores/AppStore.js   |  1 +
 4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt
index a825481dd2..753400de55 100644
--- a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt
+++ b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt
@@ -102,6 +102,8 @@ import org.videolan.vlc.media.PlaylistManager
 import org.videolan.vlc.providers.NetworkProvider
 import org.videolan.vlc.util.FileUtils
 import org.videolan.vlc.util.isSchemeSMB
+import org.videolan.vlc.viewmodels.CallBackDelegate
+import org.videolan.vlc.viewmodels.ICallBackHandler
 import org.videolan.vlc.viewmodels.browser.IPathOperationDelegate
 import org.videolan.vlc.viewmodels.browser.PathOperationDelegate
 import org.videolan.vlc.webserver.ssl.SecretGenerator
@@ -127,7 +129,7 @@ import java.util.Locale
 private const val TAG = "HttpSharingServer"
 private const val NOW_PLAYING_TIMEOUT = 500
 
-class RemoteAccessServer(private val context: Context) : PlaybackService.Callback, IPathOperationDelegate by PathOperationDelegate() {
+class RemoteAccessServer(private val context: Context) : PlaybackService.Callback, IPathOperationDelegate by PathOperationDelegate(), ICallBackHandler by CallBackDelegate()  {
     private var lastNowPlayingSendTime: Long = 0L
     private var lastWasPlaying: Boolean = false
     private var settings: SharedPreferences
@@ -177,7 +179,10 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
         Security.addProvider(BouncyCastleProvider())
         copyWebServer()
         PlaybackService.serviceFlow.onEach { onServiceChanged(it) }
-                .onCompletion { service?.removeCallback(this at RemoteAccessServer) }
+                .onCompletion {
+                    service?.removeCallback(this at RemoteAccessServer)
+                    releaseCallbacks()
+                }
                 .launchIn(AppScope)
         _serverStatus.postValue(ServerStatus.STOPPED)
         settings = Settings.getInstance(context)
@@ -501,6 +506,12 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
                 }
                 _serverStatus.postValue(ServerStatus.STOPPED)
             }
+            watchMedia()
+            scope.registerCallBacks {
+                scope.launch {
+                    RemoteAccessWebSockets.sendToAll(Gson().toJson(MLRefreshNeeded()))
+                }
+            }
         }
     }
 
@@ -529,6 +540,9 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
      */
     override fun onMediaEvent(event: IMedia.Event) {
         if (BuildConfig.DEBUG) Log.d(TAG, "Send now playing from onMediaEvent")
+        if (event.type == IMedia.Event.ParsedChanged) {
+            AppScope.launch {  RemoteAccessWebSockets.sendToAll(Gson().toJson(MLRefreshNeeded())) }
+        }
         if (System.currentTimeMillis() - lastNowPlayingSendTime < NOW_PLAYING_TIMEOUT) return
         lastNowPlayingSendTime = System.currentTimeMillis()
         generateNowPlaying()?.let { nowPlaying ->
@@ -729,6 +743,7 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
     data class Volume(val volume: Int) : WSMessage("volume")
     data class PlayerStatus(val playing: Boolean) : WSMessage("player-status")
     data class LoginNeeded(val dialogOpened: Boolean) : WSMessage("login-needed")
+    data class MLRefreshNeeded(val refreshNeeded: Boolean = true) : WSMessage("ml-refresh-needed")
     data class PlaybackControlForbidden(val forbidden: Boolean = true): WSMessage("playback-control-forbidden")
     data class SearchResults(val albums: List<PlayQueueItem>, val artists: List<PlayQueueItem>, val genres: List<PlayQueueItem>, val playlists: List<PlayQueueItem>, val videos: List<PlayQueueItem>, val tracks: List<PlayQueueItem>)
     data class BreadcrumbItem(val title: String, val path: String)
diff --git a/buildsystem/network-sharing-server/src/App.vue b/buildsystem/network-sharing-server/src/App.vue
index c378e33894..9527915b6a 100644
--- a/buildsystem/network-sharing-server/src/App.vue
+++ b/buildsystem/network-sharing-server/src/App.vue
@@ -126,6 +126,10 @@ export default {
           case 'playback-control-forbidden':
             this.appStore.warning = { type: "warning", message: this.$t('PLAYBACK_CONTROL_FORBIDDEN') }
             break;
+          case 'ml-refresh-needed':
+          this.$log.info("ML refresh needed")
+          this.appStore.needRefresh = true
+            break;
         }
       }
 
diff --git a/buildsystem/network-sharing-server/src/pages/BrowseList.vue b/buildsystem/network-sharing-server/src/pages/BrowseList.vue
index fc1783da5b..b93543772d 100644
--- a/buildsystem/network-sharing-server/src/pages/BrowseList.vue
+++ b/buildsystem/network-sharing-server/src/pages/BrowseList.vue
@@ -1,5 +1,5 @@
 <template>
-    <div class="container">
+    <div class="container" @ml-refresh-needed="fetchStreams">
         <h5 class="media-content text-primary">Streams</h5>
         <div v-if="!favoritesLoaded" class="spinner-border text-primary mt-3" role="status">
             <span class="visually-hidden">Loading...</span>
@@ -107,7 +107,7 @@ import EmptyView from '../components/EmptyView.vue'
 
 export default {
     computed: {
-        ...mapStores(useAppStore)
+        ...mapStores(useAppStore, ['needRefresh'])
     },
     components: {
         MediaCardItem,
@@ -139,6 +139,11 @@ export default {
             }
         }
     },
+    watch: {
+        needRefresh() {
+            this.fetchStreams()
+        },
+    },
     methods: {
         fetchStreams() {
             let component = this
@@ -218,7 +223,17 @@ export default {
         this.fetchFavorites();
         this.fetchStorages();
         this.fetchNetwork();
-    }
+    },
+    mounted: function () {
+        this.appStore.$subscribe((mutation, state) => {
+            console.log(`Something changed in the app store: ${mutation} -> ${state}`)
+            if (mutation.events.key == "needRefresh" && mutation.events.newValue === true) {
+                this.fetchStreams();
+                this.appStore.needRefresh = false
+            }
+        })
+
+    },
 }
 </script>
 
diff --git a/buildsystem/network-sharing-server/src/stores/AppStore.js b/buildsystem/network-sharing-server/src/stores/AppStore.js
index 4db9704629..aed6acb9d3 100644
--- a/buildsystem/network-sharing-server/src/stores/AppStore.js
+++ b/buildsystem/network-sharing-server/src/stores/AppStore.js
@@ -14,6 +14,7 @@ export const useAppStore = defineStore('app', {
     warning: Object,
     socketOpened: true,
     showAddStream: false,
+    needRefresh: false
   }),
   getters: {
   },



More information about the Android mailing list