rewrite folder view using @Akryum/vue-virtual-scroller

This commit is contained in:
geoffrey45
2022-10-08 12:43:38 +03:00
committed by Mungai Njoroge
parent 1fa7ec4c43
commit b3b7da701b
4 changed files with 91 additions and 13 deletions
+1
View File
@@ -15,6 +15,7 @@ $larger: 2rem;
$banner-height: 18rem;
$song-item-height: 4rem;
$content-padding-bottom: 4rem;
// apple human design guideline colors
$black: #181a1c;
+1
View File
@@ -24,5 +24,6 @@ defineProps<{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
gap: 1.5rem;
margin-bottom: 1.75rem;
}
</style>
+10 -3
View File
@@ -1,8 +1,13 @@
import { createApp } from "vue";
import { createPinia } from "pinia";
// @ts-ignore
import { RecycleScroller } from "vue-virtual-scroller";
import {
RecycleScroller,
DynamicScroller,
DynamicScrollerItem,
// @ts-ignore
} from "vue-virtual-scroller";
import { autoAnimatePlugin } from "@formkit/auto-animate/vue";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
@@ -21,6 +26,8 @@ app.use(pinia);
app.use(router);
app.directive("tooltip", vTooltip);
app.use(autoAnimatePlugin);
app.component("RecycleScroller", RecycleScroller)
app.component("RecycleScroller", RecycleScroller);
app.component("DynamicScroller", DynamicScroller);
app.component("DynamicScrollerItem", DynamicScrollerItem);
app.mount("#app");
+79 -10
View File
@@ -1,29 +1,87 @@
<template>
<Layout
:tracks="folder.tracks"
:no_header="folder.dirs.length === 0"
@playFromPage="playFromPage"
>
<template #header v-if="folder.dirs.length">
<FolderList :folders="folder.dirs" />
</template>
</Layout>
<div class="folder-view v-scroll-page">
<DynamicScroller
:items="scrollerItems"
:min-item-size="64"
class="scroller"
>
<template v-slot="{ item, index, active }">
<DynamicScrollerItem
:item="item"
:active="active"
:size-dependencies="[item.props]"
:data-index="index"
>
<component
:key="index"
:is="item.component"
v-bind="item.props"
@playThis="playFromPage(item.props.index - 1)"
></component>
</DynamicScrollerItem>
</template>
</DynamicScroller>
</div>
</template>
<script setup lang="ts">
import { computed } from "@vue/reactivity";
import { onBeforeRouteLeave, onBeforeRouteUpdate } from "vue-router";
import { Track } from "@/interfaces";
import useQueueStore from "@/stores/queue";
import useLoaderStore from "@/stores/loader";
import useFolderStore from "@/stores/pages/folder";
import Layout from "@/layouts/HeaderAndVList.vue";
import SongItem from "@/components/shared/SongItem.vue";
import FolderList from "@/components/FolderView/FolderList.vue";
const loader = useLoaderStore();
const folder = useFolderStore();
const queue = useQueueStore();
interface ScrollerItem {
id: string;
component: typeof FolderList | typeof SongItem;
props: any;
}
class songItem {
id: string;
component = SongItem;
props: any;
constructor(track: Track) {
this.id = track.trackid;
this.props = {
track,
index: track.index + 1,
isCurrent: queue.currenttrack?.hash === track.hash,
isCurrentPlaying:
queue.currenttrack?.hash === track.hash && queue.playing,
};
}
}
const scrollerItems = computed(() => {
const items: ScrollerItem[] = [];
if (folder.dirs.length) {
items.push({
id: "folder-list",
component: FolderList,
props: {
folders: folder.dirs,
},
});
}
folder.tracks.forEach((track) => {
items.push(new songItem(track));
});
return items;
});
function playFromPage(index: number) {
queue.playFromFolder(folder.path, folder.allTracks);
@@ -47,3 +105,14 @@ onBeforeRouteLeave(() => {
setTimeout(() => folder.resetQuery(), 500);
});
</script>
<style lang="scss">
.folder-view {
height: 100%;
.scroller {
height: 100%;
padding-bottom: $content-padding-bottom !important;
}
}
</style>