2020-08-02 09:00:04 +03:00
|
|
|
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";
|
2021-03-07 23:53:54 +03:00
|
|
|
import * as Strings from "~/common/strings";
|
2021-07-07 23:50:57 +03:00
|
|
|
import * as Actions from "~/common/actions";
|
2020-08-02 09:00:04 +03:00
|
|
|
|
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-07-07 23:50:57 +03:00
|
|
|
import SlateLinkObject from "~/components/core/SlateLinkObject";
|
2020-11-17 15:53:15 +03:00
|
|
|
|
2020-11-30 08:24:22 +03:00
|
|
|
import { css } from "@emotion/react";
|
2020-08-02 09:00:04 +03:00
|
|
|
|
|
|
|
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;
|
2020-08-02 09:00:04 +03:00
|
|
|
margin: 0;
|
2021-05-06 03:08:14 +03:00
|
|
|
padding: 24px 36px;
|
|
|
|
height: 100px;
|
|
|
|
border-radius: 4px;
|
2020-08-02 09:00:04 +03:00
|
|
|
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);
|
2020-08-02 09:00:04 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
const STYLES_OBJECT = css`
|
|
|
|
display: block;
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
width: 100%;
|
|
|
|
min-height: 10%;
|
|
|
|
height: 100%;
|
2020-08-02 10:29:24 +03:00
|
|
|
user-select: none;
|
2020-08-02 09:00:04 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
const STYLES_ASSET = css`
|
2020-08-02 10:29:24 +03:00
|
|
|
user-select: none;
|
2020-08-02 09:00:04 +03:00
|
|
|
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`
|
2020-08-02 10:29:24 +03:00
|
|
|
user-select: none;
|
2020-08-02 09:00:04 +03:00
|
|
|
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
|
2021-07-07 22:58:14 +03:00
|
|
|
background-color: ${theme.system.grayLight6};
|
2021-03-18 18:14:39 +03:00
|
|
|
`;
|
|
|
|
|
2020-09-16 12:16:46 +03:00
|
|
|
const typeMap = {
|
|
|
|
"video/quicktime": "video/mp4",
|
|
|
|
};
|
|
|
|
|
2020-08-20 23:33:08 +03:00
|
|
|
export default class SlateMediaObject extends React.Component {
|
2021-02-15 12:04:02 +03:00
|
|
|
openLink = (url) => {
|
2021-03-07 23:53:54 +03:00
|
|
|
window.open(url, "_blank");
|
2021-02-15 12:04:02 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
componentDidMount() {
|
2021-07-07 23:50:57 +03:00
|
|
|
const file = this.props.file;
|
2021-03-07 23:53:54 +03:00
|
|
|
if (this.props.isMobile) {
|
|
|
|
if (file.data.type && file.data.type.startsWith("application/pdf")) {
|
|
|
|
const url = Strings.getURLfromCID(file.cid);
|
|
|
|
this.openLink(url);
|
|
|
|
}
|
|
|
|
}
|
2021-02-15 12:04:02 +03:00
|
|
|
}
|
|
|
|
|
2020-08-02 09:00:04 +03:00
|
|
|
render() {
|
2021-03-07 23:53:54 +03:00
|
|
|
const { file, isMobile } = this.props;
|
|
|
|
const type = file.data.type || "";
|
2021-07-13 07:27:23 +03:00
|
|
|
|
2021-07-07 23:50:57 +03:00
|
|
|
if (file.isLink) {
|
|
|
|
return <SlateLinkObject {...this.props} />;
|
|
|
|
}
|
|
|
|
|
|
|
|
const url = Strings.getURLfromCID(file.cid);
|
2020-09-16 12:16:46 +03:00
|
|
|
const playType = typeMap[type] ? typeMap[type] : type;
|
2020-12-08 21:04:35 +03:00
|
|
|
|
2020-08-21 10:07:39 +03:00
|
|
|
let element = <div css={STYLES_FAILURE}>No Preview</div>;
|
2020-11-17 21:22:13 +03:00
|
|
|
|
2021-07-07 23:50:57 +03:00
|
|
|
if (Validations.isPdfType(type)) {
|
2021-01-15 00:03:21 +03:00
|
|
|
return (
|
2021-02-15 12:04:02 +03:00
|
|
|
<>
|
2021-03-07 23:53:54 +03:00
|
|
|
{isMobile ? (
|
2021-05-06 03:08:14 +03:00
|
|
|
<a href={url} target="_blank" style={{ textDecoration: "none" }}>
|
2021-03-07 23:53:54 +03:00
|
|
|
<div css={STYLES_FAILURE}>Tap to open PDF in new tab</div>
|
|
|
|
</a>
|
|
|
|
) : (
|
2021-02-15 12:04:02 +03:00
|
|
|
<object
|
|
|
|
css={STYLES_OBJECT}
|
|
|
|
style={{ width: "calc(100% - 64px)" }}
|
|
|
|
data={url}
|
|
|
|
type={type}
|
|
|
|
key={url}
|
|
|
|
onClick={(e) => {
|
|
|
|
e.stopPropagation();
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</>
|
2021-01-15 00:03:21 +03:00
|
|
|
);
|
2020-08-02 09:00:04 +03:00
|
|
|
}
|
|
|
|
|
2021-07-07 23:50:57 +03:00
|
|
|
if (Validations.isVideoType(type)) {
|
2020-09-16 12:16:46 +03:00
|
|
|
return (
|
2021-01-15 00:03:21 +03:00
|
|
|
<video
|
|
|
|
playsInline
|
|
|
|
controls
|
2021-03-07 23:53:54 +03:00
|
|
|
autoPlay={false}
|
2021-01-15 00:03:21 +03:00
|
|
|
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} />
|
2021-03-07 23:53:54 +03:00
|
|
|
{/** 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" />
|
2020-08-02 10:29:24 +03:00
|
|
|
</video>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-07-07 23:50:57 +03:00
|
|
|
if (Validations.isAudioType(type)) {
|
2020-09-16 12:16:46 +03:00
|
|
|
return (
|
2020-08-04 06:15:24 +03:00
|
|
|
<div css={STYLES_ASSET}>
|
2021-01-15 00:03:21 +03:00
|
|
|
<audio
|
|
|
|
controls
|
|
|
|
name="media"
|
|
|
|
key={url}
|
|
|
|
onClick={(e) => {
|
|
|
|
e.stopPropagation();
|
|
|
|
}}
|
|
|
|
>
|
2020-09-16 12:16:46 +03:00
|
|
|
<source src={url} type={playType} />
|
2020-08-04 06:15:24 +03:00
|
|
|
</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
|
2021-03-07 23:53:54 +03:00
|
|
|
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)) {
|
2021-04-30 22:14:14 +03:00
|
|
|
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 (
|
2020-08-02 09:00:04 +03:00
|
|
|
<div css={STYLES_ASSET}>
|
2021-01-15 00:03:21 +03:00
|
|
|
<img
|
|
|
|
css={STYLES_IMAGE}
|
|
|
|
src={url}
|
|
|
|
onClick={(e) => {
|
|
|
|
e.stopPropagation();
|
|
|
|
}}
|
|
|
|
/>
|
2020-08-02 09:00:04 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-11-18 07:34:37 +03:00
|
|
|
// TODO(jim): We will need to revisit this later.
|
2021-07-07 23:50:57 +03:00
|
|
|
if (Validations.isUnityType(type)) {
|
2021-03-07 23:53:54 +03:00
|
|
|
const { config, loader } = file.data.unity;
|
2020-12-08 21:04:35 +03:00
|
|
|
|
2021-03-07 23:53:54 +03:00
|
|
|
return <UnityFrame url={url} unityGameConfig={config} unityGameLoader={loader} key={url} />;
|
2020-11-17 15:53:15 +03:00
|
|
|
}
|
|
|
|
|
2020-08-21 10:07:39 +03:00
|
|
|
return element;
|
2020-08-02 09:00:04 +03:00
|
|
|
}
|
|
|
|
}
|