First release
This commit is contained in:
commit
b94234c8e7
50 changed files with 18231 additions and 0 deletions
109
app/client/src/components/Lyrics.vue
Normal file
109
app/client/src/components/Lyrics.vue
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<div :style='"max-height: " + height' class='overflow-y-auto' ref='content'>
|
||||
<div class='text-center my-4'>
|
||||
<v-progress-circular indeterminate v-if='loading'></v-progress-circular>
|
||||
</div>
|
||||
|
||||
<div v-if='!loading && lyrics' class='text-center'>
|
||||
<div v-for='(lyric, index) in lyrics.lyrics' :key='lyric.offset' class='my-8 mx-4'>
|
||||
<span
|
||||
class='my-8'
|
||||
:class='{"text-h6 font-weight-regular": !playingNow(index), "text-h5 font-weight-bold": playingNow(index)}'
|
||||
:ref='"l"+index'
|
||||
>
|
||||
{{lyric.text}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-if='!loading && !lyrics' class='pa-4 text-center'>
|
||||
<span class='red--text text-h5'>
|
||||
Error loading lyrics or lyrics not found!
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Lyrics',
|
||||
props: {
|
||||
songId: String,
|
||||
height: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cSongId: this.songId,
|
||||
loading: true,
|
||||
lyrics: null,
|
||||
currentLyricIndex: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Load data from API
|
||||
async load() {
|
||||
this.loading = true;
|
||||
this.lyrics = null;
|
||||
try {
|
||||
|
||||
let res = await this.$axios.get(`/lyrics/${this.songId}`);
|
||||
if (res.data) this.lyrics = res.data;
|
||||
|
||||
} catch (e) {true;}
|
||||
this.loading = false;
|
||||
},
|
||||
//Wether current lyric is playing rn
|
||||
playingNow(i) {
|
||||
if (!this.$root.audio) return false;
|
||||
//First & last lyric check
|
||||
if (i == this.lyrics.lyrics.length - 1) {
|
||||
if (this.lyrics.lyrics[i].offset <= this.$root.position) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.$root.position >= this.lyrics.lyrics[i].offset && this.$root.position < this.lyrics.lyrics[i+1].offset) return true;
|
||||
return false;
|
||||
},
|
||||
//Get index of current lyric
|
||||
currentLyric() {
|
||||
if (!this.$root.audio) return 0;
|
||||
return this.lyrics.lyrics.findIndex((l) => {
|
||||
return this.playingNow(this.lyrics.lyrics.indexOf(l));
|
||||
});
|
||||
},
|
||||
//Scroll to currently playing lyric
|
||||
scrollLyric() {
|
||||
if (!this.lyrics) return;
|
||||
|
||||
//Prevent janky scrolling
|
||||
if (this.currentLyricIndex == this.currentLyric()) return;
|
||||
this.currentLyricIndex = this.currentLyric();
|
||||
|
||||
//Roughly middle
|
||||
let offset = window.innerHeight / 2 - 500;
|
||||
|
||||
this.$refs.content.scrollTo({
|
||||
top: this.$refs["l"+this.currentLyricIndex][0].offsetTop + offset,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
watch: {
|
||||
songId() {
|
||||
//Load on song id change
|
||||
if (this.cSongId != this.songId) {
|
||||
this.cSongId = this.songId;
|
||||
this.load();
|
||||
}
|
||||
},
|
||||
'$root.position'() {
|
||||
this.scrollLyric();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue