Browse Source

Add the progress and played views to the remote access video list

merge-requests/1990/head
Nicolas Pomepuy 3 years ago
committed by Duncan McNamara
parent
commit
8f392fc2e5
  1. 2
      application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
  2. 2
      application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt
  3. 58
      buildsystem/network-sharing-server/public/icons/played.svg
  4. 12
      buildsystem/network-sharing-server/src/components/MediaCardItem.vue
  5. 13
      buildsystem/network-sharing-server/src/components/MediaListItem.vue
  6. 48
      buildsystem/network-sharing-server/src/pages/VideoList.vue
  7. 2
      buildsystem/network-sharing-server/src/scss/app.scss

2
application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt

@ -900,4 +900,4 @@ fun Playlist.toPlayQueueItem(appContext: Context) = RemoteAccessServer.PlayQueue
fun MediaWrapper.toPlayQueueItem() = RemoteAccessServer.PlayQueueItem(id, title, artist
?: "", length, artworkMrl
?: "", false, generateResolutionClass(width, height) ?: "")
?: "", false, generateResolutionClass(width, height) ?: "", progress = time, played = seen > 0)

2
application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt

@ -724,7 +724,7 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
?: false) : WSMessage("now-playing")
data class PlayQueue(val medias: List<PlayQueueItem>) : WSMessage("play-queue")
data class PlayQueueItem(val id: Long, val title: String, val artist: String, val length: Long, val artworkURL: String, val playing: Boolean, val resolution: String = "", val path: String = "", val isFolder: Boolean = false)
data class PlayQueueItem(val id: Long, val title: String, val artist: String, val length: Long, val artworkURL: String, val playing: Boolean, val resolution: String = "", val path: String = "", val isFolder: Boolean = false, val progress: Long = 0L, val played:Boolean = false)
data class WebSocketAuthorization(val status:String, val initialMessage:String) : WSMessage("auth")
data class Volume(val volume: Int) : WSMessage("volume")
data class PlayerStatus(val playing: Boolean) : WSMessage("player-status")

58
buildsystem/network-sharing-server/public/icons/played.svg

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
- *************************************************************************
- played.svg
- **************************************************************************
- Copyright © 2023 VLC authors and VideoLAN
- Author: Nicolas POMEPUY
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- ***************************************************************************
-
-
-->
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#000000" version="1.1" id="svg6"
sodipodi:docname="played.svg" inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg">
<defs
id="defs10" />
<sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="36.375"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
d="M0 0h24v24H0V0z"
fill="none"
id="path2" />
<path
d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"
id="path4"
style="fill:#ffffff" />
</svg>

12
buildsystem/network-sharing-server/src/components/MediaCardItem.vue

@ -5,6 +5,12 @@
<img class="overlay-play" :src="(`./icons/play_circle_white.svg`)" width="48" />
</div>
<span v-if="(mediaType == 'video' && media.resolution != '')" class="resolution">{{ media.resolution }}</span>
<img class="played" :src="(`./icons/played.svg`)" v-show="(media.played)"/>
<div class="card-progress-container" v-show="(media.progress > 0)">
<div class="card-progress full"></div>
<div class="card-progress" v-bind:style="(getProgressStyle())"></div>
</div>
</div>
<div class="d-flex">
@ -45,6 +51,12 @@ export default {
if (this.isBrowse() || this.mediaType == "file") return 'ratio-1x1'
return 'ratio-1x1 audio-img-container'
},
getProgressStyle() {
if (this.mediaType == 'video' && this.media.progress > 0 && this.media.length > 0) {
return `width: ${this.media.progress * 100 / this.media.length}%`
}
return ''
},
isBrowse() {
return (this.mediaType == 'folder' || this.mediaType == 'network' || this.mediaType == 'stream' || this.mediaType == 'new-stream')
},

13
buildsystem/network-sharing-server/src/components/MediaListItem.vue

@ -5,7 +5,14 @@
<div class="media-overlay" v-show="!isBrowse()">
<img class="overlay-play" :src="(`./icons/play_circle_white.svg`)" width="24" />
</div>
<span v-if="(mediaType == 'video' && media.resolution != '')" class="resolution">{{ media.resolution }}</span>
<img class="played" :src="(`./icons/played.svg`)" v-show="(media.played)"/>
<div class="card-progress-container" v-show="(media.progress > 0)">
<div class="card-progress full"></div>
<div class="card-progress" v-bind:style="(getProgressStyle())"></div>
</div>
</div>
<div v-on:click="manageClick" class="card-body media-text flex1">
<h6 class="card-title text-truncate">{{ media.title }}</h6>
<p class="card-text text-truncate" v-if="getDescription().length > 0">{{ getDescription() }}</p>
@ -41,6 +48,12 @@ export default {
if (this.isBrowse() || this.mediaType == "file") return 'ratio-1x1'
return 'ratio-1x1 audio-img-container'
},
getProgressStyle() {
if (this.mediaType == 'video' && this.media.progress > 0 && this.media.length > 0) {
return `width: ${this.media.progress * 100 / this.media.length}%`
}
return ''
},
isBrowse() {
return (this.mediaType == 'folder' || this.mediaType == 'network' || this.mediaType == 'stream' || this.mediaType == 'new-stream')
},

48
buildsystem/network-sharing-server/src/pages/VideoList.vue

@ -66,13 +66,26 @@ export default {
return this.$t('NO_MEDIA')
}
},
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.fetchVideos();
this.appStore.needRefresh = false
}
})
},
created: function () {
this.fetchVideos();
}
}
</script>
<style>
<style lang="scss">
@import '../scss/colors.scss';
.ratio>.resolution {
position: absolute;
top: 8px;
@ -85,4 +98,37 @@ export default {
border-radius: 2px;
font-size: 0.6rem;
}
.ratio>.played {
position: absolute;
top: 8px;
right: 8px;
left: auto;
width: 24px;
height: 24px;
padding: 4px;
color: #fff;
background: rgba(0, 0, 0, 0.6);
border-radius: 2px;
font-size: 0.6rem;
}
.card-progress-container {
height: 14px;
position: absolute;
bottom: 0;
top: auto;
border-radius: 6px;
overflow: hidden;
}
.card-progress {
height: 4px;
background-color: $primary-color;
position: absolute;
bottom: 0;
}
.card-progress.full {
width: 100%;
background-color: $light-grey-transparent;
}
</style>

2
buildsystem/network-sharing-server/src/scss/app.scss

@ -272,7 +272,7 @@ body {
.audio-img-container {
background-color: $dark-background;
border-radius: 7px;
border-radius: 6px;
}
.dropdown-menu {

Loading…
Cancel
Save