[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:
Alain Nussbaumer
2023-06-21 15:14:17 +02:00
parent b7a52d1761
commit eeb4d328c8
15 changed files with 249 additions and 241 deletions

View File

@@ -11,7 +11,6 @@
"@aacassandra/vue3-progressbar": "^1.0.3",
"@mdi/js": "^6.7.96",
"@ts-pro/vue-eternal-loading": "^1.2.0",
"@vueform/slider": "github:chme/slider#faff83ed8a77f2cdbcb7252505ef734301efd139",
"axios": "^1.4.0",
"bulma": "^0.9.4",
"bulma-switch": "^2.0.4",
@@ -36,7 +35,7 @@
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-vue": "^9.14.1",
"prettier": "^2.8.8",
"sass": "^1.62.1",
"sass": "^1.63.5",
"vite": "^2.9.16"
}
},
@@ -50,9 +49,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.22.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.4.tgz",
"integrity": "sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==",
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz",
"integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -124,9 +123,9 @@
}
},
"node_modules/@eslint/js": {
"version": "8.42.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz",
"integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==",
"version": "8.43.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz",
"integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -481,16 +480,10 @@
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
},
"node_modules/@vueform/slider": {
"version": "2.0.9",
"resolved": "git+ssh://git@github.com/chme/slider.git#faff83ed8a77f2cdbcb7252505ef734301efd139",
"integrity": "sha512-IfGEwBS5hwptmLbcnjrhDB7olw8mhCbQFDYv24bfYK/LVJo8pueumd7qsO9qlwfyezgnBdp1/CGBm+Wrh1oYdA==",
"license": "MIT"
},
"node_modules/acorn": {
"version": "8.8.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
"integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -745,9 +738,9 @@
"dev": true
},
"node_modules/core-js": {
"version": "3.30.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz",
"integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==",
"version": "3.31.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.0.tgz",
"integrity": "sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
@@ -1197,15 +1190,15 @@
}
},
"node_modules/eslint": {
"version": "8.42.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz",
"integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==",
"version": "8.43.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz",
"integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.3",
"@eslint/js": "8.42.0",
"@eslint/js": "8.43.0",
"@humanwhocodes/config-array": "^0.11.10",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -1265,9 +1258,9 @@
}
},
"node_modules/eslint-plugin-vue": {
"version": "9.14.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.14.1.tgz",
"integrity": "sha512-LQazDB1qkNEKejLe/b5a9VfEbtbczcOaui5lQ4Qw0tbRBbQYREyxxOV5BQgNDTqGPs9pxqiEpbMi9ywuIaF7vw==",
"version": "9.15.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.15.0.tgz",
"integrity": "sha512-XYzpK6e2REli100+6iCeBA69v6Sm0D/yK2FZP+fCeNt0yH/m82qZQq+ztseyV0JsKdhFysuSEzeE1yCmSC92BA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.3.0",
@@ -2399,9 +2392,9 @@
}
},
"node_modules/sass": {
"version": "1.62.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz",
"integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==",
"version": "1.63.5",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.63.5.tgz",
"integrity": "sha512-Q6c5gs482oezdAp+0fWF9cRisvpy7yfYb64knID0OE8AnMgtkluRPfpGMFjeD4/+M4+6QpJZCU6JRSxbjiktkg==",
"dev": true,
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
@@ -2416,9 +2409,9 @@
}
},
"node_modules/semver": {
"version": "7.5.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
"integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
"integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -2645,9 +2638,9 @@
}
},
"node_modules/vue-eslint-parser": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.0.tgz",
"integrity": "sha512-48IxT9d0+wArT1+3wNIy0tascRoywqSUe2E1YalIC1L8jsUGe5aJQItWfRok7DVFGz3UYvzEI7n5wiTXsCMAcQ==",
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz",
"integrity": "sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==",
"dev": true,
"dependencies": {
"debug": "^4.3.4",

View File

@@ -6,7 +6,7 @@
"build": "vite build --base='./'",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
"dev": "vite",
"format": "prettier . --write",
"format": "prettier . --write",
"i18n:report": "vue-cli-service i18n:report --src \"./src/**/*.?(js|vue)\" --locales \"./src/locales/**/*.json\"",
"preview": "vite preview"
},
@@ -14,7 +14,6 @@
"@aacassandra/vue3-progressbar": "^1.0.3",
"@mdi/js": "^6.7.96",
"@ts-pro/vue-eternal-loading": "^1.2.0",
"@vueform/slider": "github:chme/slider#faff83ed8a77f2cdbcb7252505ef734301efd139",
"axios": "^1.4.0",
"bulma": "^0.9.4",
"bulma-switch": "^2.0.4",
@@ -39,7 +38,7 @@
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-vue": "^9.14.1",
"prettier": "^2.8.8",
"sass": "^1.62.1",
"sass": "^1.63.5",
"vite": "^2.9.16"
}
}

View File

@@ -3,7 +3,7 @@
<navbar-top />
<vue-progress-bar class="fd-progress-bar" />
<router-view v-slot="{ Component }">
<component :is="Component" class="fd-page" />
<component :is="Component" />
</router-view>
<modal-dialog-remote-pairing

View File

@@ -115,14 +115,13 @@
<div class="level-item fd-expanded">
<div class="fd-expanded">
<p class="heading" v-text="$t('navigation.volume')" />
<Slider
<input
v-model="player.volume"
:min="0"
:max="100"
:step="1"
:tooltips="false"
:classes="{ target: 'slider' }"
@change="set_volume"
class="slider"
max="100"
type="range"
:style="{ '--ratio': player.volume / 100 }"
@change="change_volume"
/>
</div>
</div>
@@ -175,15 +174,15 @@
/></span>
</a>
</p>
<Slider
<input
v-model="stream_volume"
:min="0"
:max="100"
:step="1"
:tooltips="false"
:disabled="!playing"
:classes="{ target: 'slider' }"
@change="set_stream_volume"
class="slider"
:class="{ 'is-inactive': !playing }"
max="100"
type="range"
:style="{ '--ratio': stream_volume / 100 }"
@change="change_stream_volume"
/>
</div>
</div>
@@ -238,14 +237,13 @@
<div class="level-item fd-expanded">
<div class="fd-expanded">
<p class="heading" v-text="$t('navigation.volume')" />
<Slider
<input
v-model="player.volume"
:min="0"
:max="100"
:step="1"
:tooltips="false"
:classes="{ target: 'slider' }"
@change="set_volume"
class="slider"
max="100"
type="range"
:style="{ '--ratio': player.volume / 100 }"
@change="change_volume"
/>
</div>
</div>
@@ -260,7 +258,7 @@
/>
<!-- Outputs: stream volume -->
<hr class="fd-navbar-divider" />
<div class="navbar-item fd-has-margin-bottom">
<div class="navbar-item mb-5">
<div class="level is-mobile">
<div class="level-left fd-expanded">
<div class="level-item" style="flex-grow: 0">
@@ -298,15 +296,15 @@
/></span>
</a>
</p>
<Slider
<input
v-model="stream_volume"
:min="0"
:max="100"
:step="1"
:tooltips="false"
:disabled="!playing"
:classes="{ target: 'slider' }"
@change="set_stream_volume"
class="slider"
:class="{ 'is-inactive': !playing }"
max="100"
type="range"
:style="{ '--ratio': stream_volume / 100 }"
@change="change_stream_volume"
/>
</div>
</div>
@@ -331,7 +329,6 @@ import PlayerButtonConsume from '@/components/PlayerButtonConsume.vue'
import PlayerButtonRepeat from '@/components/PlayerButtonRepeat.vue'
import PlayerButtonSeekBack from '@/components/PlayerButtonSeekBack.vue'
import PlayerButtonSeekForward from '@/components/PlayerButtonSeekForward.vue'
import Slider from '@vueform/slider'
import * as types from '@/store/mutation_types'
export default {
@@ -339,7 +336,6 @@ export default {
components: {
NavbarItemLink,
NavbarItemOutput,
Slider,
PlayerButtonPlayPause,
PlayerButtonNext,
PlayerButtonPrevious,
@@ -382,9 +378,6 @@ export default {
return ''
},
state() {
return this.$store.state.player
},
now_playing() {
return this.$store.getters.now_playing
},
@@ -427,16 +420,13 @@ export default {
this.show_outputs_menu = false
},
set_volume(newVolume) {
webapi.player_volume(newVolume)
change_volume() {
webapi.player_volume(this.player.volume)
},
toggle_mute_volume() {
if (this.player.volume > 0) {
this.set_volume(0)
} else {
this.set_volume(this.old_volume)
}
this.player.volume = this.player.volume > 0 ? 0 : this.old_volume
this.change_volume()
},
setupAudio() {
@@ -492,8 +482,8 @@ export default {
return this.playChannel()
},
set_stream_volume(newVolume) {
this.stream_volume = newVolume
change_stream_volume() {
console.log(this.stream_volume)
_audio.setVolume(this.stream_volume / 100)
}
}

View File

@@ -19,15 +19,15 @@
:class="{ 'has-text-grey-light': !output.selected }"
v-text="output.name"
/>
<Slider
<input
v-model="volume"
:min="0"
:max="100"
:step="1"
:tooltips="false"
:disabled="!output.selected"
:classes="{ target: 'slider' }"
@change="set_volume"
class="slider"
:class="{ 'is-inactive': !output.selected }"
max="100"
type="range"
:style="{ '--ratio': volume / 100 }"
@change="change_volume"
/>
</div>
</div>
@@ -37,17 +37,19 @@
</template>
<script>
import Slider from '@vueform/slider'
import webapi from '@/webapi'
export default {
name: 'NavbarItemOutput',
components: {
Slider
},
props: ['output'],
data() {
return {
volume: this.output.selected ? this.output.volume : 0
}
},
computed: {
type_class() {
if (this.output.type.startsWith('AirPlay')) {
@@ -59,20 +61,18 @@ export default {
} else {
return 'server'
}
},
}
},
volume() {
return this.output.selected ? this.output.volume : 0
watch: {
output() {
this.volume = this.output.volume
}
},
methods: {
play_next() {
webapi.player_next()
},
set_volume(newVolume) {
webapi.player_output_volume(this.output.id, newVolume)
change_volume() {
webapi.player_output_volume(this.output.id, this.volume)
},
set_enabled() {

View File

@@ -12,7 +12,6 @@ import { icons } from './icons'
import App from './App.vue'
import './mystyles.scss'
import '@vueform/slider/themes/default.css'
const app = createApp(App)
.use(store)

View File

@@ -3,40 +3,6 @@
@import 'bulma/bulma.sass';
@import 'bulma-switch';
/* Volume slider */
.slider {
min-width: 250px;
width: 100%;
margin-top: 16px;
margin-bottom: 16px;
--slider-height: 4px;
--slider-connect-bg: #{$dark};
--slider-tooltip-bg: #{$dark};
--slider-handle-ring-color: #3b82f630;
--slider-handle-shadow: 0.5px 0.5px 0.5px 0.5px rgba(0, 0, 0, 0.32);
--slider-handle-shadow-active: 0.5px 0.5px 0.5px 0.5px rgba(0, 0, 0, 0.42);
}
/* Now playing progress bar */
.seek-slider {
min-width: 250px;
max-width: 500px;
width: 100% !important;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
margin: 0 auto 16px auto;
--slider-height: 4px;
--slider-connect-bg: #{$primary};
--slider-tooltip-bg: #{$primary};
--slider-handle-bg: #{$primary};
--slider-handle-border: 0;
--slider-handle-width: 10px;
--slider-handle-height: 10px;
--slider-handle-radius: 9999px;
--slider-handle-shadow: 0.5px 0.5px 0.5px 0.5px rgba(0, 0, 0, 0.32);
--slider-handle-shadow-active: 0.5px 0.5px 0.5px 0.5px rgba(0, 0, 0, 0.42);
--slider-handle-ring-width: 3px;
}
.progress-bar {
background-color: $info;
border-radius: 9999px;
@@ -299,3 +265,67 @@ hr.fd-navbar-divider {
.hero-body {
padding: 1.5rem !important;
}
/* Slider */
@mixin thumb {
-webkit-appearance: none;
width: var(--th);
height: var(--th);
border-radius: 50%;
background: $dark;
border: none;
}
@mixin track {
height: calc(var(--sh));
border-radius: calc(var(--sh) / 2);
background: linear-gradient(90deg, $dark var(--sx), $grey-light var(--sx));
}
input[type='range'].slider {
--sh: 0.5rem;
--th: calc(var(--sh) * 1.5);
--sx: calc(var(--th) / 2 + (var(--ratio) * (100% - var(--th))));
-webkit-appearance: none;
min-width: 250px;
width: 100% !important;
cursor: grab;
&:active {
cursor: grabbing;
}
&::-webkit-slider-thumb {
@include thumb;
margin-top: calc((var(--th) - var(--sh)) / -2);
}
&::-moz-range-thumb {
@include thumb;
}
&::-webkit-slider-runnable-track {
@include track;
}
&::-moz-range-track {
@include track;
}
&.is-inactive {
&::-webkit-slider-thumb {
background-color: $grey-light;
}
&::-webkit-slider-runnable-track {
background: linear-gradient(
90deg,
$grey-light var(--sx),
$light var(--sx)
);
}
&::-moz-range-thumb {
background-color: $grey-light;
}
&::-moz-range-track {
background: linear-gradient(
90deg,
$grey-light var(--sx),
$light var(--sx)
);
}
}
}

View File

@@ -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">

View File

@@ -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) {

View File

@@ -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">

View File

@@ -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">

View File

@@ -1,5 +1,5 @@
<template>
<section class="section fd-content">
<section class="section fd-page fd-content">
<div class="container">
<div class="columns is-centered">
<div class="column is-four-fifths">

View File

@@ -1,6 +1,6 @@
<template>
<div>
<section class="hero is-light is-bold fd-content">
<section class="hero is-light is-bold fd-page fd-content">
<div class="hero-body">
<div class="container">
<div class="columns is-centered">