mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-13 16:03:23 -05:00
[web] Create a slider component
As a component, the slider is easier to maintain.
This commit is contained in:
parent
4cddfa4dfc
commit
583b676489
29
web-src/src/components/ControlSlider.vue
Normal file
29
web-src/src/components/ControlSlider.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<input
|
||||
:value="value"
|
||||
:disabled="disabled"
|
||||
class="slider"
|
||||
:class="{ 'is-inactive': disabled }"
|
||||
:max="max"
|
||||
type="range"
|
||||
:style="{
|
||||
'--ratio': ratio,
|
||||
'--cursor': $filters.cursor(cursor)
|
||||
}"
|
||||
@input="$emit('update:value', $event.target.value)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ControlSlider',
|
||||
props: ['value', 'max', 'disabled', 'cursor'],
|
||||
emits: ['update:value'],
|
||||
|
||||
computed: {
|
||||
ratio() {
|
||||
return this.value / this.max
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -112,12 +112,9 @@
|
||||
<div class="level-item">
|
||||
<div>
|
||||
<p class="heading" v-text="$t('navigation.volume')" />
|
||||
<input
|
||||
v-model="player.volume"
|
||||
class="slider"
|
||||
max="100"
|
||||
type="range"
|
||||
:style="{ '--ratio': player.volume / 100 }"
|
||||
<control-slider
|
||||
v-model:value="player.volume"
|
||||
:max="100"
|
||||
@change="change_volume"
|
||||
/>
|
||||
</div>
|
||||
@ -163,17 +160,11 @@
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<input
|
||||
v-model="stream_volume"
|
||||
<control-slider
|
||||
v-model:value="stream_volume"
|
||||
:disabled="!playing"
|
||||
class="slider"
|
||||
:class="{ 'is-inactive': !playing }"
|
||||
max="100"
|
||||
type="range"
|
||||
:style="{
|
||||
'--ratio': stream_volume / 100,
|
||||
'--cursor': $filters.cursor(cursor)
|
||||
}"
|
||||
:max="100"
|
||||
:cursor="cursor"
|
||||
@change="change_stream_volume"
|
||||
/>
|
||||
</div>
|
||||
@ -229,12 +220,9 @@
|
||||
<div class="level-item">
|
||||
<div class="is-flex-grow-1">
|
||||
<p class="heading" v-text="$t('navigation.volume')" />
|
||||
<input
|
||||
v-model="player.volume"
|
||||
class="slider"
|
||||
max="100"
|
||||
type="range"
|
||||
:style="{ '--ratio': player.volume / 100 }"
|
||||
<control-slider
|
||||
v-model:value="player.volume"
|
||||
:max="100"
|
||||
@change="change_volume"
|
||||
/>
|
||||
</div>
|
||||
@ -279,17 +267,11 @@
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<input
|
||||
v-model="stream_volume"
|
||||
<control-slider
|
||||
v-model:value="stream_volume"
|
||||
:disabled="!playing"
|
||||
class="slider"
|
||||
:class="{ 'is-inactive': !playing }"
|
||||
max="100"
|
||||
type="range"
|
||||
:style="{
|
||||
'--ratio': stream_volume / 100,
|
||||
'--cursor': $filters.cursor(cursor)
|
||||
}"
|
||||
:max="100"
|
||||
:cursor="cursor"
|
||||
@change="change_stream_volume"
|
||||
/>
|
||||
</div>
|
||||
@ -303,8 +285,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import webapi from '@/webapi'
|
||||
import * as types from '@/store/mutation_types'
|
||||
import _audio from '@/audio'
|
||||
import ControlSlider from '@/components/ControlSlider.vue'
|
||||
import { mdiCancel } from '@mdi/js'
|
||||
import NavbarItemLink from './NavbarItemLink.vue'
|
||||
import NavbarItemOutput from './NavbarItemOutput.vue'
|
||||
@ -316,11 +299,12 @@ 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 * as types from '@/store/mutation_types'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'NavbarBottom',
|
||||
components: {
|
||||
ControlSlider,
|
||||
NavbarItemLink,
|
||||
NavbarItemOutput,
|
||||
PlayerButtonPlayPause,
|
||||
|
@ -23,17 +23,11 @@
|
||||
:class="{ 'has-text-grey-light': !output.selected }"
|
||||
v-text="output.name"
|
||||
/>
|
||||
<input
|
||||
v-model="volume"
|
||||
<control-slider
|
||||
v-model:value="volume"
|
||||
:disabled="!output.selected"
|
||||
class="slider"
|
||||
:class="{ 'is-inactive': !output.selected }"
|
||||
max="100"
|
||||
type="range"
|
||||
:style="{
|
||||
'--ratio': volume / 100,
|
||||
'--cursor': $filters.cursor(cursor)
|
||||
}"
|
||||
:max="100"
|
||||
:cursor="cursor"
|
||||
@change="change_volume"
|
||||
/>
|
||||
</div>
|
||||
@ -44,14 +38,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ControlSlider from '@/components/ControlSlider.vue'
|
||||
import { mdiCancel } from '@mdi/js'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'NavbarItemOutput',
|
||||
|
||||
props: ['output'],
|
||||
|
||||
components: {
|
||||
ControlSlider
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
volume: this.output.selected ? this.output.volume : 0,
|
||||
|
@ -63,28 +63,16 @@
|
||||
<b v-text="$t('navigation.music')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link to="/music/artists">
|
||||
<span
|
||||
class="pl-5"
|
||||
v-text="$t('navigation.artists')"
|
||||
/>
|
||||
<span class="pl-5" v-text="$t('navigation.artists')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link to="/music/albums">
|
||||
<span
|
||||
class="pl-5"
|
||||
v-text="$t('navigation.albums')"
|
||||
/>
|
||||
<span class="pl-5" v-text="$t('navigation.albums')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link to="/music/genres">
|
||||
<span
|
||||
class="pl-5"
|
||||
v-text="$t('navigation.genres')"
|
||||
/>
|
||||
<span class="pl-5" v-text="$t('navigation.genres')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link v-if="spotify_enabled" to="/music/spotify">
|
||||
<span
|
||||
class="pl-5"
|
||||
v-text="$t('navigation.spotify')"
|
||||
/>
|
||||
<span class="pl-5" v-text="$t('navigation.spotify')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link to="/podcasts">
|
||||
<mdicon class="icon" name="microphone" size="16" />
|
||||
@ -132,8 +120,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavbarItemLink from './NavbarItemLink.vue'
|
||||
import * as types from '@/store/mutation_types'
|
||||
import NavbarItemLink from './NavbarItemLink.vue'
|
||||
|
||||
export default {
|
||||
name: 'NavbarTop',
|
||||
|
@ -9,17 +9,12 @@
|
||||
class="is-clickable fd-has-shadow fd-cover-big-image"
|
||||
@click="open_dialog(track)"
|
||||
/>
|
||||
<input
|
||||
v-model.number="track_progress"
|
||||
:max="track_progress_max"
|
||||
type="range"
|
||||
class="slider mt-5"
|
||||
:class="{ 'is-inactive': is_live }"
|
||||
:style="{
|
||||
'--ratio': track_progress_ratio,
|
||||
'--cursor': $filters.cursor(cursor)
|
||||
}"
|
||||
<control-slider
|
||||
v-model:value="track_progress"
|
||||
class="mt-5"
|
||||
:disabled="is_live"
|
||||
:max="track_progress_max"
|
||||
:cursor="cursor"
|
||||
@change="seek"
|
||||
@mousedown="start_dragging"
|
||||
@mouseup="end_dragging"
|
||||
@ -58,19 +53,21 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as types from '@/store/mutation_types'
|
||||
import ControlSlider from '@/components/ControlSlider.vue'
|
||||
import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||
import { mdiCancel } from '@mdi/js'
|
||||
import ModalDialogQueueItem from '@/components/ModalDialogQueueItem.vue'
|
||||
import webapi from '@/webapi'
|
||||
import * as types from '@/store/mutation_types'
|
||||
|
||||
const INTERVAL = 1000
|
||||
|
||||
export default {
|
||||
name: 'PageNowPlaying',
|
||||
components: {
|
||||
ModalDialogQueueItem,
|
||||
CoverArtwork
|
||||
ControlSlider,
|
||||
CoverArtwork,
|
||||
ModalDialogQueueItem
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -79,8 +76,8 @@ export default {
|
||||
INTERVAL,
|
||||
interval_id: 0,
|
||||
is_dragged: false,
|
||||
show_details_modal: false,
|
||||
selected_item: {}
|
||||
selected_item: {},
|
||||
show_details_modal: false
|
||||
}
|
||||
},
|
||||
|
||||
@ -98,10 +95,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
track_progress_ratio() {
|
||||
return this.track_progress / this.track_progress_max
|
||||
},
|
||||
|
||||
player() {
|
||||
return this.$store.state.player
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user