major refactors

- add album page store
- show loaders in beforeEnter guards
- show bitrate on now playing card
- etc
This commit is contained in:
geoffrey45 2022-04-03 01:03:32 +03:00
parent 0c1e792839
commit dbb27734fe
26 changed files with 300 additions and 245 deletions

View File

@ -7,6 +7,7 @@ from app import api
from app import helpers, cache
from app import functions
from app.lib import albumslib, trackslib
album_bp = Blueprint("album", __name__, url_prefix="")
@ -44,12 +45,18 @@ def get_album_tracks():
return {"songs": songs, "info": album}
@album_bp.route("/album/<title>/<artist>/bio")
@cache.cached()
def get_album_bio(title, artist):
@album_bp.route("/album/bio", methods=["POST"])
def get_album_bio():
"""Returns the album bio for the given album."""
bio = functions.get_album_bio(title, artist)
return {"bio": bio}, 200
data = request.get_json()
print(data)
bio = functions.get_album_bio(data["album"], data["albumartist"])
if bio is not None:
return {"bio": bio}
else:
return {"bio": "No bio found."}, 404
@album_bp.route("/album/artists", methods=["POST"])

View File

@ -21,6 +21,7 @@ def get_all_playlists():
playlists = []
for pl in ppp:
pl.count = len(pl.tracks)
pl.tracks = []
playlists.append(pl)
@ -33,7 +34,7 @@ def create_playlist():
playlist = {
"name": data["name"],
"description": [],
"description": "",
"tracks": [],
"count": 0,
"lastUpdated": 0,
@ -74,6 +75,7 @@ def add_track_to_playlist(playlist_id: str):
def get_single_p_info(playlist_id: str):
for p in api.PLAYLISTS:
if p.playlistid == playlist_id:
p.count = len(p.tracks)
return {"data": p}

View File

@ -4,7 +4,7 @@ Contains all the track routes.
from flask import Blueprint, send_file
from app import instances
from app import instances, api
track_bp = Blueprint("track", __name__, url_prefix="/")
@ -15,7 +15,11 @@ def send_track_file(trackid):
Returns an audio file that matches the passed id to the client.
"""
try:
filepath = instances.songs_instance.get_song_by_id(trackid)["filepath"]
filepath = [
file["filepath"]
for file in api.PRE_TRACKS
if file["_id"]["$oid"] == trackid
][0]
return send_file(filepath, mimetype="audio/mp3")
except FileNotFoundError:
return "File not found", 404

View File

@ -147,7 +147,7 @@ def use_defaults() -> str:
"""
Returns a path to a random image in the defaults directory.
"""
path = str(random.randint(0, 10)) + ".webp"
path = "defaults/" + str(random.randint(0, 20)) + ".webp"
return path
@ -266,14 +266,14 @@ def parse_album_artist_tag(audio):
return albumartist
def parse_album_tag(audio):
def parse_album_tag(audio, full_path: str):
"""
Parses the album tag from an audio file.
"""
try:
album = audio["album"][0]
except (KeyError, IndexError):
album = "Unknown"
album = full_path.split("/")[-1]
return album
@ -339,7 +339,7 @@ def get_tags(fullpath: str) -> dict:
"artists": parse_artist_tag(audio),
"title": parse_title_tag(audio, fullpath),
"albumartist": parse_album_artist_tag(audio),
"album": parse_album_tag(audio),
"album": parse_album_tag(audio, fullpath),
"genre": parse_genre_tag(audio),
"date": parse_date_tag(audio)[:4],
"tracknumber": parse_track_number(audio),
@ -365,16 +365,13 @@ def get_album_bio(title: str, albumartist: str):
response = requests.get(last_fm_url)
data = response.json()
except:
return "None"
return None
try:
bio = data["album"]["wiki"]["summary"].split('<a href="https://www.last.fm/')[0]
except KeyError:
bio = None
if bio is None:
return "None"
return bio

View File

@ -54,3 +54,4 @@ def get_track_by_id(trackid: str) -> models.Track:
for track in api.TRACKS:
if track.trackid == trackid:
return track

View File

@ -60,19 +60,24 @@ def add_track(filepath: str) -> None:
api.TRACKS.append(models.Track(tags))
folder = folderslib.create_folder(tags["folder"])
print(f"💙💙 {tags['folder']}")
print(folder)
if folder not in api.FOLDERS:
api.FOLDERS.append(folder)
print(f"added folder {folder.path}")
def remove_track(filepath: str) -> None:
"""
Removes a track from the music dict.
"""
print(filepath)
fpath = filepath.split("/")[-1]
try:
trackid = instances.songs_instance.get_song_by_path(filepath)["_id"]["$oid"]
except TypeError:
print(f"💙 Watchdog Error: Error removing track {filepath} TypeError")
return
instances.songs_instance.remove_song_by_id(trackid)
@ -81,6 +86,10 @@ def remove_track(filepath: str) -> None:
if track.trackid == trackid:
api.TRACKS.remove(track)
for folder in api.FOLDERS:
if folder.path == filepath.replace(fpath, ""):
api.FOLDERS.remove(folder)
class Handler(PatternMatchingEventHandler):
files_to_process = []

View File

@ -69,6 +69,16 @@ class Album:
self.image = settings.IMG_THUMB_URI + tags["image"]
def get_p_track(ptrack):
for track in api.TRACKS:
if (
track.title == ptrack["title"]
and track.artists == ptrack["artists"]
and ptrack["album"] == track.album
):
return track
def create_playlist_tracks(playlist_tracks: List) -> List[Track]:
"""
Creates a list of model.Track objects from a list of playlist track dicts.
@ -76,13 +86,9 @@ def create_playlist_tracks(playlist_tracks: List) -> List[Track]:
tracks: List[Track] = []
for t in playlist_tracks:
for track in api.TRACKS:
if (
track.title == t["title"]
and track.artists == t["artists"]
and track.album == t["album"]
):
tracks.append(track)
track = get_p_track(t)
if track is not None:
tracks.append(track)
return tracks
@ -96,8 +102,8 @@ class Playlist:
description: str
image: str
tracks: List[Track]
count: int
lastUpdated: int
count: int = 0
"""A list of track objects in the playlist"""
def __init__(self, data):
@ -106,11 +112,9 @@ class Playlist:
self.description = data["description"]
self.image = ""
self.tracks = create_playlist_tracks(data["tracks"])
self.count = len(data["tracks"])
self.lastUpdated = data["lastUpdated"]
@dataclass
class Folder:
name: str

View File

@ -1,4 +1,7 @@
/home/cwilvx/.cache/pypoetry/virtualenvs/musicx_server-jsG71GtA-py3.8/bin/python manage.py
ppath=$(poetry run which python)
$ppath manage.py
#python manage.py

View File

@ -15,7 +15,8 @@
:song="song"
:index="index + 1"
@updateQueue="updateQueue"
@loadAlbum="loadAlbum"
:isPlaying="queue.playing"
:isCurrent="queue.current.trackid == song.trackid"
/>
</div>
</div>
@ -33,7 +34,6 @@ import { useRoute } from "vue-router";
import SongItem from "../shared/SongItem.vue";
import routeLoader from "../../composables/routeLoader.js";
import state from "../../composables/state";
import useQStore from "../../stores/queue";
import { Track } from "../../interfaces";
@ -43,28 +43,29 @@ const queue = useQStore();
const props = defineProps<{
tracks: Track[];
path?: string;
pname?: string;
playlistid?: string;
}>();
let route = useRoute().name;
console.log(route);
const search_query = state.search_query;
function updateQueue(song: Track) {
function updateQueue(track: Track) {
switch (route) {
// check which route the play request come from
case "FolderView":
queue.playFromFolder(props.path, props.tracks, song);
queue.playFromFolder(props.path, props.tracks);
queue.play(track);
break;
case "AlbumView":
queue.playFromAlbum(track.album, track.albumartist, props.tracks);
queue.play(track);
break;
case "PlaylistView":
queue.playFromPlaylist(props.pname, props.playlistid, props.tracks);
queue.play(track);
break;
}
// perks.updateQueue(song, type);
}
function loadAlbum(title, albumartist) {
routeLoader.toAlbum(title, albumartist);
}
</script>

View File

@ -2,6 +2,20 @@
<div class="info">
<div class="desc">
<div>
<div class="art">
<div
class="l-image image rounded"
:style="{
backgroundImage: `url(&quot;${track.image}&quot;)`,
}"
></div>
</div>
<div id="bitrate">
<span v-if="track.bitrate > 330"
>FLAC {{ track.bitrate }}</span
>
<span v-else>MP3 | {{ track.bitrate }}</span>
</div>
<div class="title ellip">{{ props.track.title }}</div>
<div class="separator no-border"></div>
<div class="artists ellip" v-if="props.track.artists[0] !== ''">

View File

@ -4,15 +4,6 @@
<div class="button menu image rounded"></div>
<div class="separator no-border"></div>
<div>
<div class="art">
<div
class="l-image image rounded"
:style="{
backgroundImage: `url(&quot;${queue.current.image}&quot;)`,
}"
></div>
</div>
<div class="separator no-border"></div>
<SongCard :track="queue.current" />
<Progress :seek="queue.seek" :pos="queue.current_time" />
<HotKeys
@ -81,6 +72,7 @@ const queue = useQStore();
width: 100%;
display: grid;
place-items: center;
margin-bottom: $small;
.l-image {
height: 12rem;
@ -88,6 +80,18 @@ const queue = useQStore();
}
}
#bitrate {
position: absolute;
font-size: 0.75rem;
width: max-content;
padding: 0.2rem;
top: 13.25rem;
left: 1.5rem;
background-color: $black;
border-radius: $smaller;
box-shadow: 0rem 0rem 1rem rgba(0, 0, 0, 0.438);
}
.title {
font-weight: 900;
}

View File

@ -58,12 +58,13 @@ export default {
<style lang="scss">
.f-artists {
height: 15.5em;
height: 14.5em;
width: calc(100%);
padding: $small;
padding-bottom: 0;
border-radius: $small;
user-select: none;
background: linear-gradient(58deg, $gray 0%, rgba(5, 0, 7, 0.5) 100%);
background: linear-gradient(0deg, transparent, $black);
position: relative;
.header {
@ -75,7 +76,8 @@ export default {
.headin {
font-size: 1.5rem;
font-weight: 900;
display: flex;
// border: solid;
margin-left: $small;
}
}
}

View File

@ -1,12 +1,12 @@
<template>
<div class="p-header">
<div class="carddd circular">
<div class="carddd">
<div class="type"> Playlist</div>
<div class="title ellip">{{ props.info.name }}</div>
<div class="desc">
{{ props.info.desc[0] }}
</div>
<div class="duration rounded">4 Tracks 3 Hours</div>
<div class="duration">4 Tracks 3 Hours</div>
<div class="btns">
<PlayBtnRect />
</div>
@ -77,6 +77,7 @@ const props = defineProps<{
width: 25rem;
padding: 1rem;
background-color: rgba(5, 4, 4, 0.829);
border-radius: .75rem;
.type {
color: rgba(255, 255, 255, 0.692);
@ -85,6 +86,7 @@ const props = defineProps<{
.title {
font-size: 2.5rem;
font-weight: 900;
text-transform: capitalize;
}
.desc {
@ -105,6 +107,7 @@ const props = defineProps<{
padding: $smaller;
border: solid 1px $gray1;
user-select: none;
border-radius: $smaller;
}
.btns {

View File

@ -14,9 +14,11 @@
<p class="title ellip">{{ queue.next.title }}</p>
<hr />
<p class="artist ellip">
<span v-for="artist in putCommas(queue.next.artists)" :key="artist">{{
artist
}}</span>
<span
v-for="artist in putCommas(queue.next.artists)"
:key="artist"
>{{ artist }}</span
>
</p>
</div>
</div>
@ -37,10 +39,11 @@
<script setup lang="ts">
import perks from "../../composables/perks.js";
import { ref } from "@vue/reactivity";
import TrackItem from "../shared/TrackItem.vue";
import useQStore from "../../stores/queue";
import { Track } from "../../interfaces.js";
import { onBeforeMount } from "vue";
const queue = useQStore();
const putCommas = perks.putCommas;

View File

@ -8,6 +8,8 @@
v-for="track in props.tracks"
:key="track.trackid"
:track="track"
:isPlaying="queue.playing"
:isCurrent="queue.current.trackid == track.trackid"
/>
</tbody>
</table>
@ -19,9 +21,10 @@
<script setup>
import LoadMore from "./LoadMore.vue";
import TrackItem from "../shared/TrackItem.vue";
import useQStore from "../../stores/queue";
let counter = 0;
const queue = useQStore();
const props = defineProps({
tracks: {
type: Object,

View File

@ -7,7 +7,7 @@
<div class="image rounded"></div>
<div class="bottom">
<div class="name ellip">{{ props.playlist.name }}</div>
<div class="count">N Tracks</div>
<div class="count">{{ props.playlist.count }} Tracks</div>
</div>
</router-link>
</template>
@ -23,21 +23,35 @@ const props = defineProps<{
<style lang="scss">
.p-card {
width: 100%;
background-color: $gray;
background: $gray;
padding: $small;
transition: all 0.2s ease;
&:hover {
background-color: $accent;
.bottom > .count {
color: $white;
}
}
.image {
min-width: 100%;
height: 10rem;
background-image: url("../../assets/images/eggs.jpg");
background-size: auto 10rem;
transition: all 0.2s ease;
}
.bottom {
margin-top: $small;
.name {
text-transform: capitalize;
}
.count {
font-size: $medium;
color: $red;
color: $indigo;
}
}
}

View File

@ -1,10 +1,7 @@
<template>
<div
class="songlist-item rounded"
:class="[
{ current: current.trackid === props.song.trackid },
{ 'context-on': context_on },
]"
:class="[{ current: props.isCurrent }, { 'context-on': context_on }]"
@dblclick="emitUpdate(props.song)"
@contextmenu="showContextMenu"
>
@ -17,8 +14,8 @@
>
<div
class="now-playing-track image"
v-if="current.trackid === props.song.trackid"
:class="{ active: is_playing, not_active: !is_playing }"
v-if="props.isPlaying && props.isCurrent"
:class="{ active: isPlaying, not_active: !isPlaying }"
></div>
</div>
<div @click="emitUpdate(props.song)">
@ -46,14 +43,20 @@
<span class="artist">{{ props.song.albumartist }}</span>
</div>
</div>
<div class="song-album">
<div
class="album ellip"
@click="emitLoadAlbum(props.song.album, props.song.albumartist)"
>
<router-link
class="song-album"
:to="{
name: 'AlbumView',
params: {
album: props.song.album,
artist: props.song.albumartist,
},
}"
>
<div class="album ellip">
{{ props.song.album }}
</div>
</div>
</router-link>
<div class="song-duration">
{{ perks.formatSeconds(props.song.length) }}
</div>
@ -62,7 +65,6 @@
<script setup lang="ts">
import perks from "../../composables/perks.js";
import state from "../../composables/state";
import useContextStore from "../../stores/context";
import useModalStore from "../../stores/modal";
@ -72,7 +74,6 @@ import { Track } from "../../interfaces.js";
const contextStore = useContextStore();
const modalStore = useModalStore();
const context_on = ref(false);
const showContextMenu = (e: Event) => {
@ -92,23 +93,17 @@ const showContextMenu = (e: Event) => {
const props = defineProps<{
song: Track;
index: Number;
isPlaying: Boolean;
isCurrent: Boolean;
}>();
const emit = defineEmits<{
(e: "updateQueue", song: Track): void;
(e: "loadAlbum", album: string, artist: string): void;
}>();
function emitUpdate(track: Track) {
emit("updateQueue", track);
}
function emitLoadAlbum(title: string, artist: string) {
emit("loadAlbum", title, artist);
}
const is_playing = state.is_playing;
const current = state.current;
</script>
<style lang="scss">

View File

@ -1,63 +0,0 @@
import axios from "axios";
import state from "./state";
const getAlbumTracks = async (album, artist) => {
let data = {};
await axios
.post(state.settings.uri + "/album/tracks", {
album: album,
artist: artist,
})
.then((res) => {
data = res.data;
})
.catch((err) => {
console.error(err);
});
return data;
};
const getAlbumArtists = async (album, artist) => {
let artists = [];
await axios
.post(state.settings.uri + "/album/artists", {
album: album,
artist: artist,
})
.then((res) => {
artists = res.data.artists;
})
.catch((err) => {
console.error(err);
});
return artists;
};
const getAlbumBio = async (name, artist) => {
const res = await fetch(
state.settings.uri +
"/album/" +
encodeURIComponent(name.replaceAll("/", "|")) +
"/" +
encodeURIComponent(artist.replaceAll("/", "|")) +
"/bio"
);
if (!res.ok) {
const message = `An error has occurred: ${res.status}`;
throw new Error(message);
}
const data = await res.json();
return data.bio;
};
export default {
getAlbumTracks,
getAlbumArtists,
getAlbumBio,
};

65
src/composables/album.ts Normal file
View File

@ -0,0 +1,65 @@
import axios from "axios";
import state from "./state";
import { AlbumInfo, Track } from "../interfaces";
const getAlbumTracks = async (album: string, artist: string) => {
let data = {
info: <AlbumInfo>{},
tracks: <Track[]>[],
};
await axios
.post(state.settings.uri + "/album/tracks", {
album: album,
artist: artist,
})
.then((res) => {
data.info = res.data.info;
data.tracks = res.data.songs;
})
.catch((err) => {
console.error(err);
});
return data;
};
const getAlbumArtists = async (album, artist) => {
let artists = [];
await axios
.post(state.settings.uri + "/album/artists", {
album: album,
artist: artist,
})
.then((res) => {
artists = res.data.artists;
})
.catch((err) => {
console.error(err);
});
return artists;
};
const getAlbumBio = async (album: string, albumartist: string) => {
let bio = null;
await axios
.post(state.settings.uri + "/album/bio", {
album: album,
albumartist: albumartist,
})
.then((res) => {
bio = res.data.bio;
})
.catch((err) => {
if (err.response.status === 404) {
bio = null;
}
});
return bio;
};
export { getAlbumTracks, getAlbumArtists, getAlbumBio };

View File

@ -1,47 +0,0 @@
import Router from "@/router";
import album from "./album.js";
import state from "./state";
async function toAlbum(title, artist) {
console.log("routing to album");
state.loading.value = true;
await album
.getAlbumTracks(title, artist)
.then((data) => {
state.album.tracklist = data.songs;
state.album.info = data.info;
})
.then(
await album.getAlbumArtists(title, artist).then((data) => {
state.album.artists = data;
})
)
.then(
album.getAlbumBio(title, artist).then((data) => {
if (data === "None") {
state.album.bio = null;
} else {
state.album.bio = data;
}
})
)
.then(() => {
Router.push({
name: "AlbumView",
params: {
album: title,
artist: artist,
},
});
state.loading.value = false;
})
.catch((error) => {
console.log(error);
});
}
export default {
toAlbum,
};

View File

@ -53,6 +53,8 @@ interface Playlist {
description?: string;
image?: string;
tracks?: Track[];
count?: number;
lastUpdated?: number;
}
interface Notif {

View File

@ -13,6 +13,8 @@ import SettingsView from "../views/SettingsView.vue";
import usePStore from "../stores/playlists";
import usePTrackStore from "../stores/p.ptracks";
import useFStore from "../stores/folder";
import useAStore from "../stores/album";
import state from "../composables/state";
const routes = [
{
@ -25,8 +27,9 @@ const routes = [
name: "FolderView",
component: FolderView,
beforeEnter: async (to) => {
console.log("beforeEnter")
state.loading.value = true;
await useFStore().fetchAll(to.params.path);
state.loading.value = false;
},
},
{
@ -38,7 +41,9 @@ const routes = [
name: "Playlists",
component: Playlists,
beforeEnter: async () => {
state.loading.value = true;
await usePStore().fetchAll();
state.loading.value = false;
},
},
{
@ -46,7 +51,9 @@ const routes = [
name: "PlaylistView",
component: PlaylistView,
beforeEnter: async (to) => {
state.loading.value = true;
await usePTrackStore().fetchAll(to.params.pid);
state.loading.value = false;
},
},
{
@ -58,6 +65,15 @@ const routes = [
path: "/albums/:album/:artist",
name: "AlbumView",
component: AlbumView,
beforeEnter: async (to) => {
state.loading.value = true;
await useAStore().fetchTracksAndArtists(
to.params.album,
to.params.artist
);
state.loading.value = false;
useAStore().fetchBio(to.params.album, to.params.artist);
},
},
{
path: "/artists",

31
src/stores/album.ts Normal file
View File

@ -0,0 +1,31 @@
import { defineStore } from "pinia";
import { Track, Artist, AlbumInfo } from "../interfaces";
import {
getAlbumTracks,
getAlbumArtists,
getAlbumBio,
} from "../composables/album";
export default defineStore("album", {
state: () => ({
info: <AlbumInfo>{},
tracks: <Track[]>[],
artists: <Artist[]>[],
bio: null,
}),
actions: {
async fetchTracksAndArtists(title: string, albumartist: string) {
const tracks = await getAlbumTracks(title, albumartist);
const artists = await getAlbumArtists(title, albumartist);
this.tracks = tracks.tracks;
this.info = tracks.info;
this.artists = artists;
},
fetchBio(title: string, albumartist: string) {
getAlbumBio(title, albumartist).then((bio) => {
this.bio = bio;
});
},
},
});

View File

@ -64,17 +64,18 @@ export default defineStore("Queue", {
progressElem: HTMLElement,
audio: new Audio(),
current: <Track>{},
playing: false,
current_time: 0,
next: <Track>{},
prev: <Track>{},
playing: false,
current_time: 0,
from: <fromFolder>{} || <fromAlbum>{} || <fromPlaylist>{},
tracks: <Track[]>[],
tracks: <Track[]>[defaultTrack],
}),
actions: {
play(track: Track) {
const uri = state.settings.uri + "/file/" + track.trackid;
const elem = document.getElementById("progress");
this.updateCurrent(track);
new Promise((resolve, reject) => {
this.audio.src = uri;
@ -82,8 +83,8 @@ export default defineStore("Queue", {
this.audio.onerror = reject;
})
.then(() => {
this.updateCurrent(track);
this.audio.play().then(() => {
this.playing = true;
notif(track, this.playPause, this.playNext, this.playPrev);
@ -172,49 +173,37 @@ export default defineStore("Queue", {
this.prev = this.tracks[index - 1];
}
},
setNewQueue(current: Track, tracklist: Track[]) {
this.play(current);
setNewQueue(tracklist: Track[]) {
if (this.tracks !== tracklist) {
this.tracks = tracklist;
addQToLocalStorage(this.from, this.tracks);
}
},
playFromFolder(fpath: string, tracks: Track[], current: Track) {
playFromFolder(fpath: string, tracks: Track[]) {
this.setNewQueue(tracks);
this.from = <fromFolder>{
type: FromOptions.folder,
path: fpath,
};
this.setNewQueue(current, tracks);
},
playFromAlbum(
aname: string,
albumartist: string,
tracks: Track[],
current: Track
) {
playFromAlbum(aname: string, albumartist: string, tracks: Track[]) {
this.setNewQueue(tracks);
this.from = <fromAlbum>{
type: FromOptions.album,
name: aname,
albumartist: albumartist,
};
this.setNewQueue(current, tracks);
},
playFromPlaylist(
pname: string,
pid: string,
tracks: Track[],
current: Track
) {
playFromPlaylist(pname: string, pid: string, tracks: Track[]) {
this.setNewQueue(tracks);
this.from = <fromPlaylist>{
type: FromOptions.playlist,
name: pname,
playlistid: pid,
};
this.setNewQueue(current, tracks);
},
},
});

View File

@ -1,47 +1,39 @@
<template>
<div class="al-view rounded">
<div>
<Header :album_info="state.album.info" />
<Header :album_info="album.info" />
</div>
<div class="separator" id="av-sep"></div>
<div class="songs rounded">
<SongList :songs="state.album.tracklist" />
<SongList :tracks="album.tracks" />
</div>
<div class="separator" id="av-sep"></div>
<FeaturedArtists :artists="state.album.artists" />
<div v-if="state.album.bio">
<FeaturedArtists :artists="album.artists" />
<div v-if="album.bio">
<div class="separator" id="av-sep"></div>
<AlbumBio :bio="state.album.bio" v-if="state.album.bio" />
<AlbumBio :bio="album.bio" />
</div>
</div>
</template>
<script setup>
import { useRoute } from "vue-router";
import { onMounted } from "@vue/runtime-core";
import { watch } from "vue";
<script setup lang="ts">
import Header from "../components/AlbumView/Header.vue";
import AlbumBio from "../components/AlbumView/AlbumBio.vue";
import SongList from "../components/FolderView/SongList.vue";
import FeaturedArtists from "../components/PlaylistView/FeaturedArtists.vue";
import state from "@/composables/state";
import routeLoader from "@/composables/routeLoader.js";
import useAStore from "../stores/album";
import { onBeforeRouteUpdate } from "vue-router";
const route = useRoute();
const album = useAStore();
onMounted(() => {
routeLoader.toAlbum(route.params.album, route.params.artist);
watch(
() => route.params,
() => {
if (route.name === "AlbumView") {
routeLoader.toAlbum(route.params.album, route.params.artist);
}
}
onBeforeRouteUpdate(async (to) => {
await album.fetchTracksAndArtists(
to.params.album.toString(),
to.params.artist.toString()
);
album.fetchBio(to.params.album.toString(), to.params.artist.toString());
});
</script>

View File

@ -4,7 +4,11 @@
<div class="separator no-border"></div>
<div class="songlist rounded">
<SongList :songs="playlist.tracks" />
<SongList
:tracks="playlist.tracks"
:pname="info.name"
:playlistid="playlist.playlistid"
/>
</div>
<div class="separator no-border"></div>
<FeaturedArtists />
@ -41,7 +45,7 @@ const info = {
}
.songlist {
padding: $small;
min-height: 100%;
min-height: calc(100% - 30rem);
}
}
</style>