2019-06-15 20:34:50 +03:00

211 lines
7.5 KiB
Vue

<template>
<v-card flat>
<v-container bg fill-height grid-list-lg pb-5>
<v-layout row wrap pb-5 class="book-layout">
<v-flex xs12 sm6 lg4>
<v-card flat class="text-xs-center">
<v-layout d-inline-block mb-2>
<div class="d-inline-block f-left">
<v-img
v-if="authorImg !== ''"
:src="authorImg"
height="55px"
width="55px"
contain
class="author-image ml-2"
>
</v-img>
</div>
<div class="d-inline-block">
<v-card-title>
<div>{{ authorName }}</div>
</v-card-title>
</div>
</v-layout>
</v-card>
<v-flex xs12 text-xs-center>
<v-img
:src="bookImg"
height="200px"
width="200px"
contain
class="d-inline-block ml-2"
>
</v-img>
</v-flex>
<v-flex xs12 text-xs-center>{{ bookTitle }}</v-flex>
</v-flex>
<v-flex xs12 sm6>
<v-list>
<v-list-tile
v-for="(item, index) in items"
v-bind:key="index"
@click="loadChapter(index, 0, true)"
>
<v-list-tile-action>
<v-icon
v-if="index == currentChapter"
>mdi-play</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title v-text="item.title"></v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-flex>
</v-layout>
</v-container>
</v-card>
</template>
<script>
export default {
data: () => ({
audioElement: null,
authorName: "",
authorImg: "",
bookImg: "",
bookTitle: "",
currentChapter: 0,
currentTime: "00:00",
duration: "00:00",
items: [],
progress: 0,
status: 0, //this.statuses.stopped,
volume: 5
}),
computed: {
isOff () {
return this.audioElement == null;
},
isPaused () {
return this.status === this.statuses.paused;
},
isPlaying () {
return this.status === this.statuses.playing;
},
isChapterLoaded () {
return (this.currentChapter !== null) && this.audioElement;
}
},
watch: {
volume (val) { this.updateVolume(); }
},
methods: {
loadChapter (index = 0, progress = 0, autoplay = false) {
if (this.audioElement) { this.audioElement.pause(); }
if (index >= this.items.length) { return false; } // show message?
this.currentChapter = index;
this.audioElement = new Audio(encodeURI(this.items[index].url));
this.updateVolume();
this.status = this.statuses.stopped;
this.audioElement.addEventListener("ended", this.loadNextChapter);
this.audioElement.ontimeupdate = this.updateProgress;
let bookInstance = this;
this.audioElement.addEventListener("durationchange", function () {
let min = parseInt(bookInstance.audioElement.duration / 60) < 10
? "0" + parseInt(bookInstance.audioElement.duration / 60)
: parseInt(bookInstance.audioElement.duration / 60);
let sec = parseInt(bookInstance.audioElement.duration % 60) < 10
? "0" + parseInt(bookInstance.audioElement.duration % 60)
: parseInt(bookInstance.audioElement.duration % 60);
bookInstance.duration = min + ":" + sec;
});
this.audioElement.addEventListener("canplay", function _listener () {
bookInstance.audioElement.currentTime = bookInstance.audioElement.duration * progress / 100;
bookInstance.audioElement.removeEventListener("canplay", _listener, true);
}, true);
if (autoplay) this.play();
},
loadNextChapter (autoplay = true) {
this.currentChapter++;
if (this.currentChapter >= this.items.length) {
this.currentChapter--;
return false;
}
this.loadChapter(this.currentChapter, 0, autoplay);
},
nextChapter () {
if (this.currentChapter < this.items.length - 1) {
this.currentChapter++;
this.loadChapter(this.currentChapter, 0, true);
}
},
pause () {
this.status = this.statuses.paused;
this.audioElement.pause();
},
play () {
this.status = this.statuses.playing;
this.audioElement.play();
},
prevChapter () {
if (this.currentChapter > 0) {
this.currentChapter--;
this.loadChapter(this.currentChapter, 0, true);
}
},
toggleStatus () {
if (!this.isChapterLoaded) {
this.loadChapter(this.currentChapter || 0);
}
if (!this.isPlaying) {
this.play();
} else {
this.pause();
}
},
updateProgress () {
if (!this.audioElement || !this.audioElement.currentTime) {
return this.progress = 0;
}
this.progress = (this.audioElement.currentTime / this.audioElement.duration) * 100;
let min = parseInt(this.audioElement.currentTime / 60) < 10
? "0" + parseInt(this.audioElement.currentTime / 60)
: parseInt(this.audioElement.currentTime / 60);
let sec = parseInt(this.audioElement.currentTime % 60) < 10
? "0" + parseInt(this.audioElement.currentTime % 60)
: parseInt(this.audioElement.currentTime % 60);
this.currentTime = min + ":" + sec;
},
updateVolume () {
this.audioElement ? this.audioElement.volume = (this.volume / 10) : null;
}
}
}
</script>
<style>
.author-image {
display: inline-block;
border-radius: 55px;
}
.book-layout { min-height: calc(100vh - 190px); }
.f-left { float: left; }
</style>