import { Embed as EmbedRJS } from "revolt.js/dist/api/objects"; import styles from "./Embed.module.scss"; import classNames from "classnames"; import { useContext } from "preact/hooks"; import { useIntermediate } from "../../../../context/intermediate/Intermediate"; import { MessageAreaWidthContext } from "../../../../pages/channels/messaging/MessageArea"; import EmbedMedia from "./EmbedMedia"; interface Props { embed: EmbedRJS; } const MAX_EMBED_WIDTH = 480; const MAX_EMBED_HEIGHT = 640; const CONTAINER_PADDING = 24; const MAX_PREVIEW_SIZE = 150; export default function Embed({ embed }: Props) { // ! FIXME: temp code // ! add proxy function to client function proxyImage(url: string) { return "https://jan.revolt.chat/proxy?url=" + encodeURIComponent(url); } const { openScreen } = useIntermediate(); const maxWidth = Math.min( useContext(MessageAreaWidthContext) - CONTAINER_PADDING, MAX_EMBED_WIDTH, ); function calculateSize( w: number, h: number, ): { width: number; height: number } { let limitingWidth = Math.min(maxWidth, w); let limitingHeight = Math.min(MAX_EMBED_HEIGHT, h); // Calculate smallest possible WxH. let width = Math.min(limitingWidth, limitingHeight * (w / h)); let height = Math.min(limitingHeight, limitingWidth * (h / w)); return { width, height }; } switch (embed.type) { case "Website": { // Determine special embed size. let mw, mh; let largeMedia = (embed.special && embed.special.type !== "None") || embed.image?.size === "Large"; switch (embed.special?.type) { case "YouTube": case "Bandcamp": { mw = embed.video?.width ?? 1280; mh = embed.video?.height ?? 720; break; } case "Twitch": { mw = 1280; mh = 720; break; } default: { if (embed.image?.size === "Preview") { mw = MAX_EMBED_WIDTH; mh = Math.min( embed.image.height ?? 0, MAX_PREVIEW_SIZE, ); } else { mw = embed.image?.width ?? MAX_EMBED_WIDTH; mh = embed.image?.height ?? 0; } } } let { width, height } = calculateSize(mw, mh); return (
{embed.site_name && (
{embed.icon_url && ( (e.currentTarget.style.display = "none") } /> )}
{embed.site_name}{" "}
)} {/*Author*/} {embed.title && ( {embed.title} )} {embed.description && (
{embed.description}
)} {largeMedia && ( )}
{!largeMedia && (
)}
); } case "Image": { return ( openScreen({ id: "image_viewer", embed })} onMouseDown={(ev) => ev.button === 1 && window.open(embed.url, "_blank") } /> ); } default: return null; } }