mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
group album tracks as they appear (in queue)
+ move handling disc logic to the album store
This commit is contained in:
@@ -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;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user