mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
use div scroll method to scroll to current song in queue
This commit is contained in:
committed by
Mungai Njoroge
parent
8e258eaf24
commit
278439eee8
@@ -4,7 +4,7 @@ input[type="range"] {
|
||||
width: calc(100% - 2px);
|
||||
height: 0.3rem;
|
||||
border-radius: 5px;
|
||||
background: $gray4 linear-gradient(90deg, $accent, $darkestblue) no-repeat;
|
||||
background: $gray4 linear-gradient(90deg, $darkblue, $darkestblue) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<div class="title ellip">
|
||||
<div v-tooltip class="title ellip">
|
||||
{{ queue.currenttrack?.title || "Hello there" }}
|
||||
</div>
|
||||
<ArtistName
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<template>
|
||||
<QueueActions />
|
||||
<div
|
||||
ref="scrollable"
|
||||
class="scrollable-r"
|
||||
v-bind="containerProps"
|
||||
style="height: 100%"
|
||||
@mouseover="mouseover = true"
|
||||
@mouseout="mouseover = false"
|
||||
>
|
||||
<div class="inner" v-bind="wrapperProps" >
|
||||
<div class="inner" v-bind="wrapperProps">
|
||||
<TrackItem
|
||||
style="height: 64px"
|
||||
v-for="t in tracks"
|
||||
@@ -34,6 +35,7 @@ import QueueActions from "./Queue/QueueActions.vue";
|
||||
|
||||
const queue = useQStore();
|
||||
const mouseover = ref(false);
|
||||
const scrollable = ref<HTMLElement>();
|
||||
|
||||
function playFromQueue(index: number) {
|
||||
queue.play(index);
|
||||
@@ -51,8 +53,8 @@ const {
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
scrollTo(queue.currentindex);
|
||||
queue.setScrollFunction(scrollTo, mouseover);
|
||||
// scrollTo(queue.currentindex);
|
||||
queue.setScrollFunction(scrollToCurrent, mouseover);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -60,6 +62,18 @@ onBeforeUnmount(() => {
|
||||
});
|
||||
|
||||
// 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">
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
<div class="flex">
|
||||
<div v-auto-animate @click.pre@dblclick.prevent="emitUpdate" class="thumbnail">
|
||||
<img
|
||||
loading="lazy"
|
||||
:src="imguri + track.image"
|
||||
alt=""
|
||||
class="album-art image rounded-sm"
|
||||
/>
|
||||
<div
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
<div class="album-art">
|
||||
<img
|
||||
:src="paths.images.thumb.small + track.image"
|
||||
alt=""
|
||||
class="rounded-sm"
|
||||
/>
|
||||
<div
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// "local" | "remote"
|
||||
let mode = "remote";
|
||||
let mode = "local";
|
||||
|
||||
export interface D<T = string> {
|
||||
[key: string]: T;
|
||||
|
||||
@@ -2,26 +2,27 @@
|
||||
<!-- JUST A COMMENT: 64 is single item height, 24 is gap height -->
|
||||
<div class="header-list-layout">
|
||||
<div
|
||||
id="v-page-scrollable"
|
||||
v-bind="containerProps"
|
||||
style="height: 100%"
|
||||
:style="{ paddingTop: !no_header ? headerHeight - 64 + 24 + 'px' : 0 }"
|
||||
@scroll="handleScroll"
|
||||
>
|
||||
<div
|
||||
v-bind="wrapperProps"
|
||||
class="scrollable"
|
||||
ref="scrollable"
|
||||
class="v-list"
|
||||
ref="v_list"
|
||||
:class="{
|
||||
isSmall: isSmall,
|
||||
isMedium: isMedium || on_album_page,
|
||||
}"
|
||||
>
|
||||
<div class="header rounded" style="height: 64px" v-if="!no_header">
|
||||
<div
|
||||
ref="header"
|
||||
:style="{ top: -headerHeight + 64 - 24 + 'px' }"
|
||||
class="header-content"
|
||||
>
|
||||
<div
|
||||
ref="header"
|
||||
class="header rounded"
|
||||
v-if="!no_header"
|
||||
:style="{ height: headerHeight + 24 + 'px' }"
|
||||
>
|
||||
<div ref="header_content" class="header-content">
|
||||
<slot name="header"></slot>
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,7 +55,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useElementSize, useVirtualList } from "@vueuse/core";
|
||||
import { computed, ref } from "vue";
|
||||
import { computed, onMounted, onUpdated, ref, watch } from "vue";
|
||||
|
||||
import { Track } from "@/interfaces";
|
||||
import useQStore from "@/stores/queue";
|
||||
@@ -79,8 +80,10 @@ function updateQueue(index: number) {
|
||||
}
|
||||
|
||||
// SCROLLABLE AREA
|
||||
const scrollable = ref<HTMLElement>();
|
||||
const { width } = useElementSize(scrollable);
|
||||
let scrollable: HTMLElement;
|
||||
const v_list = ref<HTMLElement>();
|
||||
const header_content = ref<HTMLElement>();
|
||||
const { width } = useElementSize(v_list);
|
||||
|
||||
const brk = {
|
||||
sm: 500,
|
||||
@@ -92,28 +95,38 @@ const isMedium = computed(() => width.value > brk.sm && width.value < brk.md);
|
||||
|
||||
// VIRTUAL LIST
|
||||
const source = computed(() => props.tracks);
|
||||
|
||||
const {
|
||||
list: tracks,
|
||||
containerProps,
|
||||
wrapperProps,
|
||||
} = useVirtualList(source, {
|
||||
itemHeight: 60,
|
||||
overscan: 15,
|
||||
overscan: 20,
|
||||
});
|
||||
|
||||
// watch source changes and scroll to top
|
||||
watch(source, () => {
|
||||
scrollable.scroll(0, 0);
|
||||
});
|
||||
|
||||
// HEADER
|
||||
const header = ref<HTMLElement>();
|
||||
const { height: headerHeight } = useElementSize(header);
|
||||
const { height: headerHeight } = useElementSize(header_content);
|
||||
|
||||
function handleScroll(e: Event) {
|
||||
const scrollTop = (e.target as HTMLElement).scrollTop;
|
||||
|
||||
if (scrollTop > headerHeight.value) {
|
||||
if (scrollTop > (header.value?.offsetHeight || 0)) {
|
||||
header.value ? (header.value.style.opacity = "0") : null;
|
||||
} else {
|
||||
header.value ? (header.value.style.opacity = "1") : null;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
scrollable = document.getElementById("v-page-scrollable") as HTMLElement;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -121,7 +134,7 @@ function handleScroll(e: Event) {
|
||||
margin-right: -$medium;
|
||||
height: 100%;
|
||||
|
||||
.scrollable {
|
||||
.v-list {
|
||||
padding-right: calc(1rem - $small + 2px);
|
||||
scrollbar-width: thin;
|
||||
|
||||
@@ -134,7 +147,7 @@ function handleScroll(e: Event) {
|
||||
}
|
||||
}
|
||||
|
||||
.scrollable.isSmall {
|
||||
.v-list.isSmall {
|
||||
// hide album and artists columns
|
||||
.songlist-item {
|
||||
grid-template-columns: 1.5rem 2fr 2.5rem 2.5rem;
|
||||
@@ -153,7 +166,7 @@ function handleScroll(e: Event) {
|
||||
}
|
||||
}
|
||||
|
||||
.scrollable.isMedium {
|
||||
.v-list.isMedium {
|
||||
// hide album column
|
||||
.songlist-item {
|
||||
grid-template-columns: 1.5rem 1.5fr 1fr 2.5rem 2.5rem;
|
||||
@@ -163,14 +176,5 @@ function handleScroll(e: Event) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
position: relative;
|
||||
|
||||
.header-content {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user