[web] Create a slider component

As a component, the slider is easier to maintain.
This commit is contained in:
Alain Nussbaumer 2023-07-05 22:24:50 +02:00
parent 4cddfa4dfc
commit 583b676489
5 changed files with 72 additions and 82 deletions

View 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>

View File

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

View File

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

View File

@ -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',

View File

@ -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
},