slate/components/core/SlateMediaObject.js

202 lines
4.7 KiB
JavaScript
Raw Normal View History

import * as React from "react";
import * as Constants from "~/common/constants";
2020-11-11 04:44:21 +03:00
import * as Validations from "~/common/validations";
2021-02-15 12:34:49 +03:00
import * as Events from "~/common/custom-events";
import * as Strings from "~/common/strings";
2020-11-17 15:53:15 +03:00
import UnityFrame from "~/components/core/UnityFrame";
2021-03-23 17:54:30 +03:00
import FontFrame from "~/components/core/FontFrame/index.js";
2021-02-16 21:03:59 +03:00
import MarkdownFrame from "~/components/core/MarkdownFrame";
2021-03-19 19:10:34 +03:00
import { endsWithAny } from "~/common/utilities";
2020-11-17 15:53:15 +03:00
2020-11-30 08:24:22 +03:00
import { css } from "@emotion/react";
const STYLES_FAILURE = css`
color: ${Constants.system.white};
display: flex;
align-items: center;
justify-content: center;
2021-05-06 03:08:14 +03:00
font-size: 24px;
margin: 0;
2021-05-06 03:08:14 +03:00
padding: 24px 36px;
height: 100px;
border-radius: 4px;
width: 100%;
min-height: 10%;
height: 100%;
2021-05-06 03:08:14 +03:00
text-decoration: none;
background-color: rgba(20, 20, 20, 0.8);
`;
const STYLES_OBJECT = css`
display: block;
margin: 0;
padding: 0;
width: 100%;
min-height: 10%;
height: 100%;
user-select: none;
`;
const STYLES_ASSET = css`
user-select: none;
width: 100%;
margin: 0;
padding: 0;
min-height: 10%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
`;
const STYLES_IMAGE = css`
user-select: none;
display: block;
max-width: 100%;
max-height: 100%;
`;
2021-03-18 18:14:39 +03:00
const STYLES_IFRAME = (theme) => css`
display: block;
width: 100%;
height: 100%;
// NOTE(Amine): lightbackground as fallback when html file doesn't have any
background-color: ${theme.system.wallLight};
`;
2020-09-16 12:16:46 +03:00
const typeMap = {
"video/quicktime": "video/mp4",
};
export default class SlateMediaObject extends React.Component {
openLink = (url) => {
window.open(url, "_blank");
};
componentDidMount() {
if (this.props.isMobile) {
const file = this.props.file;
if (file.data.type && file.data.type.startsWith("application/pdf")) {
const url = Strings.getURLfromCID(file.cid);
this.openLink(url);
}
}
}
render() {
const { file, isMobile } = this.props;
const url = Strings.getURLfromCID(file.cid);
const type = file.data.type || "";
2020-09-16 12:16:46 +03:00
const playType = typeMap[type] ? typeMap[type] : type;
2020-12-08 21:04:35 +03:00
let element = <div css={STYLES_FAILURE}>No Preview</div>;
2020-11-17 21:22:13 +03:00
2020-08-02 09:41:18 +03:00
if (type.startsWith("application/pdf")) {
return (
<>
{isMobile ? (
2021-05-06 03:08:14 +03:00
<a href={url} target="_blank" style={{ textDecoration: "none" }}>
<div css={STYLES_FAILURE}>Tap to open PDF in new tab</div>
</a>
) : (
<object
css={STYLES_OBJECT}
style={{ width: "calc(100% - 64px)" }}
data={url}
type={type}
key={url}
onClick={(e) => {
e.stopPropagation();
}}
/>
)}
</>
);
}
if (type.startsWith("video/")) {
2020-09-16 12:16:46 +03:00
return (
<video
playsInline
controls
autoPlay={false}
name="media"
type={playType}
css={STYLES_OBJECT}
key={url}
onClick={(e) => {
e.stopPropagation();
}}
>
2020-09-16 12:16:46 +03:00
<source src={url} type={playType} />
{/** NOTE(amine): fallback if video type isn't supported (example .mov) */}
2021-02-26 18:20:41 +03:00
<source src={url} type="video/mp4" />
</video>
);
}
if (type.startsWith("audio/")) {
2020-09-16 12:16:46 +03:00
return (
<div css={STYLES_ASSET}>
<audio
controls
name="media"
key={url}
onClick={(e) => {
e.stopPropagation();
}}
>
2020-09-16 12:16:46 +03:00
<source src={url} type={playType} />
</audio>
</div>
);
}
2021-03-18 18:14:39 +03:00
if (type.startsWith("text/html")) {
return <iframe src={url} css={STYLES_IFRAME} />;
}
2021-05-04 15:31:12 +03:00
if (Validations.isFontFile(file.filename)) {
2021-03-18 18:01:52 +03:00
return (
<FontFrame
name={file.data.name || file.filename}
cid={file.cid}
2021-04-08 22:00:09 +03:00
fallback={element}
2021-03-23 17:54:30 +03:00
onClick={(e) => {
e.stopPropagation();
}}
2021-03-18 18:01:52 +03:00
/>
);
}
2021-05-04 15:31:12 +03:00
if (Validations.isMarkdown(file.filename, type)) {
return <MarkdownFrame date={file.createdAt} url={url} />;
2021-02-15 20:23:56 +03:00
}
2020-11-11 04:44:21 +03:00
if (Validations.isPreviewableImage(type)) {
2020-09-16 12:16:46 +03:00
return (
<div css={STYLES_ASSET}>
<img
css={STYLES_IMAGE}
src={url}
onClick={(e) => {
e.stopPropagation();
}}
/>
</div>
);
}
2020-11-18 07:34:37 +03:00
// TODO(jim): We will need to revisit this later.
if (type.startsWith("application/unity")) {
const { config, loader } = file.data.unity;
2020-12-08 21:04:35 +03:00
return <UnityFrame url={url} unityGameConfig={config} unityGameLoader={loader} key={url} />;
2020-11-17 15:53:15 +03:00
}
return element;
}
}