Files
MusicServer/cmd/frontend/src/components/layout/TheFooter.vue
2023-08-19 17:13:23 +02:00

441 lines
15 KiB
Vue

<template>
<footer>
<div class="audioAndButtonsDiv">
<div class="audioButtonsDiv">
<button
class="bigButton"
:class="{ disabled: disableButtons }"
:disabled="disableButtons"
@click="randomizeTrack()"
>
<p v-if="!disableButtons"><u>R</u>andomize new track</p>
<p v-else>Loading...</p>
</button>
<button class="bigButton" @click="showAnswer()"><u>S</u>how answer</button>
</div>
<div class="audioDiv">
<audio
controls
class="audioPlayer"
:src="currentTrackSrcFile"
ref="audioPlayer"
:onended="trackHasEnded"
></audio>
</div>
</div>
</footer>
</template>
<script>
import { mapState } from "vuex";
import arne from "../../arne.js";
export default {
data() {
return {
currentTrackSrcFile: "",
disableButtons: false,
loadingBar: "",
};
},
computed: {
...mapState([
"stopAfterCurrent",
"localPlaylist",
"hideNextTrack",
"roundStarted",
"specialTrackIsPlaying",
"addPlayed",
"lowPlayed",
]),
},
methods: {
async randomizeTrack() {
console.log("Randomizing track");
/* Prevents anyone from changing the winning score after the round has started */
if (this.roundStarted === false) {
this.$store.dispatch("setRoundStarted", true);
}
let trackAddedToQue = false;
this.disableButtons = true;
let copyOfPlaylist = this.localPlaylist;
//If the local playlist of MP3s is empty, wait for a new track to load
if (copyOfPlaylist.length === 0) {
console.log("No track preloaded, loading a new one");
if (this.lowPlayed) {
await this.APIgetRandomizedLowTrack();
} else {
await this.APIgetRandomizedTrack();
}
if (this.addPlayed) {
await this.APIaddPlayed();
}
await this.APIaddToQue();
trackAddedToQue = true;
}
//Update the source file for the media player (binded property to Audio tag in the template)
this.currentTrackSrcFile = window.URL.createObjectURL(copyOfPlaylist[0]);
if (!trackAddedToQue) {
if (this.addPlayed) {
await this.APIaddPlayed();
}
await this.APIaddToQue();
}
await this.APIgetPlaylistHistory();
this.$refs.audioPlayer.play();
this.$emit("scroll-to-bottom-playlist-history");
copyOfPlaylist.shift();
if (this.hideNextTrack) {
this.$store.dispatch("setCurrentTrackHidden", true);
} else {
this.$store.dispatch("setCurrentTrackHidden", false);
}
await this.APIgetInfoAboutCurrentTrack();
await this.randomizeTrackInAdvance();
this.disableButtons = false;
},
async randomizeTrackInAdvance() {
console.log("Randomizing track in advance");
try {
if (this.lowPlayed) {
await this.APIgetRandomizedLowTrack();
} else {
await this.APIgetRandomizedTrack();
}
} catch (error) {
console.log(error);
console.log("Error: A track couldn't be loaded in advance");
}
return new Promise((resolve) => {
resolve();
});
},
async playSpecificTrack(track) {
await this.APIplaySpecificTrack(track.SongNo);
this.$store.dispatch("setCurrentlyLoadingTrack", "");
await this.APIgetPlaylistHistory();
this.$store.dispatch("setCurrentTrackHidden", false);
await this.APIgetInfoAboutCurrentTrack();
},
showAnswer() {
this.$store.dispatch("setCurrentTrackHidden", false);
},
startSoundTest() {
this.$refs.audioPlayer.pause();
this.currentTrackSrcFile = "sounds/check.mp3";
this.$store.dispatch("setSpecialTrackIsPlaying", true);
this.$nextTick(() => {
this.$refs.audioPlayer.currentTime = 0;
this.$refs.audioPlayer.play();
});
},
playWelcomeSound() {
let randomNumber = Math.floor(Math.random() * 10);
this.$refs.audioPlayer.pause();
if (randomNumber === 0) {
this.currentTrackSrcFile = "sounds/sound1.mp3";
} else if (randomNumber < 5) {
this.currentTrackSrcFile = "sounds/intro_short.mp3";
} else {
this.currentTrackSrcFile = "sounds/intro_long.mp3";
}
this.$store.dispatch("setSpecialTrackIsPlaying", true);
this.$nextTick(() => {
this.$refs.audioPlayer.currentTime = 0;
this.$refs.audioPlayer.play();
});
},
playMatchSound() {
this.$refs.audioPlayer.pause();
this.currentTrackSrcFile = "sounds/sound0.mp3";
this.$store.dispatch("setSpecialTrackIsPlaying", true);
this.$nextTick(() => {
this.$refs.audioPlayer.currentTime = 0;
this.$refs.audioPlayer.play();
});
},
playWinningSound() {
this.$refs.audioPlayer.pause();
this.currentTrackSrcFile = "sounds/winning.mp3";
this.$store.dispatch("setSpecialTrackIsPlaying", true);
this.$nextTick(() => {
this.$refs.audioPlayer.currentTime = 0;
this.$refs.audioPlayer.play();
});
},
APIgetRandomizedTrack() {
return new Promise((resolve, reject) => {
this.axios({
method: "get",
url: `${arne.hostname}/music/rand`,
responseType: "blob",
onDownloadProgress: (progressEvent) => {
let percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
if (percentCompleted % 10 === 0) {
//Debug for slow downloading
//console.log(percentCompleted);
}
},
})
.then((response) => {
let mp3 = new Blob([response.data], { type: "audio/mp3" });
this.$store.dispatch("updateLocalPlaylist", mp3);
this.$nextTick(() => {
resolve();
});
})
.catch(function(error) {
console.log("An error happened when fetching the track");
console.log(error);
reject();
});
});
},
APIgetRandomizedLowTrack() {
return new Promise((resolve, reject) => {
this.axios({
method: "get",
url: `${arne.hostname}/music/rand/low`,
responseType: "blob",
onDownloadProgress: (progressEvent) => {
let percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
if (percentCompleted % 10 === 0) {
//Debug for slow downloading
//console.log(percentCompleted);
}
},
})
.then((response) => {
let mp3 = new Blob([response.data], { type: "audio/mp3" });
this.$store.dispatch("updateLocalPlaylist", mp3);
this.$nextTick(() => {
resolve();
});
})
.catch(function(error) {
console.log("An error happened when fetching the track");
console.log(error);
reject();
});
});
},
APIaddPlayed() {
return new Promise((resolve, reject) => {
this.axios({
method: "get",
url: `${arne.hostname}/music/addPlayed`,
})
.then(() => {
resolve(false);
})
.catch(function(error) {
console.log(error);
reject();
});
});
},
APIaddToQue() {
return new Promise((resolve, reject) => {
this.axios({
method: "get",
url: `${arne.hostname}/music/addQue`,
})
.then(() => {
resolve(false);
})
.catch(function(error) {
console.log(error);
reject();
});
});
},
APIgetInfoAboutCurrentTrack() {
return new Promise((resolve, reject) => {
this.axios({
method: "get",
url: `${arne.hostname}/music/info`,
})
.then((response) => {
let gameInfoObject = {
game: response.data.Game,
track: response.data.Song.replace(".mp3", ""),
songNo: response.data.SongNo,
};
this.$store.dispatch("setCurrentGame", gameInfoObject.game);
this.$store.dispatch("setCurrentTrack", gameInfoObject.track);
resolve(false);
})
.catch(function(error) {
console.log(error);
reject();
});
});
},
APIgetPlaylistHistory() {
return new Promise((resolve, reject) => {
this.axios({
method: "get",
url: `${arne.hostname}/music/list`,
})
.then((response) => {
let tracklistArray = response.data;
this.$store.dispatch("updatePlaylistHistory", tracklistArray);
resolve();
})
.catch(function(error) {
console.log(error);
reject();
});
});
},
APIplaySpecificTrack(trackNumber) {
return new Promise((resolve, reject) => {
this.axios({
method: "get",
url: `${arne.hostname}/music?song=${trackNumber}`,
responseType: "blob",
})
.then((response) => {
let mp3 = new Blob([response.data], { type: "audio/mp3" });
this.currentTrackSrcFile = window.URL.createObjectURL(mp3);
this.$nextTick(() => {
this.$refs.audioPlayer.play();
resolve();
});
})
.catch(function(error) {
console.log(error);
reject();
});
});
},
trackHasEnded() {
if (this.specialTrackIsPlaying) {
this.$store.dispatch("setSpecialTrackIsPlaying", false);
return 0;
}
if (!this.stopAfterCurrent) {
this.randomizeTrack();
}
},
},
async mounted() {
await this.APIgetPlaylistHistory();
},
};
</script>
<style scoped>
footer {
display: flex;
position: absolute;
bottom: 0;
justify-content: flex-end;
width: 100%;
}
.audioAndButtonsDiv {
display: flex;
flex-wrap: wrap;
width: 80vw;
margin-right: 1vh;
}
.audioButtonsDiv {
display: flex;
flex-direction: row-reverse;
width: 100%;
margin-bottom: 2vh;
align-items: center;
}
.audioButtonsDiv button:nth-child(1) {
margin-right: 3vw;
width: 200px;
}
.audioButtonsDiv button:nth-child(2) {
margin-right: 25vw;
width: 220px;
}
.audioButtonsDiv .bigButton {
height: 7vh;
}
.disabled {
opacity: 0.5;
}
.audioDiv {
width: 100%;
}
.audioDiv audio {
width: 100%;
font-size: 2rem;
}
audio::-webkit-media-controls-panel {
background-color: rgb(185, 185, 185);
}
audio::-webkit-media-controls-current-time-display {
color: rgb(0, 0, 0);
font-size: 4em;
}
audio::-webkit-media-controls-time-remaining-display {
color: rgb(0, 0, 0);
font-size: 4em;
}
@media only screen and (max-width: 1000px) {
footer {
position: static;
justify-content: center;
}
.audioAndButtonsDiv {
width: 100vw;
margin: 0;
}
.audioButtonsDiv {
margin-bottom: 2vw;
font-size: 1rem;
}
.audioButtonsDiv button:nth-child(1) {
margin: 0;
width: 50vw;
border-radius: 2px;
}
.audioButtonsDiv button:nth-child(2) {
margin: 0;
width: 50vw;
border-radius: 2px;
}
.audioButtonsDiv .bigButton {
height: 22vw;
}
.disabled {
opacity: 0.5;
}
.audioDiv {
width: 100%;
}
.audioDiv audio {
font-size: 1rem;
}
audio::-webkit-media-controls-panel {
background-color: rgb(185, 185, 185);
border-radius: 2px;
}
audio::-webkit-media-controls-current-time-display {
color: rgb(0, 0, 0);
font-size: 2em;
}
audio::-webkit-media-controls-time-remaining-display {
color: rgb(0, 0, 0);
font-size: 2em;
}
}
</style>