Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | 19x 19x 19x 19x 88x 52x 52x 52x 52x 52x 52x 45x 52x 42x 10x 10x 12x | import { ReactElement, useEffect, useState } from "react"; import { CardContentContextMenu, CardTrackContextMenu, PortalTarget, } from "components"; import type { ICardContentContextMenu } from "components/CardContentContextMenu"; import { useContextMenu, useEventListener } from "hooks"; import type { ITrack } from "types/spotify"; import { calculateContextMenuPosition, CONTEXT_MENU_SIDE_OFFSET, positionContextMenu, } from "utils"; export default function ContextMenu(): ReactElement | null { const { contextMenuData, removeContextMenu } = useContextMenu(); const [contextMenuPos, setContextMenuPos] = useState({ x: (contextMenuData?.position.x ?? 0) - 30, y: (contextMenuData?.position.y ?? 0) - 40, }); const [isContextMenuOffscreen, setIsContextMenuOffscreen] = useState({ x: false, y: false, }); const [element, setElement] = useState<HTMLElement | null>(null); useEventListener({ target: document.querySelector("#__next"), type: "click", listener: removeContextMenu, options: { once: true }, ignore: !contextMenuData?.data, }); useEffect(() => { positionContextMenu({ currentPosition: contextMenuData?.position, element: element, setPosition: setContextMenuPos, setIsOffScreen: setIsContextMenuOffscreen, offsets: { x: 30, y: 10 }, }); }, [contextMenuData?.position, element]); if (!contextMenuData) { return null; } const top = calculateContextMenuPosition( isContextMenuOffscreen.y, contextMenuPos.y, contextMenuData.position.y, CONTEXT_MENU_SIDE_OFFSET ); const left = calculateContextMenuPosition( isContextMenuOffscreen.x, contextMenuPos.x, contextMenuData.position.x, CONTEXT_MENU_SIDE_OFFSET ); return ( <PortalTarget targetId="contextMenu"> <section role="menu" data-type={contextMenuData.data?.type} ref={(element) => setElement(element)} style={{ top, left }} > {contextMenuData.data?.type === "track" || contextMenuData.data?.type === "episode" ? ( <CardTrackContextMenu track={contextMenuData.data as ITrack} /> ) : ( <CardContentContextMenu data={contextMenuData.data as ICardContentContextMenu["data"]} /> )} <style jsx>{` section { max-width: 400px; width: fit-content; position: absolute; margin: 0 auto; border-radius: 5px; background-color: #282828; box-shadow: 0px 2px 9px 0px rgb(0 0 0 / 5%); padding: 3px; max-height: 95vh; z-index: 999999999999; } `}</style> </section> </PortalTarget> ); } |