mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-06-07 11:45:35 +00:00
search tracks page scroll to top on search
+ add composable to wait for scroll
This commit is contained in:
parent
3d37cd59b3
commit
68f990aada
41
src/composables/useWaitForScroll.ts
Normal file
41
src/composables/useWaitForScroll.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// CREDITS: https://stackoverflow.com/a/66664192
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrolls and waits for the scroll to finish. Returns a promise that resolves when the scroll is finished.
|
||||||
|
* @param elem The element to scroll and wait for
|
||||||
|
* @param pos The position to scroll to
|
||||||
|
* @param delay The delay in seconds to wait for
|
||||||
|
* @returns A promise that resolves when the element has been scrolled to the position
|
||||||
|
*/
|
||||||
|
export default function waitForScrollEnd(
|
||||||
|
elem: HTMLElement,
|
||||||
|
pos = 0,
|
||||||
|
delay = 100
|
||||||
|
): Promise<void> {
|
||||||
|
elem.scroll({
|
||||||
|
top: pos,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
|
const frame_limit = 20;
|
||||||
|
let last_changed_frame = 0;
|
||||||
|
let last_y = elem.scrollTop;
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
function tick(frames: number) {
|
||||||
|
// We requestAnimationFrame either for 500 frames or until 20 frames with
|
||||||
|
// no change have been observed.
|
||||||
|
if (frames >= 500 || frames - last_changed_frame > frame_limit) {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, delay);
|
||||||
|
} else {
|
||||||
|
if (window.scrollY != last_y) {
|
||||||
|
last_changed_frame = frames;
|
||||||
|
last_y = window.scrollY;
|
||||||
|
}
|
||||||
|
requestAnimationFrame(tick.bind(null, frames + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tick(0);
|
||||||
|
});
|
||||||
|
}
|
@ -3,15 +3,20 @@ import { useDebounce } from "@vueuse/core";
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { watch } from "vue";
|
import { watch } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import {
|
|
||||||
loadMoreAlbums,
|
|
||||||
loadMoreArtists, loadMoreTracks, searchAlbums,
|
|
||||||
searchArtists, searchTracks
|
|
||||||
} from "../composables/fetch/searchMusic";
|
|
||||||
import { Album, Artist, Playlist, Track } from "../interfaces";
|
|
||||||
import { Routes } from "@/router/routes";
|
import { Routes } from "@/router/routes";
|
||||||
|
|
||||||
|
import {
|
||||||
|
loadMoreAlbums,
|
||||||
|
loadMoreArtists,
|
||||||
|
loadMoreTracks,
|
||||||
|
searchAlbums,
|
||||||
|
searchArtists,
|
||||||
|
searchTracks,
|
||||||
|
} from "../composables/fetch/searchMusic";
|
||||||
import useLoaderStore from "./loader";
|
import useLoaderStore from "./loader";
|
||||||
import useTabStore from "./tabs";
|
import useTabStore from "./tabs";
|
||||||
|
import waitForScrollEnd from "@/composables/useWaitForScroll";
|
||||||
|
import { Album, Artist, Playlist, Track } from "../interfaces";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Scrolls on clicking the loadmore button
|
* Scrolls on clicking the loadmore button
|
||||||
@ -76,10 +81,16 @@ export default defineStore("search", () => {
|
|||||||
function fetchTracks(query: string) {
|
function fetchTracks(query: string) {
|
||||||
if (!query) return;
|
if (!query) return;
|
||||||
|
|
||||||
searchTracks(query).then((res) => {
|
searchTracks(query).then((data) => {
|
||||||
tracks.value = res.tracks;
|
const scrollable = document.getElementById(
|
||||||
tracks.more = res.more;
|
"songlist-scroller"
|
||||||
tracks.query = query;
|
) as HTMLElement;
|
||||||
|
|
||||||
|
waitForScrollEnd(scrollable, 0).then(() => {
|
||||||
|
tracks.value = data.tracks;
|
||||||
|
tracks.more = data.more;
|
||||||
|
tracks.query = query;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +118,7 @@ export default defineStore("search", () => {
|
|||||||
function loadTracks() {
|
function loadTracks() {
|
||||||
loadCounter.tracks += RESULT_COUNT;
|
loadCounter.tracks += RESULT_COUNT;
|
||||||
|
|
||||||
startLoading();
|
startLoading();
|
||||||
loadMoreTracks(loadCounter.tracks)
|
loadMoreTracks(loadCounter.tracks)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
tracks.value = [...tracks.value, ...res.tracks];
|
tracks.value = [...tracks.value, ...res.tracks];
|
||||||
@ -137,7 +148,7 @@ export default defineStore("search", () => {
|
|||||||
function loadArtists() {
|
function loadArtists() {
|
||||||
loadCounter.artists += RESULT_COUNT;
|
loadCounter.artists += RESULT_COUNT;
|
||||||
|
|
||||||
startLoading();
|
startLoading();
|
||||||
loadMoreArtists(loadCounter.artists)
|
loadMoreArtists(loadCounter.artists)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
artists.value = [...artists.value, ...res.artists];
|
artists.value = [...artists.value, ...res.artists];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user