save-and-restore-progress-for-audio fix #10 #16

Merged
artem merged 8 commits from save-and-restore-progress-for-audio into main 2023-09-19 16:34:57 +02:00
4 changed files with 100 additions and 55 deletions
Showing only changes of commit 239b538c4b - Show all commits

View File

@ -1,5 +1,5 @@
{ {
"backend_de": "http://localhost:31204", "backend_dev": "http://localhost:31204",
"backend_dev": "https://webplay.rocks", "backend_de": "https://webplay.rocks",
"backend": "https://webplay.rocks" "backend": "https://webplay.rocks"
} }

View File

@ -48,7 +48,7 @@ export default {
duration: 0, duration: 0,
progress: 0, progress: 0,
intervalProgress: 0, intervalProgress: 0,
intervalHistory: 0, intervalState: 0,
preConvert: false, preConvert: false,
}; };
}, },
@ -68,25 +68,27 @@ export default {
this.audio.pause(); this.audio.pause();
window.clearInterval(this.intervalProgress); window.clearInterval(this.intervalProgress);
window.clearInterval(this.intervalHistory); window.clearInterval(this.intervalState);
this.progress = this.audio.currentTime; this.pushState();
}, },
durationChanged() { durationChanged() {
this.duration = this.audio.duration; this.duration = this.audio.duration;
}, },
playing() { playing() {
window.clearInterval(this.intervalProgress); window.clearInterval(this.intervalProgress);
window.clearInterval(this.intervalHistory); window.clearInterval(this.intervalState);
this.intervalProgress = setInterval(() => { this.intervalProgress = setInterval(() => {
this.progress = this.audio.currentTime; this.progress = this.audio.currentTime;
this.selectedTrack.percent = (100 / this.duration) * this.progress; this.selectedTrack.percent = (100 / this.duration) * this.progress;
}, 500); }, 500);
this.intervalHistory = setInterval(() => { if (this.currentUser._id) {
console.log(this.selectedTrack); this.intervalState = setInterval(() => {
}, 10000); this.pushState();
}, 10000);
}
}, },
audioReset() { audioReset() {
this.audio.pause(); this.audio.pause();
@ -107,6 +109,14 @@ export default {
this.audio.play(); this.audio.play();
} }
}, },
skipToSecond(second) {
let was_paused = this.audio.paused;
this.audio.pause();
this.audio.currentTime = second;
if (!was_paused) {
this.audio.play();
}
},
playRadio(radio) { playRadio(radio) {
this.$store.commit("tracks/resetSelectedTrack"); this.$store.commit("tracks/resetSelectedTrack");
this.audio.pause(); this.audio.pause();
@ -135,8 +145,12 @@ export default {
this.pushHistoryItem(); this.pushHistoryItem();
// Try to fix SAFARI if (this.selectedTrack.parent.progress) {
this.audio.play(); this.skipToSecond(this.selectedTrack.parent.progress.progress);
} else {
// Try to fix SAFARI
this.audio.play();
}
}, },
pushHistoryItem() { pushHistoryItem() {
if (!this.currentUser._id) { if (!this.currentUser._id) {
@ -190,7 +204,7 @@ export default {
}, },
reset() { reset() {
window.clearInterval(this.intervalProgress); window.clearInterval(this.intervalProgress);
window.clearInterval(this.intervalHistory); window.clearInterval(this.intervalState);
if (!this.audio.paused) { if (!this.audio.paused) {
this.audio.pause(); this.audio.pause();
} }
@ -251,6 +265,19 @@ export default {
} }
this.$store.dispatch("user/savePlayerSettings"); this.$store.dispatch("user/savePlayerSettings");
}, },
pushState() {
if (!this.currentUser._id) {
return;
}
this.progress = this.audio.currentTime;
let item = {
id: this.selectedTrack._id,
parentId: this.selectedTrack.parent._id,
type: "track",
progress: Math.round(this.progress)
}
this.$store.dispatch("user/saveProgress", item);
},
timeUpdate(event) { timeUpdate(event) {
let percent = (event.target.currentTime / event.target.duration) * 100; let percent = (event.target.currentTime / event.target.duration) * 100;
if (percent > 10 && !this.preConvert) { if (percent > 10 && !this.preConvert) {

View File

@ -1,25 +1,12 @@
<template> <template>
<DialogBase <DialogBase ref="dialogWindow" :title="album_title" @canceled="closed" :showFooter="false" :disableXscroll="true" :disableYscroll="true">
ref="dialogWindow"
:title="album_title"
@canceled="closed"
:showFooter="false"
:disableXscroll="true"
:disableYscroll="true"
>
<div id="albumViewer" class="flex-row"> <div id="albumViewer" class="flex-row">
<div id="header" class="flex-column"> <div id="header" class="flex-column">
<div id="background" :style="coverBackground" /> <div id="background" :style="coverBackground" />
<div class="grow z1 center flex-column"> <div class="grow z1 center flex-column">
<img class="glow ma24" :src="cover" @dblclick="dblclick" /> <img class="glow ma24" :src="cover" @dblclick="dblclick" />
</div> </div>
<awesome-icon <awesome-icon icon="star" size="2x" class="favourite ma4" :class="{ active: isFavourite }" @click="toggleFavourite" />
icon="star"
size="2x"
class="favourite ma4"
:class="{ active: isFavourite }"
@click="toggleFavourite"
/>
<div id="stats" class="flex-row z1"> <div id="stats" class="flex-row z1">
<DropDown v-if="$store.getters['user/isAdministrator']"> <DropDown v-if="$store.getters['user/isAdministrator']">
<button class="flat center" :title="visibility_text"> <button class="flat center" :title="visibility_text">
@ -27,11 +14,7 @@
</button> </button>
<template v-slot:dropdown-content> <template v-slot:dropdown-content>
<div> <div>
<button <button v-for="(item, i) in $store.state.system.lists.visibility" :key="i" @click="setVisibility(item)">
v-for="(item, i) in $store.state.system.lists.visibility"
:key="i"
@click="setVisibility(item)"
>
<awesome-icon :icon="getVisibilityIcon(item)" />{{ <awesome-icon :icon="getVisibilityIcon(item)" />{{
getVisibilityText(item) getVisibilityText(item)
}} }}
@ -40,10 +23,7 @@
<button v-if="!selectedAlbum.share._id" @click="shareEnable"> <button v-if="!selectedAlbum.share._id" @click="shareEnable">
<awesome-icon icon="share" />Share this album <awesome-icon icon="share" />Share this album
</button> </button>
<button <button v-if="selectedAlbum.share._id" @click="addShareUrlToClipboard">
v-if="selectedAlbum.share._id"
@click="addShareUrlToClipboard"
>
<awesome-icon icon="clipboard" />Copy url into clipboard <awesome-icon icon="clipboard" />Copy url into clipboard
</button> </button>
<button v-if="selectedAlbum.share._id" @click="shareDisable"> <button v-if="selectedAlbum.share._id" @click="shareDisable">
@ -61,8 +41,7 @@
}}</b> }}</b>
<br /> <br />
<span v-if="album_year"> <span v-if="album_year">
from year <b>{{ album_year }}</b> </span from year <b>{{ album_year }}</b> </span><br />
><br />
<b>{{ album_tracks.length }}</b> Tracks with a duration of <b>{{ album_tracks.length }}</b> Tracks with a duration of
<b>{{ album_duration }}</b> <b>{{ album_duration }}</b>
</span> </span>
@ -89,6 +68,7 @@
</DropDown> </DropDown>
</div> </div>
</div> </div>
<p v-if="selectedAlbum.progress" @click="playProgress">Progress</p>
<ul id="trackList" class="tracks"> <ul id="trackList" class="tracks">
<li v-for="track in selectedAlbum.tracks" :key="track._id"> <li v-for="track in selectedAlbum.tracks" :key="track._id">
@ -156,6 +136,14 @@ export default {
} }
} }
}, },
playProgress() {
let track = this.selectedAlbum.tracks.find(
(f) => f._id == this.selectedAlbum.progress.id
);
if (track) {
this.$store.dispatch("tracks/play", track);
}
},
closed() { closed() {
if ( if (
(window.history.state.back && (window.history.state.back &&
@ -201,19 +189,19 @@ export default {
return visibility == "global" return visibility == "global"
? "globe" ? "globe"
: visibility == "instance" : visibility == "instance"
? "server" ? "server"
: visibility == "hidden" : visibility == "hidden"
? "eye-slash" ? "eye-slash"
: "user"; : "user";
}, },
getVisibilityText(visibility) { getVisibilityText(visibility) {
return visibility == "global" return visibility == "global"
? "Global" ? "Global"
: visibility == "instance" : visibility == "instance"
? "On this server" ? "On this server"
: visibility == "hidden" : visibility == "hidden"
? "Hide this Album" ? "Hide this Album"
: "Only for me"; : "Only for me";
}, },
selectAlbum(album) { selectAlbum(album) {
this.$store.dispatch("albums/selectAlbum", album); this.$store.dispatch("albums/selectAlbum", album);
@ -228,6 +216,9 @@ export default {
shareDisable() { shareDisable() {
this.$store.dispatch("albums/shareDisable", this.selectedAlbum); this.$store.dispatch("albums/shareDisable", this.selectedAlbum);
}, },
loadUserProgress() {
this.$store.dispatch("user/getProgress", this.selectedAlbum);
}
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
@ -287,19 +278,19 @@ export default {
return this.selectedAlbum.visibility == "global" return this.selectedAlbum.visibility == "global"
? "globe" ? "globe"
: this.selectedAlbum.visibility == "instance" : this.selectedAlbum.visibility == "instance"
? "server" ? "server"
: this.selectedAlbum.visibility == "hidden" : this.selectedAlbum.visibility == "hidden"
? "eye-slash" ? "eye-slash"
: "user"; : "user";
}, },
visibility_text() { visibility_text() {
return this.selectedAlbum.visibility == "global" return this.selectedAlbum.visibility == "global"
? "Visible for the whole world" ? "Visible for the whole world"
: this.selectedAlbum.visibility == "instance" : this.selectedAlbum.visibility == "instance"
? "Visible on this instance" ? "Visible on this instance"
: this.selectedAlbum.visibility == "hidden" : this.selectedAlbum.visibility == "hidden"
? "Hidden for all users" ? "Hidden for all users"
: "Visible only for me"; : "Visible only for me";
}, },
isFavourite() { isFavourite() {
return ( return (
@ -318,6 +309,7 @@ export default {
this.$refs.dialogWindow.open(); this.$refs.dialogWindow.open();
window.addEventListener("keydown", this.keydownListener); window.addEventListener("keydown", this.keydownListener);
} }
this.loadUserProgress();
this.gotoTrack(); this.gotoTrack();
} else { } else {
if (this.$refs.dialogWindow.visible) { if (this.$refs.dialogWindow.visible) {
@ -339,14 +331,17 @@ export default {
height: 366px; height: 366px;
width: 640px; width: 640px;
} }
#header { #header {
position: relative; position: relative;
background-color: black; background-color: black;
} }
#header img { #header img {
align-self: center; align-self: center;
width: 256px; width: 256px;
} }
#stats { #stats {
z-index: 2; z-index: 2;
align-items: center; align-items: center;
@ -357,10 +352,12 @@ export default {
border-top: 1px solid #ffffff20; border-top: 1px solid #ffffff20;
border-bottom: 1px solid #00000020; border-bottom: 1px solid #00000020;
} }
.dropdown-activator button { .dropdown-activator button {
width: 32px; width: 32px;
height: 32px; height: 32px;
} }
#trackList { #trackList {
background-color: var(--white); background-color: var(--white);
z-index: 1; z-index: 1;
@ -370,15 +367,19 @@ export default {
#header { #header {
width: 100%; width: 100%;
} }
#albumViewer { #albumViewer {
flex-direction: column; flex-direction: column;
} }
} }
@media (max-width: 480px), (max-height: 480px) {
@media (max-width: 480px),
(max-height: 480px) {
#albumViewer { #albumViewer {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
#trackList { #trackList {
height: initial; height: initial;
flex-grow: 1; flex-grow: 1;

View File

@ -80,6 +80,23 @@ export default {
context.commit("setHistory", res.data); context.commit("setHistory", res.data);
}); });
}, },
saveProgress(context, item) {
if (context.state._id == -1) {
return;
}
axios.post(context.rootGetters.server + "/api/user/progress", item, context.rootGetters.headers);
},
getProgress(context, parent) {
if (context.state._id == -1) {
return;
}
axios
.get(context.rootGetters.server + "/api/user/progress/" + parent._id, context.rootGetters.headers)
.then((res) => {
parent.progress = res.data;
});
},
savePlayerSettings(context) { savePlayerSettings(context) {
let body = { let body = {
repeat: context.rootGetters["player/repeatType"], repeat: context.rootGetters["player/repeatType"],