ytptube/ui/app/plugins/autoscroll.ts
2026-02-20 22:46:30 +03:00

38 lines
1.1 KiB
TypeScript

let observer: MutationObserver;
const AUTO_SCROLL_EVENTS = ['scroll', 'mousewheel', 'touchmove'] as const;
const events_handlers: Array<(ev: Event) => void> = [];
const on_mounted = (el: HTMLElement) => {
let scrolledToBottom = true;
AUTO_SCROLL_EVENTS.forEach((ev, index) => {
const handler = () => {
scrolledToBottom = el.scrollHeight - el.scrollTop - el.clientHeight <= 80;
};
events_handlers[index] = handler;
el.addEventListener(ev as string, handler, { passive: true } as AddEventListenerOptions);
});
observer = new MutationObserver(() => {
if (false === scrolledToBottom) return;
el.scrollTop = el.scrollHeight;
});
observer.observe(el, { childList: true, subtree: true });
};
const on_unmounted = (el: HTMLElement) => {
AUTO_SCROLL_EVENTS.forEach((ev, index) => {
const handler = events_handlers[index];
if (handler) {
el.removeEventListener(ev as string, handler, { passive: true } as EventListenerOptions);
}
});
observer.disconnect();
};
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('autoscroll', {
mounted: on_mounted,
unmounted: on_unmounted,
});
});