mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 04:23:01 +00:00
fix playing tracks on album page
This commit is contained in:
committed by
Mungai Njoroge
parent
977d9282cb
commit
6adf5df4c6
@@ -2,7 +2,7 @@
|
||||
<QueueActions />
|
||||
<div
|
||||
ref="scrollable"
|
||||
class="scrollable-r"
|
||||
id="queue-scrollable"
|
||||
v-bind="containerProps"
|
||||
style="height: 100%"
|
||||
@mouseover="mouseover = true"
|
||||
@@ -36,44 +36,37 @@ import QueueActions from "./Queue/QueueActions.vue";
|
||||
const queue = useQStore();
|
||||
const mouseover = ref(false);
|
||||
const scrollable = ref<HTMLElement>();
|
||||
const sourceTrackList = computed(() => queue.tracklist);
|
||||
const {
|
||||
list: tracks,
|
||||
containerProps,
|
||||
wrapperProps,
|
||||
} = useVirtualList(sourceTrackList, {
|
||||
itemHeight: 64,
|
||||
});
|
||||
|
||||
function playFromQueue(index: number) {
|
||||
queue.play(index);
|
||||
}
|
||||
|
||||
const source = computed(() => queue.tracklist);
|
||||
function scrollToCurrent() {
|
||||
const elem = document.getElementById("queue-scrollable") as HTMLElement;
|
||||
const itemHeight = 64;
|
||||
|
||||
const {
|
||||
list: tracks,
|
||||
containerProps,
|
||||
wrapperProps,
|
||||
scrollTo,
|
||||
} = useVirtualList(source, {
|
||||
itemHeight: 64,
|
||||
});
|
||||
const top = queue.currentindex * itemHeight - itemHeight;
|
||||
elem.scroll({
|
||||
top,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// scrollTo(queue.currentindex);
|
||||
queue.setScrollFunction(scrollToCurrent, mouseover);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
queue.setScrollFunction(() => {}, null);
|
||||
});
|
||||
|
||||
// TODO: Handle focusing current track on song end
|
||||
|
||||
|
||||
function scrollToCurrent() {
|
||||
const elem = document.getElementsByClassName('scrollable-r')[0] as HTMLElement;
|
||||
const itemHeight = 64;
|
||||
|
||||
const top = queue.currentindex * itemHeight - itemHeight;
|
||||
elem.scroll({
|
||||
top,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="morexx">
|
||||
<button class="btn" @click="loader">
|
||||
<button class="btn" @click.prevent="loader()">
|
||||
<div class="text">Load More</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,12 @@
|
||||
ref="header"
|
||||
class="header rounded"
|
||||
v-if="!no_header"
|
||||
:style="{ height: headerHeight + (on_album_page ? 0 : 24) + 'px' }"
|
||||
:style="{
|
||||
height:
|
||||
headerHeight +
|
||||
(on_album_page && album.query.length === 0 ? 0 : 24) +
|
||||
'px',
|
||||
}"
|
||||
>
|
||||
<div ref="header_content" class="header-content">
|
||||
<slot name="header"></slot>
|
||||
@@ -50,7 +55,11 @@
|
||||
queue.currentid === t.data.trackid && queue.playing
|
||||
"
|
||||
@playThis="
|
||||
updateQueue(t.data.index !== undefined ? t.data.index : t.index)
|
||||
updateQueue(
|
||||
t.data.index !== undefined
|
||||
? t.data.index - (on_album_page ? t.data.disc : 0)
|
||||
: t.index
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@@ -62,13 +71,15 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useElementSize, useVirtualList } from "@vueuse/core";
|
||||
import { computed, onMounted, onUpdated, ref, watch } from "vue";
|
||||
import { computed, onMounted, ref, watch } from "vue";
|
||||
|
||||
import { Track } from "@/interfaces";
|
||||
import useQStore from "@/stores/queue";
|
||||
import useAlbumStore from "@/stores/pages/album";
|
||||
|
||||
import SongItem from "@/components/shared/SongItem.vue";
|
||||
import AlbumDiscBar from "@/components/AlbumView/AlbumDiscBar.vue";
|
||||
|
||||
// EMITS & PROPS
|
||||
const emit = defineEmits<{
|
||||
(e: "playFromPage", index: number): void;
|
||||
@@ -80,13 +91,13 @@ const props = defineProps<{
|
||||
no_header?: boolean;
|
||||
}>();
|
||||
|
||||
// QUEUE
|
||||
const queue = useQStore();
|
||||
const album = useAlbumStore();
|
||||
|
||||
function updateQueue(index: number) {
|
||||
emit("playFromPage", index);
|
||||
}
|
||||
|
||||
// SCROLLABLE AREA
|
||||
let scrollable: HTMLElement;
|
||||
const v_list = ref<HTMLElement>();
|
||||
const header_content = ref<HTMLElement>();
|
||||
|
||||
+33
-15
@@ -9,7 +9,11 @@ import { getAlbumTracks } from "../../composables/fetch/album";
|
||||
import { AlbumInfo, Artist, FuseResult, Track } from "../../interfaces";
|
||||
import { useNotifStore } from "../notification";
|
||||
|
||||
function sortTracks(tracks: Track[]) {
|
||||
interface Disc {
|
||||
[key: string]: Track[];
|
||||
}
|
||||
|
||||
function sortByTrackNumber(tracks: Track[]) {
|
||||
return tracks.sort((a, b) => {
|
||||
if (a.track && b.track) {
|
||||
return a.track - b.track;
|
||||
@@ -19,24 +23,31 @@ function sortTracks(tracks: Track[]) {
|
||||
});
|
||||
}
|
||||
|
||||
interface Discs {
|
||||
[key: string]: Track[];
|
||||
function albumHasNoDiscs(album: AlbumInfo) {
|
||||
if (album.is_single) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function createDiscs(tracks: Track[]): Discs {
|
||||
/**
|
||||
*
|
||||
* @param tracks The raw tracklist from the server
|
||||
* @returns A list of `Disc` objects
|
||||
*/
|
||||
function createDiscs(tracks: Track[]) {
|
||||
return tracks.reduce((group, track) => {
|
||||
const { disc } = track;
|
||||
group[disc] = group[disc] ?? [];
|
||||
group[disc].push(track);
|
||||
return group;
|
||||
}, {} as Discs);
|
||||
}, {} as Disc);
|
||||
}
|
||||
|
||||
export default defineStore("album", {
|
||||
state: () => ({
|
||||
query: "",
|
||||
info: <AlbumInfo>{},
|
||||
allTracks: <Track[]>[],
|
||||
rawTracks: <Track[]>[],
|
||||
artists: <Artist[]>[],
|
||||
bio: null,
|
||||
}),
|
||||
@@ -47,14 +58,8 @@ export default defineStore("album", {
|
||||
* @param hash title of the album
|
||||
*/
|
||||
async fetchTracksAndArtists(hash: string) {
|
||||
this.allTracks = [];
|
||||
const album = await getAlbumTracks(hash, useNotifStore);
|
||||
|
||||
const discs = createDiscs(sortTracks(album.tracks));
|
||||
Object.keys(discs).forEach((disc) => {
|
||||
this.allTracks.push(...discs[disc]);
|
||||
});
|
||||
|
||||
this.rawTracks = album.tracks;
|
||||
this.info = album.info;
|
||||
},
|
||||
resetQuery() {
|
||||
@@ -62,15 +67,26 @@ export default defineStore("album", {
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
discs(): Disc {
|
||||
return createDiscs(sortByTrackNumber(this.rawTracks));
|
||||
},
|
||||
allTracks(): Track[] {
|
||||
return Object.keys(this.discs).reduce((tracks: Track[], disc) => {
|
||||
const disc_tracks = this.discs[disc];
|
||||
|
||||
return [...tracks, ...disc_tracks];
|
||||
}, []);
|
||||
},
|
||||
filteredTracks(): ComputedRef<FuseResult[]> {
|
||||
const discs = createDiscs(this.allTracks);
|
||||
let tracks: (Track[] | AlbumDisc[]) = [];
|
||||
const discs = this.discs;
|
||||
let tracks: Track[] | AlbumDisc[] = [];
|
||||
|
||||
Object.keys(discs).forEach((disc) => {
|
||||
const discHeader = {
|
||||
is_album_disc_number: true,
|
||||
album_page_disc_number: parseInt(disc),
|
||||
} as AlbumDisc;
|
||||
|
||||
tracks = [...tracks, discHeader, ...discs[disc]];
|
||||
});
|
||||
|
||||
@@ -90,3 +106,5 @@ export default defineStore("album", {
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: Implement Disc interface using a class
|
||||
|
||||
Reference in New Issue
Block a user