advplyr.audiobookshelf-app/components/modals/PlaybackSpeedModal.vue

122 lines
3.5 KiB
Vue
Raw Permalink Normal View History

<template>
<modals-modal v-model="show" @input="modalInput" :width="200" height="100%">
<template #outer>
2023-02-26 14:41:18 -06:00
<div class="absolute top-8 left-4 z-40">
<p class="text-white text-2xl truncate">{{ $strings.LabelPlaybackSpeed }}</p>
</div>
</template>
<div class="w-full h-full overflow-hidden absolute top-0 left-0 flex items-center justify-center">
<div class="w-full overflow-x-hidden overflow-y-auto bg-primary rounded-lg border border-border" style="max-height: 75%" @click.stop>
<ul class="w-full" role="listbox" aria-labelledby="listbox-label">
<template v-for="rate in rates">
<li :key="rate" class="text-fg select-none relative py-4" :class="rate === selected ? 'bg-bg-hover/50' : ''" role="option" @click="clickedOption(rate)">
<div class="flex items-center justify-center">
<span class="font-normal block truncate text-lg">{{ rate }}x</span>
</div>
</li>
</template>
</ul>
<div class="flex items-center justify-center py-3 border-t border-fg/10">
<button :disabled="!canDecrement" @click="decrement" class="icon-num-btn w-8 h-8 text-fg-muted rounded border border-border flex items-center justify-center">
<span class="material-symbols">remove</span>
</button>
<div class="w-24 text-center">
<p class="text-xl">{{ playbackRate }}<span class="text-lg"></span></p>
</div>
<button :disabled="!canIncrement" @click="increment" class="icon-num-btn w-8 h-8 text-fg-muted rounded border border-border flex items-center justify-center">
<span class="material-symbols">add</span>
</button>
</div>
</div>
</div>
</modals-modal>
</template>
<script>
export default {
props: {
value: Boolean,
playbackRate: Number
},
data() {
return {
currentPlaybackRate: 0,
MIN_SPEED: 0.5,
2023-01-16 17:34:42 -06:00
MAX_SPEED: 10
}
},
watch: {
show(newVal) {
if (newVal) {
this.currentPlaybackRate = this.selected
}
}
},
computed: {
show: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
},
selected: {
get() {
return this.playbackRate
},
set(val) {
this.$emit('update:playbackRate', val)
}
},
rates() {
return [0.5, 1, 1.2, 1.5, 1.7, 2, 3]
},
canIncrement() {
return this.playbackRate + 0.1 <= this.MAX_SPEED
},
canDecrement() {
return this.playbackRate - 0.1 >= this.MIN_SPEED
}
},
methods: {
increment() {
if (this.selected + 0.1 > this.MAX_SPEED) return
var newPlaybackRate = this.selected + 0.1
this.selected = Number(newPlaybackRate.toFixed(1))
},
decrement() {
if (this.selected - 0.1 < this.MIN_SPEED) return
var newPlaybackRate = this.selected - 0.1
this.selected = Number(newPlaybackRate.toFixed(1))
},
modalInput(val) {
if (!val) {
if (this.currentPlaybackRate !== this.selected) {
this.$emit('change', this.selected)
}
}
},
clickedOption(rate) {
this.selected = Number(rate)
this.show = false
this.$emit('change', Number(rate))
}
},
mounted() {}
}
</script>
<style>
button.icon-num-btn:disabled {
cursor: not-allowed;
}
button.icon-num-btn:disabled::before {
background-color: rgba(0, 0, 0, 0.2);
}
button.icon-num-btn:disabled span {
color: #777;
}
</style>