From 0920c060770d7f8fb2ec8b45caf299602f138bec Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Oct 2024 00:01:10 +0200 Subject: [PATCH] web/timeline: open inline images in lightbox when clicked --- web/src/App.tsx | 2 +- web/src/ui/modal/Lightbox.tsx | 1 + web/src/ui/timeline/content/TextMessageBody.tsx | 11 ++++++++++- web/src/vite-env.d.ts | 9 +++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index f3d0912..bb78844 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -28,7 +28,7 @@ function App() { const client = useMemo(() => new Client(new WSClient("_gomuks/websocket")), []) const connState = useEventAsState(client.rpc.connect) const clientState = useEventAsState(client.state) - ;((window as unknown) as { client: Client }).client = client + window.client = client useEffect(() => { Notification.requestPermission() .then(permission => console.log("Notification permission:", permission)) diff --git a/web/src/ui/modal/Lightbox.tsx b/web/src/ui/modal/Lightbox.tsx index 9c39f03..fc32815 100644 --- a/web/src/ui/modal/Lightbox.tsx +++ b/web/src/ui/modal/Lightbox.tsx @@ -51,6 +51,7 @@ export const LightboxWrapper = ({ children }: { children: React.ReactNode }) => setParams(params as LightboxParams) } }, []) + window.openLightbox = onOpen const onClose = useCallback(() => setParams(null), []) return <> diff --git a/web/src/ui/timeline/content/TextMessageBody.tsx b/web/src/ui/timeline/content/TextMessageBody.tsx index 1cf6491..91a3c2f 100644 --- a/web/src/ui/timeline/content/TextMessageBody.tsx +++ b/web/src/ui/timeline/content/TextMessageBody.tsx @@ -16,8 +16,17 @@ import { MessageEventContent } from "@/api/types" import EventContentProps from "./props.ts" +function isImageElement(elem: EventTarget): elem is HTMLImageElement { + return (elem as HTMLImageElement).tagName === "IMG" +} + const onClickHTML = (evt: React.MouseEvent) => { - if ((evt.target as HTMLElement).closest("span.hicli-spoiler")?.classList.toggle("spoiler-revealed")) { + if (isImageElement(evt.target)) { + window.openLightbox({ + src: evt.target.src, + alt: evt.target.alt, + }) + } else if ((evt.target as HTMLElement).closest?.("span.hicli-spoiler")?.classList.toggle("spoiler-revealed")) { // When unspoilering, don't trigger links and other clickables inside the spoiler evt.preventDefault() } diff --git a/web/src/vite-env.d.ts b/web/src/vite-env.d.ts index b1f45c7..27dd206 100644 --- a/web/src/vite-env.d.ts +++ b/web/src/vite-env.d.ts @@ -1,2 +1,11 @@ /// /// + +import type Client from "@/api/client.ts" + +declare global { + interface Window { + client: Client + openLightbox: (params: { src: string, alt: string }) => void + } +}