mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
extract queue songlist into a reusable component
~ getting ready to implement "see all" in favorite page
This commit is contained in:
committed by
Mungai Njoroge
parent
b95603c51e
commit
108182ab01
@@ -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>
|
|
||||||
@@ -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>
|
||||||
+4
-39
@@ -1,54 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<SongList :tracks="queue.tracklist" :handlePlay="playFromQueue" />
|
||||||
class="queue-view-virtual-scroller v-scroll-page"
|
|
||||||
:class="{ isSmall, isMedium }"
|
|
||||||
style="height: 100%"
|
|
||||||
>
|
|
||||||
<RecycleScroller
|
|
||||||
class="scroller"
|
|
||||||
id="queue-page-scrollable"
|
|
||||||
style="height: 100%"
|
|
||||||
:items="scrollerItems"
|
|
||||||
:item-size="itemHeight"
|
|
||||||
key-field="id"
|
|
||||||
v-slot="{ item, index }"
|
|
||||||
>
|
|
||||||
<SongItem
|
|
||||||
:track="item.track"
|
|
||||||
:index="index + 1"
|
|
||||||
@playThis="playFromQueue(index)"
|
|
||||||
/>
|
|
||||||
</RecycleScroller>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted } from "vue";
|
import { onMounted } from "vue";
|
||||||
|
|
||||||
import SongItem from "@/components/shared/SongItem.vue";
|
|
||||||
import { isMedium, isSmall } from "@/stores/content-width";
|
|
||||||
import useQStore from "@/stores/queue";
|
import useQStore from "@/stores/queue";
|
||||||
import { createTrackProps } from "@/utils";
|
import SongList from "@/components/shared/SongList.vue";
|
||||||
|
|
||||||
const itemHeight = 64;
|
|
||||||
const queue = useQStore();
|
const queue = useQStore();
|
||||||
|
|
||||||
const scrollerItems = computed(() => {
|
|
||||||
return queue.tracklist.map((track) => {
|
|
||||||
return {
|
|
||||||
track,
|
|
||||||
id: Math.random(),
|
|
||||||
props: createTrackProps(track),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function playFromQueue(index: number) {
|
function playFromQueue(index: number) {
|
||||||
queue.play(index);
|
queue.play(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollToCurrent() {
|
function scrollToCurrent() {
|
||||||
const scrollable = document.getElementById("queue-page-scrollable");
|
const scrollable = document.getElementById("songlist-scroller");
|
||||||
const itemHeight = 64;
|
const itemHeight = 64;
|
||||||
const top = (queue.currentindex - 1) * itemHeight;
|
const top = (queue.currentindex - 1) * itemHeight;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user