Made compontent more generic and replaced link finder function
This commit is contained in:
parent
522ca5beda
commit
7733baef00
2 changed files with 122 additions and 53 deletions
|
@ -16,6 +16,7 @@ import PlaySVG from '../../../../public/res/ic/outlined/play.svg';
|
|||
|
||||
import { getBlobSafeMimeType } from '../../../util/mimetypes';
|
||||
import initMatrix from '../../../client/initMatrix';
|
||||
import settings from '../../../client/state/settings';
|
||||
|
||||
async function getDecryptedBlob(response, type, decryptData) {
|
||||
const arrayBuffer = await response.arrayBuffer();
|
||||
|
@ -362,47 +363,19 @@ Video.propTypes = {
|
|||
blurhash: PropTypes.string,
|
||||
};
|
||||
|
||||
function YoutubeEmbed({ link }) {
|
||||
const url = new URL(link);
|
||||
|
||||
const [urlPreviewInfo, setUrlPreviewInfo] = useState(null);
|
||||
function IframePlayer({
|
||||
children, link, sitename, title, thumbnail,
|
||||
}) {
|
||||
const [videoStarted, setVideoStarted] = useState(false);
|
||||
|
||||
const mx = initMatrix.matrixClient;
|
||||
|
||||
const handlePlayVideo = () => {
|
||||
setVideoStarted(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let unmounted = false;
|
||||
|
||||
async function getThumbnail() {
|
||||
const info = await mx.getUrlPreview(link, 0);
|
||||
if (unmounted) return;
|
||||
|
||||
setUrlPreviewInfo(info);
|
||||
}
|
||||
|
||||
getThumbnail();
|
||||
|
||||
return () => {
|
||||
unmounted = true;
|
||||
};
|
||||
});
|
||||
|
||||
let embedURL = `https://www.youtube-nocookie.com/embed/${url.searchParams.get('v')}?autoplay=1`;
|
||||
if (url.searchParams.has('t')) {
|
||||
embedURL += `&start=${url.searchParams.get('t')}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="file-container">
|
||||
{urlPreviewInfo !== null && (
|
||||
<div>
|
||||
|
||||
<div className="file-header">
|
||||
<Text className="file-name" variant="b3">{`Youtube - ${urlPreviewInfo['og:title']}`}</Text>
|
||||
<Text className="file-name" variant="b3">{`${sitename} - ${title}`}</Text>
|
||||
|
||||
<IconButton
|
||||
size="extra-small"
|
||||
|
@ -415,30 +388,125 @@ function YoutubeEmbed({ link }) {
|
|||
<div
|
||||
className="video-container"
|
||||
>
|
||||
{!videoStarted && <img src={mx.mxcUrlToHttp(urlPreviewInfo['og:image'])} alt="Youtube thumbnail" />}
|
||||
{!videoStarted && <img src={thumbnail} alt={`${sitename} thumbnail`} />}
|
||||
{!videoStarted && <IconButton onClick={handlePlayVideo} tooltip="Play video" src={PlaySVG} />}
|
||||
|
||||
{videoStarted && (
|
||||
<div>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
IframePlayer.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
link: PropTypes.string.isRequired,
|
||||
sitename: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
thumbnail: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
function Embed({ link }) {
|
||||
const url = new URL(link);
|
||||
|
||||
if (settings.showYoutubeEmbedPlayer && (((url.host === 'www.youtube.com' || url.host === 'youtube.com') && url.pathname === '/watch') || url.host === 'youtu.be' || url.host === 'www.youtu.be')) {
|
||||
return <YoutubeEmbed link={link} />;
|
||||
}
|
||||
|
||||
// TODO: url preview
|
||||
// const [urlPreviewInfo, setUrlPreviewInfo] = useState(null);
|
||||
// const mx = initMatrix.matrixClient;
|
||||
|
||||
// useEffect(() => {
|
||||
// let unmounted = false;
|
||||
|
||||
// async function getThumbnail() {
|
||||
// const info = await mx.getUrlPreview(link, 0);
|
||||
// console.log('DEBUG', info);
|
||||
// if (unmounted) return;
|
||||
|
||||
// setUrlPreviewInfo(info);
|
||||
// }
|
||||
|
||||
// getThumbnail();
|
||||
|
||||
// return () => {
|
||||
// unmounted = true;
|
||||
// };
|
||||
// });
|
||||
|
||||
// if (urlPreviewInfo !== null) {
|
||||
// return <div>url preview here!/div>;
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
Embed.propTypes = {
|
||||
link: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
function YoutubeEmbed({ link }) {
|
||||
const [urlPreviewInfo, setUrlPreviewInfo] = useState(null);
|
||||
const mx = initMatrix.matrixClient;
|
||||
const url = new URL(link);
|
||||
|
||||
// fix for no embed information on www.youtu.be
|
||||
if (url.host === 'www.youtu.be') {
|
||||
url.host = 'youtu.be';
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let unmounted = false;
|
||||
|
||||
async function getThumbnail() {
|
||||
const info = await mx.getUrlPreview(url.toString(), 0);
|
||||
if (unmounted) return;
|
||||
|
||||
setUrlPreviewInfo(info);
|
||||
}
|
||||
|
||||
getThumbnail();
|
||||
|
||||
return () => {
|
||||
unmounted = true;
|
||||
};
|
||||
});
|
||||
|
||||
let videoID;
|
||||
if (url.host === 'youtu.be' || url.host === 'www.youtu.be') {
|
||||
videoID = url.pathname.slice(1);
|
||||
} else {
|
||||
videoID = url.searchParams.get('v');
|
||||
}
|
||||
|
||||
let embedURL = `https://www.youtube-nocookie.com/embed/${videoID}?autoplay=1`;
|
||||
if (url.searchParams.has('t')) { // timestamp flag
|
||||
embedURL += `&start=${url.searchParams.get('t')}`;
|
||||
}
|
||||
|
||||
if (urlPreviewInfo !== null) {
|
||||
return (
|
||||
<IframePlayer link={link} sitename="Youtube" title={urlPreviewInfo['og:title']} thumbnail={mx.mxcUrlToHttp(urlPreviewInfo['og:image'])}>
|
||||
<iframe
|
||||
src={embedURL}
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
/>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</IframePlayer>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
YoutubeEmbed.propTypes = {
|
||||
link: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export {
|
||||
File, Image, Sticker, Audio, Video, YoutubeEmbed,
|
||||
File, Image, Sticker, Audio, Video, YoutubeEmbed, Embed, IframePlayer,
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ import React, {
|
|||
import PropTypes from 'prop-types';
|
||||
import './Message.scss';
|
||||
|
||||
import { find } from 'linkifyjs';
|
||||
import { twemojify } from '../../../util/twemojify';
|
||||
|
||||
import initMatrix from '../../../client/initMatrix';
|
||||
|
@ -29,7 +30,6 @@ import IconButton from '../../atoms/button/IconButton';
|
|||
import Time from '../../atoms/time/Time';
|
||||
import ContextMenu, { MenuHeader, MenuItem, MenuBorder } from '../../atoms/context-menu/ContextMenu';
|
||||
import * as Media from '../media/Media';
|
||||
import settings from '../../../client/state/settings';
|
||||
|
||||
import ReplyArrowIC from '../../../../public/res/ic/outlined/reply-arrow.svg';
|
||||
import EmojiAddIC from '../../../../public/res/ic/outlined/emoji-add.svg';
|
||||
|
@ -42,7 +42,7 @@ import BinIC from '../../../../public/res/ic/outlined/bin.svg';
|
|||
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
|
||||
import { getBlobSafeMimeType } from '../../../util/mimetypes';
|
||||
import { html, plain } from '../../../util/markdown';
|
||||
import { YoutubeEmbed } from '../media/Media';
|
||||
import { Embed } from '../media/Media';
|
||||
|
||||
function PlaceholderMessage() {
|
||||
return (
|
||||
|
@ -718,8 +718,9 @@ function getEditedBody(editedMEvent) {
|
|||
return [parsedContent.body, isCustomHTML, newContent.formatted_body ?? null];
|
||||
}
|
||||
|
||||
function findYoutubeLinks(body) {
|
||||
return [...new Set(body.match(/https?:\/\/(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)[^ \n]+/g))] ?? [];
|
||||
function findLinks(body) {
|
||||
return find(body, 'url')
|
||||
.filter((v, i, a) => a.findIndex((v2) => (v2.href === v.href)) === i);
|
||||
}
|
||||
|
||||
function Message({
|
||||
|
@ -807,8 +808,8 @@ function Message({
|
|||
isEdited={isEdited}
|
||||
/>
|
||||
)}
|
||||
{settings.showYoutubeEmbedPlayer && findYoutubeLinks(body).map((link) => (
|
||||
<YoutubeEmbed key={link} link={link} />
|
||||
{findLinks(body).map((link) => (
|
||||
<Embed key={link.href} link={link.href} />
|
||||
))}
|
||||
{isEdit && (
|
||||
<MessageEdit
|
||||
|
|
Loading…
Reference in a new issue