group album tracks as they appear (in queue)

+ move handling disc logic to the album store
This commit is contained in:
geoffrey45
2022-08-02 23:46:13 +03:00
parent 3dcb8ed2ef
commit ef2926f18f
5 changed files with 39 additions and 34 deletions
+12 -5
View File
@@ -6,7 +6,7 @@
</div> </div>
<div class="songlist"> <div class="songlist">
<SongItem <SongItem
v-for="track in getTracks()" v-for="track in getTrackList()"
:key="track.trackid" :key="track.trackid"
:track="track" :track="track"
:index="track.index" :index="track.index"
@@ -34,6 +34,7 @@ import { focusElem } from "@/composables/perks";
import { onMounted, onUpdated, ref } from "vue"; import { onMounted, onUpdated, ref } from "vue";
import { Track } from "@/interfaces"; import { Track } from "@/interfaces";
import useQStore from "@/stores/queue"; import useQStore from "@/stores/queue";
import useAlbumStore from "@/stores/pages/album";
const queue = useQStore(); const queue = useQStore();
@@ -90,13 +91,16 @@ function updateQueue(track: Track) {
queue.play(index); queue.play(index);
break; break;
case "AlbumView": case "AlbumView":
const album = useAlbumStore();
const tindex = album.tracks.findIndex((t) => t.trackid === track.trackid);
queue.playFromAlbum( queue.playFromAlbum(
track.album, track.album,
track.albumartist, track.albumartist,
track.albumhash, track.albumhash,
props.tracks album.tracks
); );
queue.play(index); queue.play(tindex);
break; break;
case "PlaylistView": case "PlaylistView":
queue.playFromPlaylist(props.pname, props.playlistid, props.tracks); queue.playFromPlaylist(props.pname, props.playlistid, props.tracks);
@@ -105,7 +109,10 @@ function updateQueue(track: Track) {
} }
} }
function getTracks() { /**
* Used to show track numbers as indexes in the album page.
*/
function getTrackList() {
if (props.on_album_page) { if (props.on_album_page) {
let tracks = props.tracks.map((track) => { let tracks = props.tracks.map((track) => {
track.index = track.tracknumber; track.index = track.tracknumber;
@@ -115,7 +122,7 @@ function getTracks() {
return tracks; return tracks;
} }
let tracks = props.tracks.map((track, index) => { const tracks = props.tracks.map((track, index) => {
track.index = index + 1; track.index = index + 1;
return track; return track;
}); });
+2 -1
View File
@@ -72,10 +72,11 @@ const showContextMenu = (e: Event) => {
.l-track-time { .l-track-time {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
opacity: 0.8;
margin-top: $small;
span { span {
font-size: small; font-size: small;
// background-color: $gray;
padding: $smaller; padding: $smaller;
} }
} }
+22 -3
View File
@@ -17,10 +17,24 @@ function sortTracks(tracks: Track[]) {
}); });
} }
interface Discs {
[key: string]: Track[];
}
function createDiscs(tracks: Track[]): Discs {
return tracks.reduce((group, track) => {
const { discnumber } = track;
group[discnumber] = group[discnumber] ?? [];
group[discnumber].push(track);
return group;
}, {} as Discs);
}
export default defineStore("album", { export default defineStore("album", {
state: () => ({ state: () => ({
info: <AlbumInfo>{}, info: <AlbumInfo>{},
tracks: <Track[]>[], tracks: <Track[]>[],
discs: <Discs>{},
artists: <Artist[]>[], artists: <Artist[]>[],
bio: null, bio: null,
}), }),
@@ -31,11 +45,16 @@ export default defineStore("album", {
* @param hash title of the album * @param hash title of the album
*/ */
async fetchTracksAndArtists(hash: string) { async fetchTracksAndArtists(hash: string) {
const tracks = await getAlbumTracks(hash, useNotifStore); this.tracks = [];
const album = await getAlbumTracks(hash, useNotifStore);
const artists = await getAlbumArtists(hash); const artists = await getAlbumArtists(hash);
this.tracks = sortTracks(tracks.tracks); this.discs = createDiscs(sortTracks(album.tracks));
this.info = tracks.info; Object.keys(this.discs).forEach((disc) => {
this.tracks.push(...this.discs[disc]);
});
this.info = album.info;
this.artists = artists; this.artists = artists;
}, },
/** /**
+1 -1
View File
@@ -1,7 +1,7 @@
<template> <template>
<div class="album-tracks rounded"> <div class="album-tracks rounded">
<div v-for="(disc, key) in discs" class="album-disc"> <div v-for="(disc, key) in discs" class="album-disc">
<SongList :key="key" :tracks="disc" :on_album_page="true" :c="key" /> <SongList :key="key" :tracks="disc" :on_album_page="true" :disc="key" />
</div> </div>
</div> </div>
</template> </template>
+2 -24
View File
@@ -4,7 +4,7 @@
<Header :album="album.info" /> <Header :album="album.info" />
</template> </template>
<template #content> <template #content>
<Content :discs="discs" /> <Content :discs="album.discs" />
</template> </template>
<template #bottom> <template #bottom>
<Bottom <Bottom
@@ -28,36 +28,14 @@ import Page from "@/layouts/HeaderContentBottom.vue";
import Bottom from "./Bottom.vue"; import Bottom from "./Bottom.vue";
import Content from "./Content.vue"; import Content from "./Content.vue";
import Header from "./Header.vue"; import Header from "./Header.vue";
import { Track } from "@/interfaces";
import { ref } from "vue";
const album = useAStore(); const album = useAStore();
// function that takes in a Track[] and returns a Track[][] which is a list of tracks split into discs
interface Disc {
[key: string]: Track[];
}
function createDiscs(tracks: Track[]): Disc {
// group tracks by disc using array.reduce
return tracks.reduce((group, track) => {
const { discnumber } = track;
group[discnumber] = group[discnumber] ?? [];
group[discnumber].push(track);
return group;
}, {} as Disc);
}
const discs = ref(createDiscs(album.tracks));
console.log(discs.value);
function fetchAlbumBio(params: RouteParams) { function fetchAlbumBio(params: RouteParams) {
album.fetchBio(params.hash.toString()); album.fetchBio(params.hash.toString());
} }
onBeforeRouteUpdate(async (to: RouteLocationNormalized) => { onBeforeRouteUpdate(async (to: RouteLocationNormalized) => {
await album.fetchTracksAndArtists(to.params.hash.toString()).then(() => { await album.fetchTracksAndArtists(to.params.hash.toString());
discs.value = createDiscs(album.tracks);
});
}); });
</script> </script>