main #19

Merged
artem merged 39 commits from main into dev 2023-09-22 14:13:12 +02:00
6 changed files with 194 additions and 192 deletions
Showing only changes of commit 44497c4429 - 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

@ -95,6 +95,14 @@ td.fillCell>* {
color: var(--yellow); color: var(--yellow);
} }
.keepPlaying {
z-index: 1;
position: absolute;
cursor: pointer;
right: 0;
}
/* /*
DIALOGS DIALOGS
*/ */

View File

@ -1,26 +1,9 @@
<template> <template>
<div <div id="player" class="flex-column" v-show="selectedTrack._id || selectedRadio._id">
id="player" <input type="range" id="slider" min="0" max="100" step="0.1" v-model="selectedTrack.percent" @change="slideChanged" />
class="flex-column"
v-show="selectedTrack._id || selectedRadio._id"
>
<input
type="range"
id="slider"
min="0"
max="100"
step="0.1"
v-model="selectedTrack.percent"
@change="slideChanged"
/>
<div id="playerBar" class="flex-row"> <div id="playerBar" class="flex-row">
<div class="flex-row grow"> <div class="flex-row grow">
<img <img class="cover pointer" :src="cover" :title="selectedTrack.parent.title" @click="gotoContainer" />
class="cover pointer"
:src="cover"
:title="selectedTrack.parent.title"
@click="gotoContainer"
/>
<div v-if="selectedTrack._id" class="flex-column"> <div v-if="selectedTrack._id" class="flex-column">
<b>{{ selectedTrack.title }}</b> <b>{{ selectedTrack.title }}</b>
from from
@ -28,21 +11,9 @@
</div> </div>
</div> </div>
<div id="playerControls" class="flex-row center"> <div id="playerControls" class="flex-row center">
<button <button @click="switchShuffle" title="Shuffle mode" v-if="selectedTrack._id">
@click="switchShuffle" <img src="static/icons/media-shuffle-dark.svg" v-show="$store.getters['player/shuffle']" class="small" />
title="Shuffle mode" <img src="static/icons/media-consecutive-dark.svg" v-show="$store.getters['player/shuffle'] == false" class="small" />
v-if="selectedTrack._id"
>
<img
src="static/icons/media-shuffle-dark.svg"
v-show="$store.getters['player/shuffle']"
class="small"
/>
<img
src="static/icons/media-consecutive-dark.svg"
v-show="$store.getters['player/shuffle'] == false"
class="small"
/>
</button> </button>
<button @click="prevTrack" title="Back" v-if="selectedTrack._id"> <button @click="prevTrack" title="Back" v-if="selectedTrack._id">
<awesome-icon icon="backward" /> <awesome-icon icon="backward" />
@ -54,46 +25,17 @@
<button @click="nextTrack" title="Forward" v-if="selectedTrack._id"> <button @click="nextTrack" title="Forward" v-if="selectedTrack._id">
<awesome-icon icon="forward" /> <awesome-icon icon="forward" />
</button> </button>
<button <button @click="switchRepeatType" title="Repeat mode" v-if="selectedTrack._id">
@click="switchRepeatType" <img src="static/icons/media-repeat-dark.svg" class="small" v-show="$store.getters['player/repeatType'] == 'all'" />
title="Repeat mode" <img src="static/icons/media-repeat-song-dark.svg" class="small" v-show="$store.getters['player/repeatType'] == 'one'" />
v-if="selectedTrack._id" <img src="static/icons/media-no-repeat-dark.svg" class="small" v-show="$store.getters['player/repeatType'] == 'none'" />
>
<img
src="static/icons/media-repeat-dark.svg"
class="small"
v-show="$store.getters['player/repeatType'] == 'all'"
/>
<img
src="static/icons/media-repeat-song-dark.svg"
class="small"
v-show="$store.getters['player/repeatType'] == 'one'"
/>
<img
src="static/icons/media-no-repeat-dark.svg"
class="small"
v-show="$store.getters['player/repeatType'] == 'none'"
/>
</button> </button>
</div> </div>
<div <div class="flex-row ma-right hideOnMobilePortrait grow right" v-show="selectedTrack.title">
class="flex-row ma-right hideOnMobilePortrait grow right"
v-show="selectedTrack.title"
>
{{ formatedP }}&nbsp;|&nbsp;{{ formatedD }} {{ formatedP }}&nbsp;|&nbsp;{{ formatedD }}
</div> </div>
</div> </div>
<audio <audio preload="auto" ref="audioControl" type="audio/mpeg" @ended="nextTrack" @canplay="play" @playing="playing" @durationchange="durationChanged" @timeupdate="timeUpdate" src></audio>
preload="auto"
ref="audioControl"
type="audio/mpeg"
@ended="nextTrack"
@canplay="play"
@playing="playing"
@durationchange="durationChanged"
@timeupdate="timeUpdate"
src
></audio>
</div> </div>
</template> </template>
@ -105,7 +47,8 @@ export default {
audio: {}, audio: {},
duration: 0, duration: 0,
progress: 0, progress: 0,
interval: 0, intervalProgress: 0,
intervalState: 0,
preConvert: false, preConvert: false,
}; };
}, },
@ -121,21 +64,31 @@ export default {
play() { play() {
this.audio.play(); this.audio.play();
}, },
pause() { pause() {
if (!this.audio.paused) { this.audio.pause();
this.audio.pause();
} window.clearInterval(this.intervalProgress);
window.clearInterval(this.intervalState);
this.pushState();
}, },
durationChanged() { durationChanged() {
this.duration = this.audio.duration; this.duration = this.audio.duration;
}, },
playing() { playing() {
window.clearInterval(this.interval); window.clearInterval(this.intervalProgress);
this.interval = setInterval(() => { window.clearInterval(this.intervalState);
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);
if (this.currentUser._id) {
this.intervalState = setInterval(() => {
this.pushState();
}, 10000);
}
}, },
audioReset() { audioReset() {
this.audio.pause(); this.audio.pause();
@ -156,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();
@ -184,8 +145,13 @@ export default {
this.pushHistoryItem(); this.pushHistoryItem();
// Try to fix SAFARI if (this.currentTrackParent.progress) {
this.audio.play(); this.skipToSecond(this.currentTrackParent.progress.progress);
this.currentTrackParent.progress = undefined;
} else {
// Try to fix SAFARI
this.audio.play();
}
}, },
pushHistoryItem() { pushHistoryItem() {
if (!this.currentUser._id) { if (!this.currentUser._id) {
@ -232,13 +198,20 @@ export default {
return; return;
} }
if (!this.audio.paused) { if (!this.audio.paused) {
this.audio.pause(); this.pause();
} else if (this.audio.src != "") { } else if (this.audio.src != "") {
this.audio.play(); this.audio.play();
} }
}, },
reset() { reset(item) {
window.clearInterval(this.interval); let parentId = item.parent._id;
if (item.parent.parent && item.parent.parent.tracks) {
parentId = item.parent.parent._id;
}
this.$store.dispatch("user/resetProgress", parentId);
window.clearInterval(this.intervalProgress);
window.clearInterval(this.intervalState);
if (!this.audio.paused) { if (!this.audio.paused) {
this.audio.pause(); this.audio.pause();
} }
@ -299,6 +272,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.currentTrackParent._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) {
@ -390,11 +376,11 @@ export default {
this.reset(); this.reset();
} }
}, },
selectedTrack(newVal) { selectedTrack(newVal, oldVal) {
if (newVal._id) { if (newVal._id) {
this.playTrack(newVal); this.playTrack(newVal);
} else { } else {
this.reset(); this.reset(oldVal);
} }
}, },
}, },
@ -409,17 +395,21 @@ export default {
z-index: 1001; z-index: 1001;
box-shadow: 0 0px 4px var(--shadow); box-shadow: 0 0px 4px var(--shadow);
} }
#player .cover { #player .cover {
width: 52px; width: 52px;
margin-right: 4px; margin-right: 4px;
} }
#playerBar { #playerBar {
overflow: hidden; overflow: hidden;
max-height: 52px; max-height: 52px;
} }
#playerBar > div {
#playerBar>div {
align-items: center; align-items: center;
} }
#playerControls button { #playerControls button {
display: flex; display: flex;
padding: 4px 12px; padding: 4px 12px;

View File

@ -1,25 +1,13 @@
<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" title="Favourite" />
icon="star" <awesome-icon icon="play" size="2x" class="keepPlaying ma4 primary-text" @click="playProgress" v-if="selectedAlbum.progress" title="Keep playing" />
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 +15,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 +24,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 +42,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,7 +69,6 @@
</DropDown> </DropDown>
</div> </div>
</div> </div>
<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">
<TrackItem :track="track" :showCover="false" /> <TrackItem :track="track" :showCover="false" />
@ -156,6 +135,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 +188,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 +215,10 @@ export default {
shareDisable() { shareDisable() {
this.$store.dispatch("albums/shareDisable", this.selectedAlbum); this.$store.dispatch("albums/shareDisable", this.selectedAlbum);
}, },
loadUserProgress() {
if (this.selectedTrack.parent._id != this.selectedAlbum._id)
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

@ -1,24 +1,10 @@
<template> <template>
<DialogBase <DialogBase ref="dialogWindow" id="dialogWindow" :title="selectedArtist.name" @canceled="closed" :showFooter="false" :showFullscreenButton="true" :disableXscroll="true" :disableYscroll="true">
ref="dialogWindow"
id="dialogWindow"
:title="selectedArtist.name"
@canceled="closed"
:showFooter="false"
:showFullscreenButton="true"
:disableXscroll="true"
:disableYscroll="true"
>
<div id="artistViewer"> <div id="artistViewer">
<div id="header" class="flex-column"> <div id="header" class="flex-column">
<div id="background" :style="coverBackground" /> <div id="background" :style="coverBackground" />
<awesome-icon <awesome-icon icon="star" size="2x" class="favourite ma4" :class="{ active: isFavourite }" @click="toggleFavourite" />
icon="star" <awesome-icon icon="play" size="2x" class="keepPlaying ma4 primary-text" @click="playProgress" v-if="selectedArtist.progress" title="Keep playing" />
size="2x"
class="favourite ma4"
:class="{ active: isFavourite }"
@click="toggleFavourite"
/>
<h1 @dblclick="dblclick"> <h1 @dblclick="dblclick">
{{ selectedArtist.name }} {{ selectedArtist.name }}
</h1> </h1>
@ -28,41 +14,20 @@
<b>{{ artist_duration }}</b> <b>{{ artist_duration }}</b>
</span> </span>
<div id="albumList" class="flex-row showOnMobilePortrait"> <div id="albumList" class="flex-row showOnMobilePortrait">
<AlbumItem <AlbumItem class="ma" :class="{ playing: playingAlbumId == album._id }" v-for="album in selectedArtist.albums" :key="album._id" :item="album" @click="scrollToAlbum(album)" @dblclick="playAlbum(album)" />
class="ma"
:class="{ playing: playingAlbumId == album._id }"
v-for="album in selectedArtist.albums"
:key="album._id"
:item="album"
@click="scrollToAlbum(album)"
@dblclick="playAlbum(album)"
/>
</div> </div>
<div id="navigation" class="flex-row center ma-top"> <div id="navigation" class="flex-row center ma-top">
<div class="flex-row grow"></div> <div class="flex-row grow"></div>
<div class="flex-row"> <div class="flex-row">
<button <button @click="gotoPrevArtist" class="primary ma4" :title="prevArtist.name" :disabled="!prevArtist._id">
@click="gotoPrevArtist"
class="primary ma4"
:title="prevArtist.name"
:disabled="!prevArtist._id"
>
<awesome-icon icon="angle-left" class="ma4" /> <awesome-icon icon="angle-left" class="ma4" />
</button> </button>
<button <button @click="gotoNextArtist" class="primary ma4" :title="nextArtist.name" :disabled="!nextArtist._id">
@click="gotoNextArtist"
class="primary ma4"
:title="nextArtist.name"
:disabled="!nextArtist._id"
>
<awesome-icon icon="angle-right" class="ma4" /> <awesome-icon icon="angle-right" class="ma4" />
</button> </button>
</div> </div>
<div class="flex-row grow right center"> <div class="flex-row grow right center">
<DropDown <DropDown v-if="$store.getters['user/isAdministrator']" class="hideOnMobile">
v-if="$store.getters['user/isAdministrator']"
class="hideOnMobile"
>
<button class="flat pa8-left pa8-right"> <button class="flat pa8-left pa8-right">
<awesome-icon icon="ellipsis-v" /> <awesome-icon icon="ellipsis-v" />
</button> </button>
@ -86,23 +51,9 @@
</div> </div>
<div class="flex-row overflow-y"> <div class="flex-row overflow-y">
<div id="albumList" class="flex-column hideOnMobilePortrait"> <div id="albumList" class="flex-column hideOnMobilePortrait">
<AlbumItem <AlbumItem class="ma-top ma-left ma-right" :class="{ playing: playingAlbumId == album._id }" v-for="album in selectedArtist.albums" :key="album._id" :item="album" :id="album._id" :ref="album._id" @click="scrollToAlbum(album)" @dblclick="playAlbum(album)" />
class="ma-top ma-left ma-right"
:class="{ playing: playingAlbumId == album._id }"
v-for="album in selectedArtist.albums"
:key="album._id"
:item="album"
:id="album._id"
:ref="album._id"
@click="scrollToAlbum(album)"
@dblclick="playAlbum(album)"
/>
</div> </div>
<ul <ul id="trackList" class="tracks" :class="{ playing: selectedTrack._id != null }">
id="trackList"
class="tracks"
:class="{ playing: selectedTrack._id != null }"
>
<li v-for="track in selectedArtist.tracks" :key="track._id"> <li v-for="track in selectedArtist.tracks" :key="track._id">
<TrackItem :track="track" :ref="track._id" /> <TrackItem :track="track" :ref="track._id" />
</li> </li>
@ -143,6 +94,14 @@ export default {
} }
} }
}, },
playProgress() {
let track = this.selectedArtist.tracks.find(
(f) => f._id == this.selectedArtist.progress.id
);
if (track) {
this.$store.dispatch("tracks/play", track);
}
},
gotoNextArtist() { gotoNextArtist() {
this.$store.dispatch("artists/gotoNextArtist"); this.$store.dispatch("artists/gotoNextArtist");
}, },
@ -194,6 +153,10 @@ export default {
uploadNewCover() { uploadNewCover() {
this.$store.dispatch("artists/uploadNewCover", this.selectedArtist); this.$store.dispatch("artists/uploadNewCover", this.selectedArtist);
}, },
loadUserProgress() {
if (!this.isPlaying || this.selectedTrack.parent.parent._id != this.selectedArtist._id)
this.$store.dispatch("user/getProgress", this.selectedArtist);
}
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
@ -202,6 +165,7 @@ export default {
selectedArtist: ["artists/selectedArtist"], selectedArtist: ["artists/selectedArtist"],
selectedTrack: ["tracks/selectedTrack"], selectedTrack: ["tracks/selectedTrack"],
favourites: ["user/favourites"], favourites: ["user/favourites"],
isPlaying: ["player/isPlaying"]
}), }),
cover() { cover() {
let covers = this.selectedArtist.covers; let covers = this.selectedArtist.covers;
@ -266,6 +230,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) {
@ -289,6 +254,7 @@ export default {
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
} }
h1, h1,
#stats { #stats {
z-index: 1; z-index: 1;
@ -297,33 +263,40 @@ h1,
color: var(--white); color: var(--white);
text-shadow: 0 1px 2px black; text-shadow: 0 1px 2px black;
} }
#artistImage { #artistImage {
width: 512px; width: 512px;
max-height: 256px; max-height: 256px;
} }
#header { #header {
position: relative; position: relative;
background-color: black; background-color: black;
width: 760px; width: 760px;
max-width: 100%; max-width: 100%;
} }
#albumList { #albumList {
z-index: 1; z-index: 1;
overflow-y: auto; overflow-y: auto;
background-color: var(--white); background-color: var(--white);
} }
#albumList::-webkit-scrollbar { #albumList::-webkit-scrollbar {
display: none; display: none;
} }
#albumList .album:last-child { #albumList .album:last-child {
margin-bottom: 12px; margin-bottom: 12px;
} }
#navigation { #navigation {
z-index: 2; z-index: 2;
background-color: #ffffff40; background-color: #ffffff40;
border-top: 1px solid #ffffff20; border-top: 1px solid #ffffff20;
border-bottom: 1px solid #00000020; border-bottom: 1px solid #00000020;
} }
#trackList { #trackList {
z-index: 1; z-index: 1;
background-color: var(--white); background-color: var(--white);
@ -338,12 +311,15 @@ h1,
width: initial; width: initial;
height: initial; height: initial;
} }
.dialog-body button { .dialog-body button {
color: var(--darkgray); color: var(--darkgray);
} }
.container { .container {
flex-grow: 0; flex-grow: 0;
} }
@media (max-width: 480px) { @media (max-width: 480px) {
#albumList { #albumList {
background-color: initial; background-color: initial;
@ -353,19 +329,21 @@ h1,
} }
} }
@media (max-width: 480px), (max-height: 480px) { @media (max-width: 480px),
(max-height: 480px) {
#artistViewer { #artistViewer {
height: initial; height: initial;
} }
#trackList { #trackList {
width: initial; width: initial;
height: initial; height: initial;
} }
#header { #header {
width: initial; width: initial;
} }
} }
@media (max-height: 480px) { @media (max-height: 480px) {}
}
</style> </style>

View File

@ -80,6 +80,31 @@ 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;
});
},
resetProgress(context, parentId) {
if (context.state._id == -1) {
return;
}
axios
.delete(context.rootGetters.server + "/api/user/progress/" + parentId, context.rootGetters.headers);
},
savePlayerSettings(context) { savePlayerSettings(context) {
let body = { let body = {
repeat: context.rootGetters["player/repeatType"], repeat: context.rootGetters["player/repeatType"],