Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
227
AssetLightbox.tsx3.62 kB
import { Portal, Presence, UsePresenceProps } from "@ark-ui/react"; import { useClickAway } from "@uidotdev/usehooks"; import { ArrowRight } from "lucide-react"; import Image from "next/image"; import { useQueryState } from "nuqs"; import { Asset } from "@/api/openapi-schema"; import { css, cx } from "@/styled-system/css"; import { Box, Center, HStack } from "@/styled-system/jsx"; import { getAssetURL } from "@/utils/asset"; import { IconButton } from "../ui/icon-button"; import { ArrowLeftIcon, ArrowRightIcon } from "../ui/icons/Arrow"; type Props = UsePresenceProps & { asset: Asset; set?: Asset[]; setIndex?: number; onClose: () => void; }; const overlayStyles = css({ position: "fixed", top: "0", left: "0", width: "screen", height: "dvh", }); const containerStyles = css({ zIndex: "overlay", }); const backdropStyles = css({ backdropBlur: "sm", backdropGrayscale: "0.8", backdropBrightness: "0.1", backdropFilter: "auto", }); const backdropImageStyles = css({ blur: "3xl", opacity: "2", brightness: "0.5", filter: "auto", }); const lightboxStyles = css({ margin: "auto", padding: "4", }); const imageStyles = css({ height: "auto", width: "auto", maxHeight: "lvh", borderRadius: "sm", boxShadow: "var(--box-shadow)", "--box-shadow": "0px 0px 40px var(--colors-black-a2), 0px 0px 1px var(--colors-gray-a7)", }); export function AssetLightbox({ asset, set, setIndex, onClose, ...presenceProps }: Props) { const url = getAssetURL(asset.path)!; const [view, setView] = useQueryState<string | null>("view", { defaultValue: null, clearOnDefault: true, parse: (value) => (value === "" ? null : value), }); const ref = useClickAway<HTMLImageElement>(handleClose); function handleClose() { onClose(); } function handlePrevious() { if (set === undefined || setIndex === undefined) return; const nextIndex = setIndex - 1 < 0 ? set.length - 1 : setIndex - 1; const next = set[nextIndex]; if (next) { setView(next.id); } } function handleNext() { if (set === undefined || setIndex === undefined) return; const nextIndex = setIndex + 1 === set.length ? 0 : setIndex + 1; const next = set[nextIndex]; if (next) { setView(next.id); } } // NOTE: Presence doesn't work for some reason. Possibly bug in Ark UI. if (!presenceProps.present) { return null; } return ( <Presence lazyMount present={presenceProps.present}> <Portal> <Box className={cx(overlayStyles, containerStyles)}> <Box className={cx(overlayStyles, backdropStyles)}> <Image className={backdropImageStyles} src={url} fill alt="" /> </Box> <Center className={cx(overlayStyles, lightboxStyles)}> <HStack ref={ref}> <Box position="fixed" left="8"> <IconButton variant="subtle" size="sm" onClick={handlePrevious}> <ArrowLeftIcon /> </IconButton> </Box> <Box position="fixed" right="8"> <IconButton variant="subtle" size="sm" onClick={handleNext}> <ArrowRightIcon /> </IconButton> </Box> <Image className={imageStyles} src={url} width={2000} height={2000} alt="" /> </HStack> </Center> {/* <Image src={url} alt={asset.filename} width="1920" height="1080" /> */} </Box> </Portal> </Presence> ); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server