[Android] Add a play all icon icon in the remote access groups / folders
Nicolas Pomepuy
git at videolan.org
Thu Feb 22 13:29:25 UTC 2024
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Tue Jan 30 14:25:52 2024 +0100| [8baa1d4d533ffbf85e97c0208dcddc4901247a69] | committer: Nicolas Pomepuy
Add a play all icon icon in the remote access groups / folders
> https://code.videolan.org/videolan/vlc-android/commit/8baa1d4d533ffbf85e97c0208dcddc4901247a69
---
.../videolan/vlc/webserver/RemoteAccessRouting.kt | 38 ++++++++++++++++++++++
.../videolan/vlc/webserver/TranslationMapping.kt | 1 +
buildsystem/network-sharing-server/src/App.vue | 4 +--
.../src/components/AppHeader.vue | 5 +++
.../network-sharing-server/src/plugins/api.js | 12 +++++++
.../network-sharing-server/src/plugins/vlcUtils.js | 11 +++++++
buildsystem/network-sharing-server/src/routes.js | 6 ++--
7 files changed, 72 insertions(+), 5 deletions(-)
diff --git a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
index 0186095ed7..431d4ec7a7 100644
--- a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
+++ b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
@@ -707,6 +707,44 @@ fun Route.setupRouting(appContext: Context, scope: CoroutineScope) {
}
call.respond(HttpStatusCode.NotFound)
}
+ // Play a media
+ get("/play-all") {
+ val type = call.request.queryParameters["type"]
+ val id = call.request.queryParameters["id"]
+ type?.let { type ->
+
+ val medias = appContext.getFromMl {
+ when (type) {
+ "video-group" -> {
+ id?.let { id ->
+ val group = getVideoGroup(id.toLong())
+ group.media(Medialibrary.SORT_DEFAULT, false, false, false, group.mediaCount(), 0)
+ }
+ }
+ "video-folder" -> {
+ id?.let { id ->
+ val folder = getFolder(Folder.TYPE_FOLDER_VIDEO, id.toLong())
+ folder.media(Folder.TYPE_FOLDER_VIDEO, Medialibrary.SORT_DEFAULT, false, false, false, folder.mediaCount(Folder.TYPE_FOLDER_VIDEO), 0)
+ }
+ }
+ else -> getAudio(Medialibrary.SORT_DEFAULT, false, false, false)
+ }
+ }
+ if (medias.isNullOrEmpty()) call.respond(HttpStatusCode.NotFound)
+ else {
+ if (medias.size == 1 && medias[0].id == RemoteAccessServer.getInstance(appContext).service?.currentMediaWrapper?.id) {
+ call.respond(HttpStatusCode.OK)
+ return at get
+ }
+ if (medias[0].type == MediaWrapper.TYPE_VIDEO && !appContext.awaitAppIsForegroung()) {
+ call.respond(HttpStatusCode.Forbidden, appContext.getString(R.string.ra_not_in_foreground))
+ }
+ MediaUtils.openList(appContext, medias.toList(), 0)
+ call.respond(HttpStatusCode.OK)
+ }
+ }
+ call.respond(HttpStatusCode.NotFound)
+ }
// Download a media file
get("/prepare-download") {
val type = call.request.queryParameters["type"] ?: "media"
diff --git a/application/webserver/src/main/java/org/videolan/vlc/webserver/TranslationMapping.kt b/application/webserver/src/main/java/org/videolan/vlc/webserver/TranslationMapping.kt
index 3e9edecac0..ed0ae6a5ec 100644
--- a/application/webserver/src/main/java/org/videolan/vlc/webserver/TranslationMapping.kt
+++ b/application/webserver/src/main/java/org/videolan/vlc/webserver/TranslationMapping.kt
@@ -91,5 +91,6 @@ object TranslationMapping {
VIDEO_GROUP_NONE(R.string.video_min_group_length_disable),
VIDEO_GROUP_BY_FOLDER(R.string.video_min_group_length_folder),
VIDEO_GROUP_BY_NAME(R.string.video_min_group_length_name),
+ PLAY_ALL(R.string.play_all),
}
}
\ No newline at end of file
diff --git a/buildsystem/network-sharing-server/src/App.vue b/buildsystem/network-sharing-server/src/App.vue
index 9527915b6a..9a956dc2de 100644
--- a/buildsystem/network-sharing-server/src/App.vue
+++ b/buildsystem/network-sharing-server/src/App.vue
@@ -127,8 +127,8 @@ export default {
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
+ this.$log.info("ML refresh needed")
+ this.appStore.needRefresh = true
break;
}
}
diff --git a/buildsystem/network-sharing-server/src/components/AppHeader.vue b/buildsystem/network-sharing-server/src/components/AppHeader.vue
index 01b00dad8d..c2c437562b 100644
--- a/buildsystem/network-sharing-server/src/components/AppHeader.vue
+++ b/buildsystem/network-sharing-server/src/components/AppHeader.vue
@@ -115,6 +115,11 @@
</div>
<div class="flex1 d-flex justify-content-end align-items-center">
+ <button class="btn btn-lg image-button" v-show="this.$route.meta.showFAB"
+ v-on:click.stop="$playAll(this.$route)" data-bs-toggle="tooltip" data-bs-placement="bottom"
+ :title="$t('PLAY_ALL')">
+ <img class="image-button-image" v-bind:src="$getAppAsset('ic_ctx_play_all', 24)">
+ </button>
<button class="btn btn-lg image-button" v-show="this.$route.meta.showResume"
v-on:click.stop="$resumePlayback(this.$route.meta.isAudio)" data-bs-toggle="tooltip" data-bs-placement="bottom"
:title="$t('RESUME_PLAYBACK')">
diff --git a/buildsystem/network-sharing-server/src/plugins/api.js b/buildsystem/network-sharing-server/src/plugins/api.js
index 06ab06876d..e851d5e222 100644
--- a/buildsystem/network-sharing-server/src/plugins/api.js
+++ b/buildsystem/network-sharing-server/src/plugins/api.js
@@ -181,6 +181,18 @@ export const vlcApi = {
if (mediaType) params.type = mediaType
return `${API_URL}play?${new URLSearchParams(params).toString()}`
},
+ /**
+ * Retrieve the media play API URL
+ * @param {String} type the media container type (video-group, video-folder, ...)
+ * @param {String} id the media container id
+ * @returns the URL
+ */
+ playAll: (type, id) => {
+ const params = {}
+ if (type) params.type = type
+ if (id) params.id = id
+ return `${API_URL}play-all?${new URLSearchParams(params).toString()}`
+ },
/**
* Retrieve the resume playback API URL
* @param {Boolean} isAudio
diff --git a/buildsystem/network-sharing-server/src/plugins/vlcUtils.js b/buildsystem/network-sharing-server/src/plugins/vlcUtils.js
index df5c888596..a4e3d947b4 100644
--- a/buildsystem/network-sharing-server/src/plugins/vlcUtils.js
+++ b/buildsystem/network-sharing-server/src/plugins/vlcUtils.js
@@ -46,6 +46,17 @@ export default {
appStore.warning = { type: "warning", message: error.response.data }
}
})
+ },
+ app.config.globalProperties.$playAll = (route) => {
+ let type= route.meta.playAllType
+ let id = (type == "video-group") ? route.params.groupId : (type == "video-folder") ? route.params.folderId : 0
+ console.log(`Play all: ${type} with id: ${id}`)
+ axios.get(vlcApi.playAll(type, id))
+ .catch(function (error) {
+ if (error.response.status != 200) {
+ appStore.warning = { type: "warning", message: error.response.data }
+ }
+ })
}
app.config.globalProperties.$resumePlayback = (isAudio) => {
axios.get(vlcApi.resumePlayback(isAudio)).then((response) => {
diff --git a/buildsystem/network-sharing-server/src/routes.js b/buildsystem/network-sharing-server/src/routes.js
index 724b0559d6..94372a284c 100644
--- a/buildsystem/network-sharing-server/src/routes.js
+++ b/buildsystem/network-sharing-server/src/routes.js
@@ -17,8 +17,8 @@ const routes = [
path: '/videos',
children: [
{ path: '', component: VideoList, name: 'VideoList', meta: { showDisplayBar: true, showResume: true, showGrouping: true } },
- { path: 'group/:groupId', component: VideoList, name: 'VideoGroupList', meta: { showDisplayBar: true } },
- { path: 'folder/:folderId', component: VideoList, name: 'VideoFolderList', meta: { showDisplayBar: true } },
+ { path: 'group/:groupId', component: VideoList, name: 'VideoGroupList', meta: { showDisplayBar: true, showFAB: true, playAllType: "video-group" } },
+ { path: 'folder/:folderId', component: VideoList, name: 'VideoFolderList', meta: { showDisplayBar: true, showFAB: true, playAllType: "video-folder" } },
]
},
{
@@ -26,7 +26,7 @@ const routes = [
children: [
{ path: 'artists', component: AudioArtists, name: 'AudioArtists', meta: { showDisplayBar: true, isAudio: true, showResume: true, showGrouping: false } },
{ path: 'albums', component: AudioAlbums, name: 'AudioAlbums', meta: { showDisplayBar: true, isAudio: true, showResume: true, showGrouping: false } },
- { path: 'tracks', component: AudioTracks, name: 'AudioTracks', meta: { showDisplayBar: true, isAudio: true, showResume: true, showGrouping: false } },
+ { path: 'tracks', component: AudioTracks, name: 'AudioTracks', meta: { showDisplayBar: true, isAudio: true, showResume: true, showGrouping: false, showFAB: true, playAllType: "tracks" } },
{ path: 'genres', component: AudioGenres, name: 'AudioGenres', meta: { showDisplayBar: true, isAudio: true, showResume: true, showGrouping: false } },
]
},
More information about the Android
mailing list