fix playing tracks on album page

This commit is contained in:
geoffrey45
2022-10-04 10:09:27 +03:00
committed by Mungai Njoroge
parent 977d9282cb
commit 6adf5df4c6
4 changed files with 68 additions and 46 deletions
+18 -25
View File
@@ -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>
+16 -5
View File
@@ -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
View File
@@ -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