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:
parent
c0601ad79c
commit
3640e9bf18
@ -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 {
|
||||||
|
@ -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",
|
||||||
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user