revite/src/components/common/messaging/attachments/Attachment.tsx

192 lines
7.3 KiB
TypeScript
Raw Normal View History

2021-07-05 11:23:23 +01:00
import { Attachment as AttachmentRJS } from "revolt.js/dist/api/objects";
2021-06-20 22:09:18 +01:00
import styles from "./Attachment.module.scss";
2021-07-05 11:23:23 +01:00
import classNames from "classnames";
import { Text } from "preact-i18n";
2021-06-20 22:09:18 +01:00
import { useContext, useState } from "preact/hooks";
2021-07-05 11:23:23 +01:00
2021-06-20 22:09:18 +01:00
import { useIntermediate } from "../../../../context/intermediate/Intermediate";
2021-07-05 11:23:23 +01:00
import { AppContext } from "../../../../context/revoltjs/RevoltClient";
import AttachmentActions from "./AttachmentActions";
import TextFile from "./TextFile";
2021-07-10 15:21:35 +01:00
import { SizedGrid } from "./Grid";
2021-06-20 22:09:18 +01:00
interface Props {
2021-07-05 11:25:20 +01:00
attachment: AttachmentRJS;
hasContent: boolean;
2021-06-20 22:09:18 +01:00
}
const MAX_ATTACHMENT_WIDTH = 480;
export default function Attachment({ attachment, hasContent }: Props) {
2021-07-05 11:25:20 +01:00
const client = useContext(AppContext);
const { openScreen } = useIntermediate();
const { filename, metadata } = attachment;
const [spoiler, setSpoiler] = useState(filename.startsWith("SPOILER_"));
const [loaded, setLoaded] = useState(false);
2021-06-20 22:09:18 +01:00
2021-07-05 11:25:20 +01:00
const url = client.generateFileURL(
attachment,
{ width: MAX_ATTACHMENT_WIDTH * 1.5 },
true,
);
2021-06-20 22:09:18 +01:00
2021-07-05 11:25:20 +01:00
switch (metadata.type) {
case "Image": {
return (
2021-07-10 15:21:35 +01:00
<SizedGrid width={metadata.width} height={metadata.height}
className={classNames({ [styles.margin]: hasContent })}>
<img src={url} alt={filename}
className={styles.image}
loading="lazy"
onClick={() =>
openScreen({ id: "image_viewer", attachment })
}
onMouseDown={(ev) =>
ev.button === 1 && window.open(url, "_blank")
} />
</SizedGrid>
)
}
case "Video": {
return (
<div className={classNames(styles.container, { [styles.margin]: hasContent })}
style={{ '--width': metadata.width + 'px' }}>
<AttachmentActions attachment={attachment} />
<SizedGrid width={metadata.width} height={metadata.height}>
<video src={url} alt={filename}
controls
loading="lazy"
width={metadata.width}
height={metadata.height}
onMouseDown={(ev) =>
ev.button === 1 && window.open(url, "_blank")
}
/>
</SizedGrid>
</div>
)
}
/*return (
2021-07-05 11:25:20 +01:00
<div
className={styles.container}
onClick={() => spoiler && setSpoiler(false)}>
{spoiler && (
<div className={styles.overflow}>
<span>
<Text id="app.main.channel.misc.spoiler_attachment" />
</span>
</div>
)}
<img
src={url}
alt={filename}
width={metadata.width}
height={metadata.height}
loading="lazy"
2021-07-05 11:25:20 +01:00
data-has-content={hasContent}
2021-07-10 15:21:35 +01:00
data-spoiler={spoiler}
2021-07-05 11:25:20 +01:00
className={classNames(
styles.attachment,
styles.image,
loaded && styles.loaded,
metadata.width > metadata.height
? styles.long
: styles.tall,
2021-07-05 11:25:20 +01:00
)}
style={{
"--width": metadata.width,
"--height": metadata.height,
"--width-px": metadata.width + "px",
"--height-px": metadata.height + "px",
}}
2021-07-05 11:25:20 +01:00
onClick={() =>
openScreen({ id: "image_viewer", attachment })
}
onMouseDown={(ev) =>
ev.button === 1 && window.open(url, "_blank")
}
2021-07-10 15:21:35 +01:00
onLoad={() => setLoaded(true)}
2021-07-05 11:25:20 +01:00
/>
</div>
);
2021-07-10 15:21:35 +01:00
}*/
2021-07-05 11:25:20 +01:00
case "Audio": {
return (
<div
className={classNames(styles.attachment, styles.audio)}
data-has-content={hasContent}>
<AttachmentActions attachment={attachment} />
<audio src={url} controls />
</div>
);
}
2021-07-10 15:21:35 +01:00
/*case "Video": {
2021-07-05 11:25:20 +01:00
return (
<div
className={styles.container}
onClick={() => spoiler && setSpoiler(false)}>
{spoiler && (
<div className={styles.overflow}>
<span>
<Text id="app.main.channel.misc.spoiler_attachment" />
</span>
</div>
)}
<div
data-spoiler={spoiler}
data-has-content={hasContent}
className={classNames(styles.attachment, styles.video)}>
<AttachmentActions attachment={attachment} />
<video
src={url}
width={metadata.width}
height={metadata.height}
loading="lazy"
className={classNames(
metadata.width > metadata.height
? styles.long
: styles.tall,
)}
style={{
"--width": metadata.width,
"--height": metadata.height,
"--width-px": metadata.width + "px",
"--height-px": metadata.height + "px",
}}
2021-07-05 11:25:20 +01:00
controls
onMouseDown={(ev) =>
ev.button === 1 && window.open(url, "_blank")
}
/>
</div>
</div>
);
2021-07-10 15:21:35 +01:00
}*/
2021-07-05 11:25:20 +01:00
case "Text": {
return (
<div
className={classNames(styles.attachment, styles.text)}
data-has-content={hasContent}>
<TextFile attachment={attachment} />
<AttachmentActions attachment={attachment} />
</div>
);
}
default: {
return (
<div
className={classNames(styles.attachment, styles.file)}
data-has-content={hasContent}>
<AttachmentActions attachment={attachment} />
</div>
);
}
}
2021-06-20 22:09:18 +01:00
}