1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-22 02:12:38 +01:00

more fixes for embeds

This commit is contained in:
Puyodead1 2024-04-17 23:01:46 -04:00
parent c0601ad79c
commit 3640e9bf18
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
3 changed files with 83 additions and 52 deletions

View File

@ -30,7 +30,6 @@ iframe {
border-inline-start-style: solid; border-inline-start-style: solid;
padding: 12px; padding: 12px;
width: fit-content;
background: var(--background-secondary); background: var(--background-secondary);
border-radius: 4px; border-radius: 4px;
} }
@ -45,7 +44,6 @@ iframe {
font-size: 12px; font-size: 12px;
color: var(--text-secondary); color: var(--text-secondary);
font-weight: var(--font-weight-regular); font-weight: var(--font-weight-regular);
width: fit-content;
} }
.embedAuthor { .embedAuthor {

View File

@ -6,6 +6,27 @@ import { modalController } from "../../controllers/modals";
import Icon from "../Icon"; import Icon from "../Icon";
import styles from "./Embed.module.css"; import styles from "./Embed.module.css";
function getScaledDimensions(originalWidth: number, originalHeight: number, maxWidth: number, maxHeight: number) {
const aspectRatio = originalWidth / originalHeight;
let newWidth = originalWidth;
let newHeight = originalHeight;
if (newWidth > maxWidth) {
newWidth = maxWidth;
newHeight = newWidth / aspectRatio;
}
if (newHeight > maxHeight) {
newHeight = maxHeight;
newWidth = newHeight * aspectRatio;
}
return { width: Math.round(newWidth), height: Math.round(newHeight) };
}
function shouldScaleImage(originalWidth: number, originalHeight: number, maxWidth: number, maxHeight: number) {
return originalWidth > maxWidth || originalHeight > maxHeight;
}
interface Props { interface Props {
embed: APIEmbed; embed: APIEmbed;
width?: number; width?: number;
@ -14,12 +35,49 @@ interface Props {
} }
function EmbedMedia({ embed, width, height, thumbnail }: Props) { function EmbedMedia({ embed, width, height, thumbnail }: Props) {
let maxWidth = 400;
let maxHeight = 300;
if (!width || !height) {
if (embed.video) {
width = embed.video.width;
height = embed.video.height;
} else if (embed.image) {
width = embed.image.width;
height = embed.image.height;
} else if (embed.thumbnail) {
if (embed.type !== EmbedType.Image && embed.provider?.name !== "GitHub") {
maxWidth = 80;
maxHeight = 80;
}
width = embed.thumbnail.width;
height = embed.thumbnail.height;
} else {
console.log("No media size provided");
width = 400;
height = 300;
}
}
const originalWidth = width;
const originalHeight = height;
// Scale image if it's too large
if (shouldScaleImage(width!, height!, maxWidth, maxHeight)) {
const { width: newWidth, height: newHeight } = getScaledDimensions(width!, height!, maxWidth, maxHeight);
width = newWidth;
height = newHeight;
}
console.log(`Original size: ${originalWidth}x${originalHeight} - Scaled size: ${width}x${height}`);
switch (embed.provider?.name) { switch (embed.provider?.name) {
case "YouTube": { case "YouTube": {
if (!embed.video?.url) return null; if (!embed.video?.url) return null;
const url = embed.video.url; const url = embed.video.url;
return <iframe loading="lazy" src={url} allowFullScreen style={{ height }} />; return <iframe loading="lazy" src={url} allowFullScreen style={{ height, width }} />;
} }
case "Spotify": { case "Spotify": {
const url = embed.url; const url = embed.url;
@ -144,7 +202,7 @@ function EmbedMedia({ embed, width, height, thumbnail }: Props) {
className={thumbnail ? styles.embedThumbnail : styles.embedImage} className={thumbnail ? styles.embedThumbnail : styles.embedImage}
src={url} src={url}
loading="lazy" loading="lazy"
style={{ width: thumbnail ? width : undefined, height }} style={{ height, width }}
onClick={() => { onClick={() => {
modalController.push({ modalController.push({
type: "image_viewer", type: "image_viewer",

View File

@ -9,13 +9,11 @@ import Markdown from "../markdown/Markdown";
import MarkdownRenderer from "../markdown/MarkdownRenderer"; import MarkdownRenderer from "../markdown/MarkdownRenderer";
import styles from "./Embed.module.css"; import styles from "./Embed.module.css";
import EmbedMedia from "./EmbedMedia"; import EmbedMedia from "./EmbedMedia";
import { MESSAGE_AREA_PADDING, MessageAreaWidthContext } from "./MessageList"; import { MessageAreaWidthContext } from "./MessageList";
const MAX_EMBED_WIDTH = 400; const LINK_EMBED_MAX_WIDTH = 516;
const MAX_EMBED_HEIGHT = 640; const RICH_EMBED_MAX_WIDTH = 428;
const THUMBNAIL_MAX_WIDTH = 80;
const CONTAINER_PADDING = 24; const CONTAINER_PADDING = 24;
const MAX_PREVIEW_SIZE = 150;
const EMBEDDABLE_PROVIDERS = ["Spotify" /*, "Bandcamp"*/]; const EMBEDDABLE_PROVIDERS = ["Spotify" /*, "Bandcamp"*/];
interface Props { interface Props {
@ -24,19 +22,19 @@ interface Props {
function MessageEmbed({ embed }: Props) { function MessageEmbed({ embed }: Props) {
const c = React.useContext(MessageAreaWidthContext); const c = React.useContext(MessageAreaWidthContext);
const maxWidth = Math.min(c - MESSAGE_AREA_PADDING, MAX_EMBED_WIDTH); // const maxWidth = Math.min(c - MESSAGE_AREA_PADDING, MAX_EMBED_WIDTH);
function calculateSize(w: number, h: number): { width: number; height: number } { // function calculateSize(w: number, h: number): { width: number; height: number } {
const limitingWidth = Math.min(w, maxWidth); // const limitingWidth = Math.min(w, maxWidth);
const limitingHeight = Math.min(MAX_EMBED_HEIGHT, h); // const limitingHeight = Math.min(MAX_EMBED_HEIGHT, h);
// Calculate smallest possible WxH. // // Calculate smallest possible WxH.
const width = Math.min(limitingWidth, limitingHeight * (w / h)); // const width = Math.min(limitingWidth, limitingHeight * (w / h));
const height = Math.min(limitingHeight, limitingWidth * (h / w)); // const height = Math.min(limitingHeight, limitingWidth * (h / w));
return { width, height }; // return { width, height };
} // }
// Determine special embed size. // Determine special embed size.
let mw, mh; let mw, mh;
@ -47,42 +45,14 @@ function MessageEmbed({ embed }: Props) {
embed.type === EmbedType.GIFV || embed.type === EmbedType.GIFV ||
embed.type === EmbedType.Image; embed.type === EmbedType.Image;
if (embed.image) { // const { width, height } = calculateSize(mw, mh);
mw = embed.image?.width ?? MAX_EMBED_WIDTH;
mh = embed.image?.height ?? 0;
} else if (embed.thumbnail) {
mw = embed.thumbnail.width ?? MAX_EMBED_WIDTH;
mh = embed.thumbnail.height ?? 0;
} else {
switch (embed.provider?.name) {
case "YouTube":
case "Bandcamp": {
mw = embed.video?.width ?? 1280;
mh = embed.video?.height ?? 720;
break;
}
case "Twitch":
case "Lightspeed":
case "Streamable": {
mw = 1280;
mh = 720;
break;
}
default: {
mw = MAX_EMBED_WIDTH;
mh = 1;
}
}
}
const { width, height } = calculateSize(mw, mh);
if ( if (
embed.type === EmbedType.GIFV || embed.type === EmbedType.GIFV ||
embed.type === EmbedType.Image || embed.type === EmbedType.Image ||
embed.type === EmbedType.Video || (embed.type === EmbedType.Video && embed.provider?.name !== "YouTube") ||
EMBEDDABLE_PROVIDERS.includes(embed.provider?.name ?? "") EMBEDDABLE_PROVIDERS.includes(embed.provider?.name ?? "")
) { ) {
return <EmbedMedia embed={embed} width={height} height={height} />; return <EmbedMedia embed={embed} />;
} }
return ( return (
@ -90,10 +60,15 @@ function MessageEmbed({ embed }: Props) {
className={classNames(styles.embed, styles.website)} className={classNames(styles.embed, styles.website)}
style={{ style={{
borderInlineStartColor: embed.color ? decimalColorToHex(embed.color) : "var(--background-tertiary)", borderInlineStartColor: embed.color ? decimalColorToHex(embed.color) : "var(--background-tertiary)",
maxWidth: width + CONTAINER_PADDING, maxWidth: 432,
}} }}
> >
<div className={styles.embedGap}> <div
className={styles.embedGap}
style={{
maxWidth: embed.type === EmbedType.Rich ? RICH_EMBED_MAX_WIDTH : LINK_EMBED_MAX_WIDTH,
}}
>
<div style={{ display: "flex" }}> <div style={{ display: "flex" }}>
<div className={styles.embedGap}> <div className={styles.embedGap}>
{embed.type !== EmbedType.Rich && embed.provider && ( {embed.type !== EmbedType.Rich && embed.provider && (
@ -178,7 +153,7 @@ function MessageEmbed({ embed }: Props) {
{(largeMedia || embed.type === EmbedType.Rich) && ( {(largeMedia || embed.type === EmbedType.Rich) && (
<div> <div>
<EmbedMedia embed={embed} width={width} /> <EmbedMedia embed={embed} width={embed.provider?.name === "YouTube" ? 400 : undefined} />
</div> </div>
)} )}