search tracks page scroll to top on search

+ add composable to wait for scroll
This commit is contained in:
geoffrey45 2023-01-03 14:53:53 +03:00 committed by Mungai Njoroge
parent 3d37cd59b3
commit 68f990aada
2 changed files with 64 additions and 12 deletions

View 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);
});
}

View File

@ -3,15 +3,20 @@ import { useDebounce } from "@vueuse/core";
import { defineStore } from "pinia";
import { watch } from "vue";
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 {
loadMoreAlbums,
loadMoreArtists,
loadMoreTracks,
searchAlbums,
searchArtists,
searchTracks,
} from "../composables/fetch/searchMusic";
import useLoaderStore from "./loader";
import useTabStore from "./tabs";
import waitForScrollEnd from "@/composables/useWaitForScroll";
import { Album, Artist, Playlist, Track } from "../interfaces";
/**
*
* Scrolls on clicking the loadmore button
@ -76,10 +81,16 @@ export default defineStore("search", () => {
function fetchTracks(query: string) {
if (!query) return;
searchTracks(query).then((res) => {
tracks.value = res.tracks;
tracks.more = res.more;
tracks.query = query;
searchTracks(query).then((data) => {
const scrollable = document.getElementById(
"songlist-scroller"
) 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() {
loadCounter.tracks += RESULT_COUNT;
startLoading();
startLoading();
loadMoreTracks(loadCounter.tracks)
.then((res) => {
tracks.value = [...tracks.value, ...res.tracks];
@ -137,7 +148,7 @@ export default defineStore("search", () => {
function loadArtists() {
loadCounter.artists += RESULT_COUNT;
startLoading();
startLoading();
loadMoreArtists(loadCounter.artists)
.then((res) => {
artists.value = [...artists.value, ...res.artists];