repod/src/components/Player/Bar.vue

173 lines
3.8 KiB
Vue
Raw Normal View History

2023-08-24 20:29:11 +00:00
<template>
2023-08-27 18:01:26 +00:00
<div v-if="episode" class="footer">
<audio id="audio-player"
autoplay
preload
:src="episode.episodeUrl"
2023-08-27 18:29:54 +00:00
@durationchange="duration = audio.duration"
2023-08-27 18:01:26 +00:00
@loadeddata="loading = false"
@pause="paused = audio.paused"
@play="paused = audio.paused"
@seeked="currentTime = audio.currentTime"
2023-08-27 18:29:54 +00:00
@timeupdate="currentTime = audio.currentTime"
2023-08-27 18:01:26 +00:00
@volumechange="volume = audio.volume" />
<NcLoadingIcon v-if="loading" />
<div v-if="!loading"
2023-08-27 19:33:39 +00:00
class="pointer"
2023-08-27 18:29:54 +00:00
@click="(event) => audio.fastSeek(event.x * duration / event.target.offsetWidth)">
<NcProgressBar size="medium" :value="currentTime * 100 / duration" />
2023-08-27 18:01:26 +00:00
</div>
<div v-if="!loading" class="player">
<img :src="episode.episodeImage">
<div class="infos">
<a :href="episode.episodeLink" target="_blank">
<strong>{{ episode.episodeName }}</strong>
</a>
<a :href="podcastLink" target="_blank">
<i>{{ episode.podcastName }}</i>
</a>
</div>
2023-08-27 19:33:39 +00:00
<PauseButton v-if="!paused"
class="pointer"
:size="50"
@click="() => audio.pause()" />
<PlayButton v-if="paused"
class="pointer"
:size="50"
@click="() => audio.play()" />
<StopButton class="pointer"
:size="30"
@click="stop" />
2023-08-27 18:01:26 +00:00
<div class="time">
2023-08-27 18:29:54 +00:00
<span class="current">{{ formatTimer(new Date(currentTime*1000)) }}</span>
2023-08-27 18:01:26 +00:00
<span class="divider">/</span>
2023-08-27 18:29:54 +00:00
<span class="length">{{ formatTimer(new Date(duration*1000)) }}</span>
2023-08-27 18:01:26 +00:00
</div>
<div class="volume">
2023-08-27 19:33:39 +00:00
<VolumeHigh v-if="volume > 0.7"
class="pointer"
:size="30"
@click="mute" />
<VolumeLow v-if="volume > 0 && volume <= 0.3"
class="pointer"
:size="30"
@click="mute" />
<VolumeMedium v-if="volume > 0.3 && volume <= 0.7"
class="pointer"
:size="30"
@click="mute" />
<VolumeMute v-if="volume == 0"
class="pointer"
:size="30"
@click="unmute" />
2023-08-27 10:45:19 +00:00
</div>
2023-08-24 21:19:54 +00:00
</div>
2023-08-27 18:01:26 +00:00
</div>
2023-08-24 20:29:11 +00:00
</template>
<script>
2023-08-27 18:01:26 +00:00
import { NcLoadingIcon, NcProgressBar } from '@nextcloud/vue'
2023-08-27 19:33:39 +00:00
import PauseButton from 'vue-material-design-icons/Pause.vue'
import PlayButton from 'vue-material-design-icons/Play.vue'
import StopButton from 'vue-material-design-icons/Stop.vue'
2023-08-27 10:45:19 +00:00
import VolumeHigh from 'vue-material-design-icons/VolumeHigh.vue'
import VolumeLow from 'vue-material-design-icons/VolumeLow.vue'
import VolumeMedium from 'vue-material-design-icons/VolumeMedium.vue'
import VolumeMute from 'vue-material-design-icons/VolumeMute.vue'
2023-08-27 18:29:54 +00:00
import { formatTimer } from '../../utils/time.js'
2023-08-27 10:45:19 +00:00
2023-08-24 20:29:11 +00:00
export default {
name: 'Bar',
2023-08-27 10:45:19 +00:00
components: {
2023-08-27 18:01:26 +00:00
NcLoadingIcon,
2023-08-27 10:45:19 +00:00
NcProgressBar,
2023-08-27 19:33:39 +00:00
PauseButton,
PlayButton,
StopButton,
2023-08-27 10:45:19 +00:00
VolumeHigh,
VolumeLow,
VolumeMedium,
VolumeMute,
},
2023-08-27 18:01:26 +00:00
data() {
return {
currentTime: 0,
2023-08-27 18:29:54 +00:00
duration: 0,
2023-08-27 18:01:26 +00:00
loading: true,
paused: true,
2023-08-27 19:33:39 +00:00
volume: 1,
volumeMuted: 0,
2023-08-27 18:01:26 +00:00
}
},
2023-08-24 20:29:11 +00:00
computed: {
2023-08-27 10:45:19 +00:00
audio() {
2023-08-27 18:01:26 +00:00
return document.getElementById('audio-player')
2023-08-27 10:45:19 +00:00
},
2023-08-24 21:19:54 +00:00
episode() {
return this.$store.state.player.episode
2023-08-24 20:29:11 +00:00
},
2023-08-27 10:45:19 +00:00
podcastLink() {
return atob(this.$route.params.url)
},
2023-08-24 20:29:11 +00:00
},
2023-08-27 18:29:54 +00:00
methods: {
formatTimer,
2023-08-27 19:33:39 +00:00
mute() {
this.volumeMuted = this.audio.volume
this.audio.volume = 0
},
stop() {
this.$store.commit('player/play', null)
},
unmute() {
this.audio.volume = this.volumeMuted
},
2023-08-27 18:29:54 +00:00
},
2023-08-24 20:29:11 +00:00
}
</script>
<style scoped>
2023-08-24 21:19:54 +00:00
.footer {
2023-08-27 10:45:19 +00:00
background-color: rgba(66, 66, 66, .9);
2023-08-24 21:59:55 +00:00
bottom: 0;
2023-08-27 10:45:19 +00:00
height: 6rem;
2023-08-24 21:59:55 +00:00
right: 0;
2023-08-24 20:29:11 +00:00
position: absolute;
width: 100%;
2023-08-24 21:59:55 +00:00
z-index: 2000;
2023-08-24 20:29:11 +00:00
}
2023-08-27 10:45:19 +00:00
.infos {
display: flex;
flex-direction: column;
justify-content: center;
2023-08-27 19:33:39 +00:00
width: 45%;
2023-08-27 10:45:19 +00:00
}
.player {
display: flex;
gap: 1rem;
height: calc(6rem - 6px);
2023-08-27 19:33:39 +00:00
justify-content: space-between;
2023-08-27 10:45:19 +00:00
}
2023-08-27 18:01:26 +00:00
2023-08-27 19:33:39 +00:00
.pointer {
2023-08-27 18:01:26 +00:00
cursor: pointer;
}
2023-08-27 19:33:39 +00:00
.time, .volume {
align-items: center;
display: flex;
gap: 5px;
justify-content: center;
}
.time {
width: 25%;
}
.volume {
width: 10%;
}
2023-08-24 20:29:11 +00:00
</style>