1import { mediaKindFromPath } from "@t3tools/shared/mediaPreview";
2import { mediaUrlReference } from "@t3tools/client-runtime/media-reference";
3import type { ExpandedImageItem, ExpandedImagePreview } from "./ExpandedImagePreview";
4import { resolveExternalWebLinkHost } from "./externalLinkContextMenu";
5import { resolveProtocolRelativeMediaUrl } from "../media/mediaContent";
6
7export const markdownImageItems = new WeakMap<Element, ExpandedImageItem>();
8
9export function markdownImageGallery(
10 element: Element,
11 selected: ExpandedImageItem,
12): ExpandedImagePreview {
13 const scope = element.closest("[data-image-gallery]") ?? element.closest(".chat-markdown");
14 const images: ExpandedImageItem[] = [];
15 let index = -1;
16 for (const image of scope?.querySelectorAll("img") ?? []) {
17 const registered = markdownImageItems.get(image);
18 if (!registered) continue;
19 const link = image.closest("a");
20 const href = link?.getAttribute("href") ?? "";
21 if (link && mediaKindFromPath(href) !== "image") continue;
22 const linkedSource =
23 resolveExternalWebLinkHost(href) !== null ? resolveProtocolRelativeMediaUrl(href) : null;
24 const reference = mediaUrlReference(href);
25 const item = linkedSource
26 ? {
27 ...registered,
28 src: linkedSource,
29 originalUrl: href,
30 actionsSource: {
31 kind: "image" as const,
32 name: registered.name,
33 src: linkedSource,
34 ...(reference ? { reference } : {}),
35 },
36 }
37 : registered;
38 if (
39 image === element ||
40 (!markdownImageItems.has(element) && index < 0 && item.src === selected.src)
41 ) {
42 index = images.length;
43 images.push(selected);
44 } else {
45 images.push(item);
46 }
47 }
48 return index < 0 ? { images: [selected], index: 0 } : { images, index };
49}