diff options
author | Vitaly Takmazov | 2019-04-08 17:12:18 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2023-01-13 10:37:54 +0300 |
commit | 603c3960422fc9976d270cf8dc57afd245caa6e4 (patch) | |
tree | c4bcabc940546eb0d605d5815c6d69b24baad2e1 /vnext/src/components | |
parent | 820a5033db1a629f62d24fcfec2b2505abcb0b93 (diff) |
Embed links
Diffstat (limited to 'vnext/src/components')
-rw-r--r-- | vnext/src/components/Message.css | 51 | ||||
-rw-r--r-- | vnext/src/components/Message.js | 21 |
2 files changed, 66 insertions, 6 deletions
diff --git a/vnext/src/components/Message.css b/vnext/src/components/Message.css index 55bed2f2..1522c166 100644 --- a/vnext/src/components/Message.css +++ b/vnext/src/components/Message.css @@ -158,3 +158,54 @@ blockquote { font-size: x-large; margin: 0; } + +.embedContainer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + padding: 12px; + margin: 30px -3px 15px -3px; +} +.embedContainer > * { + box-sizing: border-box; + flex-grow: 1; + margin: 3px; + min-width: 49%; +} +.embedContainer > .compact { + flex-grow: 0; +} +.embedContainer .picture img { + display: block; +} +.embedContainer img, +.embedContainer video { + max-width: 100%; + max-height: 80vh; +} +.embedContainer > .audio, +.embedContainer > .youtube { + min-width: 90%; +} +.embedContainer audio { + width: 100%; +} +.embedContainer iframe { + overflow: hidden; + resize: vertical; + display: block; +} +.msg-cont .nsfw .embedContainer img, +.msg-cont .nsfw .embedContainer video, +.msg-cont .nsfw .embedContainer iframe, +.msg-cont .nsfw .ir img { + opacity: 0.1; +} +.msg-cont .nsfw .embedContainer img:hover, +.msg-cont .nsfw .embedContainer video:hover, +.msg-cont .nsfw .embedContainer iframe:hover, +.msg-cont .nsfw .ir img:hover { + opacity: 1; +} + diff --git a/vnext/src/components/Message.js b/vnext/src/components/Message.js index e27e057b..6c78b4bc 100644 --- a/vnext/src/components/Message.js +++ b/vnext/src/components/Message.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import moment from 'moment'; @@ -8,14 +8,24 @@ import Icon from './Icon'; import Avatar from './Avatar'; import { UserLink } from './UserInfo'; -import { format } from '../utils/embed'; +import { format, embedUrls } from '../utils/embed'; import './Message.css'; -function Message({ data, visitor, children, ...rest }) { +export default function Message({ data, visitor, children, ...rest }) { const isCode = (data.tags || []).indexOf('code') >= 0; const likesSummary = data.likes ? `${data.likes}` : 'Recommend'; const commentsSummary = data.replies ? `${data.replies}` : 'Comment'; + const embedRef = useRef(); + const msgRef = useRef(); + useEffect(() => { + if (msgRef.current) { + embedUrls(msgRef.current.querySelectorAll('a'), embedRef.current); + if (!embedRef.current.hasChildNodes()) { + embedRef.current.style.display = 'none'; + } + } + }, []); return ( <div className="msg-cont"> <Recommendations forMessage={data} /> @@ -34,7 +44,7 @@ function Message({ data, visitor, children, ...rest }) { </header> { data.body && - <div className="msg-txt"> + <div className="msg-txt" ref={msgRef}> <MessageContainer isCode={isCode} data={{ __html: format(data.body, data.mid, isCode) }} /> </div> } @@ -44,6 +54,7 @@ function Message({ data, visitor, children, ...rest }) { <img src={`//i.juick.com/photos-512/${data.mid}.${data.attach}`} alt="" /></a> </p> } + <div className="embedContainer" ref={embedRef} /> <nav className="l"> {visitor.uid === data.user.uid ? ( <Link to={{ pathname: `/${data.user.uname}/${data.mid}` }} className="a-like msg-button"> @@ -75,8 +86,6 @@ function Message({ data, visitor, children, ...rest }) { ); } -export default React.memo(Message); - function MessageContainer({ isCode, data }) { return isCode ? (<pre dangerouslySetInnerHTML={data} />) : (<p dangerouslySetInnerHTML={data} />); } |