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_"));
|
2021-07-09 11:09:55 -04:00
|
|
|
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}
|
2021-07-08 10:22:42 -04:00
|
|
|
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,
|
2021-07-09 11:09:55 -04:00
|
|
|
loaded && styles.loaded,
|
2021-07-08 10:22:42 -04:00
|
|
|
metadata.width > metadata.height
|
|
|
|
? styles.long
|
|
|
|
: styles.tall,
|
2021-07-05 11:25:20 +01:00
|
|
|
)}
|
2021-07-08 10:22:42 -04: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}
|
2021-07-08 10:22:42 -04:00
|
|
|
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
|
|
|
}
|