import { createSignal, onCleanup, onMount, Show, type Accessor } from "solid-js"; import { Icon } from "./Icon"; const BACK_TO_TOP_POSITION_KEY = "ehpeek:back-to-top:position"; export function clearBackToTopPosition(): void { GM_deleteValue(BACK_TO_TOP_POSITION_KEY); } type ButtonPosition = { bottom: number; right: number; }; export function BackToTop(props: { leftHanded: Accessor }) { let button!: HTMLButtonElement; let drag: { bottom: number; pointerId: number; right: number; x: number; y: number } | null = null; let dragged = false; const [visible, setVisible] = createSignal(false); const [position, setPosition] = createSignal(null); const positionStyle = () => { const current = position(); return current ? { bottom: `${current.bottom}px`, right: `${current.right}px` } : undefined; }; onMount(() => { const updateVisibility = () => { setVisible(window.scrollY > Math.max(320, window.innerHeight * 0.5)); }; updateVisibility(); const savedPosition = GM_getValue(BACK_TO_TOP_POSITION_KEY, null); if (savedPosition) { setPosition(savedPosition); } window.addEventListener("scroll", updateVisibility, { passive: true }); onCleanup(() => window.removeEventListener("scroll", updateVisibility)); }); return ( ); } function clampPosition(position: ButtonPosition, button: HTMLButtonElement): ButtonPosition { return { bottom: Math.min(Math.max(0, position.bottom), Math.max(0, window.innerHeight - button.offsetHeight)), right: Math.min(Math.max(0, position.right), Math.max(0, window.innerWidth - button.offsetWidth)), }; }