From f470636a70943a8ecad8bddc791a1c2dddd28e1e Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 4 May 2019 21:13:12 +0300 Subject: Components -> UI --- vnext/src/ui/Message.js | 142 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 vnext/src/ui/Message.js (limited to 'vnext/src/ui/Message.js') diff --git a/vnext/src/ui/Message.js b/vnext/src/ui/Message.js new file mode 100644 index 00000000..eb008bfe --- /dev/null +++ b/vnext/src/ui/Message.js @@ -0,0 +1,142 @@ +import React, { useEffect, useRef } from 'react'; +import PropTypes from 'prop-types'; +import { Link } from 'react-router-dom'; +import moment from 'moment'; + +import { UserType, MessageType } from './Types'; +import Icon from './Icon'; +import Avatar from './Avatar'; +import { UserLink } from './UserInfo'; + +import { format, embedUrls } from '../utils/embed'; + +import './Message.css'; + +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 ( +
+ +
+ +
+ + + +
+
+ +
+ { + data.body && +
+ +
+ } + { + data.photo && +
+ + + +
+ } +
+ + {children} +
+ ); +} + +function MessageContainer({ isCode, data }) { + return isCode ? (
) : (

); +} + +function Tags({ data, user, ...rest }) { + return data.length > 0 && ( +

+ { + data.map(tag => { + return ({tag}); + }).reduce((prev, curr) => [prev, ', ', curr]) + } +
+ ); +} + +const TagsList = React.memo(Tags); + +function Recommends({ forMessage, ...rest }) { + const { likes, recommendations } = forMessage; + return recommendations && recommendations.length > 0 && ( +
{'♡ by '} + { + recommendations.map(it => ( + + )).reduce((prev, curr) => [prev, ', ', curr]) + } + { + likes > recommendations.length && ( and {likes - recommendations.length} others) + } +
+ ) || null; +} + +const Recommendations = React.memo(Recommends); + +Message.propTypes = { + data: MessageType, + visitor: UserType.isRequired, + children: PropTypes.node +}; + +MessageContainer.propTypes = { + isCode: PropTypes.bool.isRequired, + data: PropTypes.object.isRequired +}; + +Tags.propTypes = { + user: UserType.isRequired, + data: PropTypes.array +}; + -- cgit v1.2.3