extract queue songlist into a reusable component

~ getting ready to implement "see all" in favorite page
This commit is contained in:
geoffrey45
2023-01-01 19:21:53 +03:00
committed by Mungai Njoroge
parent b95603c51e
commit 108182ab01
3 changed files with 40 additions and 227 deletions
-188
View File
@@ -1,188 +0,0 @@
<template>
<div
class="table"
v-if="tracks.length"
ref="tracklistElem"
:class="{
isSmall: isSmall,
isMedium: isMedium,
}"
>
<div class="header">
<div class="disc-number" v-if="disc">Disc {{ disc }}</div>
<div class="disc-number" v-if="$route.name === Routes.folder">
In this folder
</div>
</div>
<div class="songlist">
<SongItem
v-for="(track, index) in tracks"
:key="track.id"
:track="track"
:index="
on_album_page
? track.track
: track.index !== undefined
? track.index + 1
: index + 1
"
@playThis="updateQueue(track.index !== undefined ? track.index : index)"
/>
</div>
<div class="copyright" v-if="copyright && copyright">
{{ copyright }}
</div>
</div>
<div v-else-if="tracks.length === 0">
<div class="no-results">
<div class="text">No tracks here</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from "@vue/reactivity";
import { useElementSize } from "@vueuse/core";
import { ref } from "vue";
import SongItem from "../shared/SongItem.vue";
import { Track } from "@/interfaces";
import { Routes } from "@/router/routes";
import useQStore from "@/stores/queue";
const queue = useQStore();
const props = defineProps<{
tracks: Track[];
path?: string;
pname?: string;
id?: string;
on_album_page?: boolean;
disc?: string | number;
copyright?: string | null;
}>();
const emit = defineEmits<{
(e: "playFromPage", index: number): void;
}>();
const tracklistElem = ref<HTMLElement | null>(null);
const { width } = useElementSize(tracklistElem);
const brk = {
sm: 500,
md: 800,
};
const isSmall = computed(() => width.value < brk.sm);
const isMedium = computed(() => width.value > brk.sm && width.value < brk.md);
function updateQueue(index: number) {
emit("playFromPage", index);
}
/**
* Used to show handle track indexes.
*/
function getTrackList() {
if (props.on_album_page) {
const tracks = props.tracks.map((track) => {
track.index = track.track;
return track;
});
return tracks;
}
return props.tracks;
}
</script>
<style lang="scss">
.no-results {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 1rem;
}
.copyright {
font-size: 0.8rem;
margin-top: 1rem;
text-align: center;
opacity: 0.5;
}
.table {
height: 100%;
overflow-y: hidden;
padding: $small 0;
.header {
margin: $small;
.disc-number {
font-size: small;
font-weight: bold;
margin: $small 1.5rem;
color: $gray1;
}
}
.current {
a {
color: inherit;
}
color: $red;
}
.current:hover {
* {
color: rgb(255, 255, 255);
}
}
.songlist {
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
.contexton {
background-color: $gray4;
color: $white !important;
}
}
}
.table.isSmall {
.songlist-item {
grid-template-columns: 1.5rem 2fr 2rem 2.5rem;
}
.song-artists,
.song-album {
display: none !important;
}
.isSmallArtists {
display: unset !important;
font-size: small;
color: $white;
opacity: 0.67;
}
}
.table.isMedium {
.songlist-item {
grid-template-columns: 1.5rem 2fr 1fr 2rem 2.5rem;
}
.song-album {
display: none !important;
}
}
</style>
+36
View File
@@ -0,0 +1,36 @@
<template>
<div
class="queue-view-virtual-scroller v-scroll-page"
:class="{ isSmall, isMedium }"
style="height: 100%"
>
<RecycleScroller
class="scroller"
id="songlist-scroller"
style="height: 100%"
:items="tracks.map((track) => ({ track, id: Math.random() }))"
:item-size="itemHeight"
key-field="id"
v-slot="{ item, index }"
>
<SongItem
:track="item.track"
:index="index + 1"
@playThis="handlePlay(index)"
/>
</RecycleScroller>
</div>
</template>
<script setup lang="ts">
import SongItem from "@/components/shared/SongItem.vue";
import { isMedium, isSmall } from "@/stores/content-width";
import { Track } from "@/interfaces";
defineProps<{
tracks: Track[];
handlePlay: (index: number) => void;
}>();
const itemHeight = 64;
</script>