koel/resources/assets/js/components/ui/VolumeSlider.vue

77 lines
2.3 KiB
Vue
Raw Normal View History

2022-04-15 14:24:30 +00:00
<template>
2024-04-04 22:20:42 +00:00
<span id="volume" :class="level" class="hidden md:flex relative items-center gap-2">
<FooterExtraControlBtn v-show="level === 'muted'" tabindex="0" title="Unmute" @click="unmute">
2023-11-10 13:16:06 +00:00
<Icon :icon="faVolumeMute" fixed-width />
2024-04-04 22:20:42 +00:00
</FooterExtraControlBtn>
2024-04-04 22:20:42 +00:00
<FooterExtraControlBtn v-show="level !== 'muted'" tabindex="0" title="Mute" @click="mute">
2023-11-10 13:16:06 +00:00
<Icon :icon="level === 'discreet' ? faVolumeLow : faVolumeHigh" fixed-width />
2024-04-04 22:20:42 +00:00
</FooterExtraControlBtn>
2022-07-15 07:23:55 +00:00
2022-04-15 14:24:30 +00:00
<input
2024-03-18 17:51:51 +00:00
ref="inputEl"
2024-04-04 22:20:42 +00:00
class="plyr__volume !w-[120px] before:absolute before:left-0 before:right-0 before:top-[-12px] before:bottom-[-12px]"
2022-04-15 14:24:30 +00:00
max="10"
role="slider"
2022-04-15 14:24:30 +00:00
step="0.1"
title="Volume"
type="range"
@input="setVolume"
2022-04-15 14:24:30 +00:00
>
</span>
</template>
2022-04-15 17:00:08 +00:00
<script lang="ts" setup>
2022-07-15 07:23:55 +00:00
import { faVolumeHigh, faVolumeLow, faVolumeMute } from '@fortawesome/free-solid-svg-icons'
2024-03-18 17:51:51 +00:00
import { computed, onMounted, ref } from 'vue'
import { socketService, volumeManager } from '@/services'
import { preferenceStore } from '@/stores'
2024-03-18 17:51:51 +00:00
import { watchThrottled } from '@vueuse/core'
2024-04-04 22:20:42 +00:00
import FooterExtraControlBtn from '@/components/layout/app-footer/FooterButton.vue'
2022-04-15 14:24:30 +00:00
2024-03-18 17:51:51 +00:00
const inputEl = ref<HTMLInputElement>()
2022-04-15 14:24:30 +00:00
const level = computed(() => {
2024-03-18 18:04:32 +00:00
if (volumeManager.volume.value === 0) return 'muted'
if (volumeManager.volume.value < 3) return 'discreet'
return 'loud'
})
2022-04-15 14:24:30 +00:00
const mute = () => volumeManager.mute()
const unmute = () => volumeManager.unmute()
2022-12-02 16:17:37 +00:00
const setVolume = (e: Event) => volumeManager.set(parseFloat((e.target as HTMLInputElement).value))
2022-07-15 07:23:55 +00:00
2024-03-18 18:04:32 +00:00
// since changing volume can be frequent, we throttle the event to avoid too many "save preferences" API calls
// and socket broadcasts
2024-03-18 17:51:51 +00:00
watchThrottled(volumeManager.volume, volume => {
preferenceStore.volume = volume
socketService.broadcast('SOCKET_VOLUME_CHANGED', volume)
}, { throttle: 1_000 })
onMounted(() => volumeManager.init(inputEl.value!, preferenceStore.volume))
2022-04-15 14:24:30 +00:00
</script>
2024-04-04 20:13:35 +00:00
<style lang="postcss" scoped>
2022-04-15 14:24:30 +00:00
#volume {
[type=range] {
2022-10-13 15:18:47 +00:00
&::-webkit-slider-thumb {
2024-04-04 22:20:42 +00:00
@apply bg-k-text-secondary;
2022-10-13 15:18:47 +00:00
}
&:hover {
&::-webkit-slider-thumb {
2024-04-04 22:20:42 +00:00
@apply bg-k-text-primary;
2022-10-13 15:18:47 +00:00
}
}
2022-04-15 14:24:30 +00:00
}
2022-10-13 15:18:47 +00:00
&.muted {
[type=range] {
&::-webkit-slider-thumb {
2024-04-04 22:20:42 +00:00
@apply bg-transparent shadow-none;
2022-10-13 15:18:47 +00:00
}
}
2022-04-15 14:24:30 +00:00
}
}
</style>