mirror of
https://github.com/owntone/owntone-server.git
synced 2025-11-10 22:10:15 -05:00
[web] Improve user interaction with sliders for output volume and music progress bar #1620
The sliders for output volume and the music slider have been optimised and simplified (one library less) to ensure easier user interaction.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<section class="section">
|
||||
<section class="section fd-page">
|
||||
<div class="container">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-four-fifths has-text-centered-mobile">
|
||||
|
||||
@@ -1,69 +1,54 @@
|
||||
<template>
|
||||
<section>
|
||||
<div v-if="now_playing.id > 0" class="fd-is-fullheight">
|
||||
<cover-artwork
|
||||
:artwork_url="now_playing.artwork_url"
|
||||
:artist="now_playing.artist"
|
||||
:album="now_playing.album"
|
||||
class="is-clickable fd-has-shadow fd-is-expanded fd-cover fd-cover-big-image"
|
||||
@click="open_dialog(now_playing)"
|
||||
/>
|
||||
<div class="fd-has-padding-left-right">
|
||||
<div class="container has-text-centered">
|
||||
<p class="control has-text-centered fd-progress-now-playing">
|
||||
<slider
|
||||
ref="slider"
|
||||
v-model="item_progress_ms"
|
||||
:min="0"
|
||||
:max="state.item_length_ms"
|
||||
:step="1000"
|
||||
:tooltips="false"
|
||||
:disabled="state.state === 'stop'"
|
||||
:classes="{ target: 'seek-slider' }"
|
||||
@change="seek"
|
||||
@start="start_dragging"
|
||||
@end="end_dragging"
|
||||
/>
|
||||
</p>
|
||||
<p class="content">
|
||||
<span
|
||||
v-text="
|
||||
[
|
||||
$filters.durationInHours(item_progress_ms),
|
||||
$filters.durationInHours(now_playing.length_ms)
|
||||
].join(' / ')
|
||||
"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fd-has-padding-left-right">
|
||||
<div class="container has-text-centered fd-has-margin-top">
|
||||
<h1 class="title is-5" v-text="now_playing.title" />
|
||||
<h2 class="title is-6" v-text="now_playing.artist" />
|
||||
<h2
|
||||
v-if="composer"
|
||||
class="subtitle is-6 has-text-grey has-text-weight-bold"
|
||||
v-text="composer"
|
||||
<div class="hero is-fullheight">
|
||||
<div v-if="track.id > 0" class="hero-body">
|
||||
<div class="container has-text-centered" style="max-width: 500px">
|
||||
<cover-artwork
|
||||
:artwork_url="track.artwork_url"
|
||||
:artist="track.artist"
|
||||
:album="track.album"
|
||||
class="is-clickable fd-has-shadow fd-cover-big-image"
|
||||
@click="open_dialog(track)"
|
||||
/>
|
||||
<input
|
||||
v-model.number="item_progress_ms"
|
||||
:step="1000"
|
||||
:max="is_live ? 1000 : track.length_ms"
|
||||
type="range"
|
||||
class="slider mt-5"
|
||||
:style="{ '--ratio': progress }"
|
||||
@change="seek"
|
||||
@touchstart="start_dragging"
|
||||
@touchend="end_dragging"
|
||||
/>
|
||||
<div class="is-flex is-justify-content-space-between">
|
||||
<p
|
||||
class="subtitle is-7"
|
||||
v-text="$filters.durationInHours(item_progress_ms)"
|
||||
/>
|
||||
<h3 class="subtitle is-6" v-text="now_playing.album" />
|
||||
<h3
|
||||
v-if="filepath"
|
||||
class="subtitle is-6 has-text-grey"
|
||||
v-text="filepath"
|
||||
<p
|
||||
class="subtitle is-7"
|
||||
v-text="$filters.durationInHours(track.length_ms)"
|
||||
/>
|
||||
</div>
|
||||
<h1 class="title is-5" v-text="track.title" />
|
||||
<h2 class="title is-6" v-text="track.artist" />
|
||||
<h2
|
||||
v-if="composer"
|
||||
class="subtitle is-6 has-text-grey has-text-weight-bold"
|
||||
v-text="composer"
|
||||
/>
|
||||
<h3 class="subtitle is-6" v-text="track.album" />
|
||||
<h3
|
||||
v-if="filepath"
|
||||
class="subtitle is-6 has-text-grey"
|
||||
v-text="filepath"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="fd-is-fullheight">
|
||||
<div
|
||||
class="fd-is-expanded fd-has-padding-left-right"
|
||||
style="flex-direction: column"
|
||||
>
|
||||
<div class="content has-text-centered">
|
||||
<h1 class="title is-5" v-text="$t('page.now-playing.title')" />
|
||||
<p v-text="$t('page.now-playing.info')" />
|
||||
</div>
|
||||
<div v-else class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<p class="title is-5" v-text="$t('page.now-playing.title')" />
|
||||
<p class="subtitle" v-text="$t('page.now-playing.info')" />
|
||||
</div>
|
||||
</div>
|
||||
<modal-dialog-queue-item
|
||||
@@ -71,12 +56,11 @@
|
||||
:item="selected_item"
|
||||
@close="show_details_modal = false"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ModalDialogQueueItem from '@/components/ModalDialogQueueItem.vue'
|
||||
import Slider from '@vueform/slider'
|
||||
import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||
import webapi from '@/webapi'
|
||||
import * as types from '@/store/mutation_types'
|
||||
@@ -85,7 +69,6 @@ export default {
|
||||
name: 'PageNowPlaying',
|
||||
components: {
|
||||
ModalDialogQueueItem,
|
||||
Slider,
|
||||
CoverArtwork
|
||||
},
|
||||
|
||||
@@ -101,11 +84,19 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
state() {
|
||||
progress() {
|
||||
return this.is_live ? 2 : this.item_progress_ms / this.track.length_ms
|
||||
},
|
||||
|
||||
is_live() {
|
||||
return this.track.length_ms == 0
|
||||
},
|
||||
|
||||
player() {
|
||||
return this.$store.state.player
|
||||
},
|
||||
|
||||
now_playing() {
|
||||
track() {
|
||||
return this.$store.getters.now_playing
|
||||
},
|
||||
|
||||
@@ -121,16 +112,16 @@ export default {
|
||||
if (this.settings_option_show_composer_now_playing) {
|
||||
if (
|
||||
!this.settings_option_show_composer_for_genre ||
|
||||
(this.now_playing.genre &&
|
||||
(this.track.genre &&
|
||||
this.settings_option_show_composer_for_genre
|
||||
.toLowerCase()
|
||||
.split(',')
|
||||
.findIndex(
|
||||
(elem) =>
|
||||
this.now_playing.genre.toLowerCase().indexOf(elem.trim()) >= 0
|
||||
this.track.genre.toLowerCase().indexOf(elem.trim()) >= 0
|
||||
) >= 0)
|
||||
) {
|
||||
return this.now_playing.composer
|
||||
return this.track.composer
|
||||
}
|
||||
}
|
||||
return null
|
||||
@@ -142,32 +133,30 @@ export default {
|
||||
|
||||
filepath() {
|
||||
if (this.settings_option_show_filepath_now_playing) {
|
||||
return this.now_playing.path
|
||||
return this.track.path
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
state() {
|
||||
player() {
|
||||
if (this.interval_id > 0) {
|
||||
window.clearTimeout(this.interval_id)
|
||||
this.interval_id = 0
|
||||
}
|
||||
this.item_progress_ms = this.state.item_progress_ms
|
||||
if (this.state.state === 'play') {
|
||||
this.item_progress_ms = this.player.item_progress_ms
|
||||
if (this.player.state === 'play') {
|
||||
this.interval_id = window.setInterval(this.tick, 1000)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {},
|
||||
|
||||
created() {
|
||||
this.item_progress_ms = this.state.item_progress_ms
|
||||
this.item_progress_ms = this.player.item_progress_ms
|
||||
webapi.player_status().then(({ data }) => {
|
||||
this.$store.commit(types.UPDATE_PLAYER_STATUS, data)
|
||||
if (this.state.state === 'play') {
|
||||
if (this.player.state === 'play') {
|
||||
this.interval_id = window.setInterval(this.tick, 1000)
|
||||
}
|
||||
})
|
||||
@@ -183,7 +172,13 @@ export default {
|
||||
methods: {
|
||||
tick() {
|
||||
if (!this.is_dragged) {
|
||||
this.item_progress_ms += 1000
|
||||
if (this.is_live) {
|
||||
this.item_progress_ms += 1000
|
||||
} else if (this.item_progress_ms + 1000 > this.track.length_ms) {
|
||||
this.item_progress_ms = this.track.length_ms
|
||||
} else {
|
||||
this.item_progress_ms += 1000
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -195,10 +190,12 @@ export default {
|
||||
this.is_dragged = false
|
||||
},
|
||||
|
||||
seek(newPosition) {
|
||||
webapi.player_seek_to_pos(newPosition).catch(() => {
|
||||
this.item_progress_ms = this.state.item_progress_ms
|
||||
})
|
||||
seek() {
|
||||
if (!this.is_live) {
|
||||
webapi.player_seek_to_pos(this.item_progress_ms).catch(() => {
|
||||
this.item_progress_ms = this.player.item_progress_ms
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
open_dialog(item) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Search field + recent searches -->
|
||||
<section class="section pb-0">
|
||||
<section class="section fd-page pb-0">
|
||||
<div class="container">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-four-fifths">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Search field + recent searches -->
|
||||
<section class="section pb-0">
|
||||
<section class="section pb-0 fd-page">
|
||||
<div class="container">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-four-fifths">
|
||||
|
||||
Reference in New Issue
Block a user