diff options
author | Vitaly Takmazov | 2019-05-04 21:13:12 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2023-01-13 10:37:54 +0300 |
commit | f470636a70943a8ecad8bddc791a1c2dddd28e1e (patch) | |
tree | c43d109d88adbde9a696084070cdd92c6b9a004b /vnext/src/components/Thread.js | |
parent | 3d7d213e3ddc5bf4f71d536f31677b768aa3b7c0 (diff) |
Components -> UI
Diffstat (limited to 'vnext/src/components/Thread.js')
-rw-r--r-- | vnext/src/components/Thread.js | 181 |
1 files changed, 0 insertions, 181 deletions
diff --git a/vnext/src/components/Thread.js b/vnext/src/components/Thread.js deleted file mode 100644 index e7ccb032..00000000 --- a/vnext/src/components/Thread.js +++ /dev/null @@ -1,181 +0,0 @@ -import React, { useEffect, useState, useRef, useCallback } from 'react'; -import PropTypes from 'prop-types'; - -import ReactRouterPropTypes from 'react-router-prop-types'; -import { UserType, MessageType } from './Types'; - -import Message from './Message'; -import MessageInput from './MessageInput'; -import Spinner from './Spinner'; -import Avatar from './Avatar'; -import Button from './Button'; - -import { format, embedUrls } from '../utils/embed'; - -import { getMessages, comment, markReadTracker } from '../api'; - -function Comment({ msg, visitor, active, setActive, postComment }) { - 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"> - <div className="msg-header"> - <Avatar user={msg.user}> - <div className="msg-ts"> - {msg.replyto > 0 && - ( - <a href={`#${msg.replyto}`} className="info-avatar"><img src={msg.to.avatar} /> {msg.to.uname} </a> - )} - </div> - </Avatar> - </div> - { - msg.html ? <div className="msg-txt" dangerouslySetInnerHTML={{ __html: msg.body }} ref={msgRef} /> - : - <div className="msg-txt" ref={msgRef}> - <p dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid, (msg.tags || []).indexOf('code') >= 0) }} /> - </div> - } - { - msg.photo && - <div className="msg-media"> - <a href={`//i.juick.com/p/${msg.mid}-${msg.rid}.${msg.attach}`} data-fname={`${msg.mid}-${msg.rid}.${msg.attach}`}> - <img src={`//i.juick.com/p/${msg.mid}-${msg.rid}.${msg.attach}`} alt="" /> - </a> - </div> - } - <div className="embedContainer" ref={embedRef} /> - <div className="msg-links"> - { - visitor.uid > 0 ? ( - <> - {active === msg.rid || <span style={linkStyle} onClick={() => setActive(msg.rid)}>Reply</span>} - {active === msg.rid && <MessageInput data={msg} onSend={postComment}>Write a comment...</MessageInput>} - </> - ) : ( - <> - <span> · </span>{active === msg.rid || <Button>Reply</Button>} - </> - ) - } - </div> - </div> - ); -} - -Comment.propTypes = { - msg: MessageType.isRequired, - visitor: UserType.isRequired, - active: PropTypes.number.isRequired, - setActive: PropTypes.func.isRequired, - postComment: PropTypes.func.isRequired -}; - -export default function Thread(props) { - const [message, setMessage] = useState((props.location.state || {}).msg || {}); - const [replies, setReplies] = useState([]); - const [loading, setLoading] = useState(false); - const [active, setActive] = useState(0); - useEffect(() => { - setActive(0); - loadReplies(); - }, [loadReplies]); - useEffect(() => { - if (props.connection.addEventListener && message.mid) { - props.connection.addEventListener('msg', onReply); - } - return () => { - if (props.connection.removeEventListener && message.mid) { - props.connection.removeEventListener('msg', onReply); - } - }; - }, [props.connection, message.mid, onReply]); - - let loadReplies = useCallback(() => { - document.body.scrollTop = 0; - document.documentElement.scrollTop = 0; - - setReplies([]); - setLoading(true); - const { mid } = props.match.params; - let params = { - mid: mid - }; - if (props.visitor && props.visitor.hash) { - params.hash = props.visitor.hash; - } - getMessages('/api/thread', params) - .then(response => { - setMessage(response.data.shift()); - setReplies(response.data); - setLoading(false); - setActive(0); - } - ).catch(ex => { - console.log(ex); - }); - }, [props.visitor, props.match.params]); - let onReply = useCallback((json) => { - const msg = JSON.parse(json.data); - if (msg.mid == message.mid) { - setReplies(oldReplies => { - return [...oldReplies, msg]; - }); - } - }, [message]); - let postComment = (template) => { - const { mid, rid, body, attach } = template; - comment(mid, rid, body, attach).then(res => { - loadReplies(); - }) - .catch(console.log); - }; - - const loaders = Math.min(message.replies || 0, 10); - return ( - <> - { - message.mid ? ( - <Message data={message} visitor={props.visitor}> - {active === (message.rid || 0) && <MessageInput data={message} onSend={postComment}>Write a comment...</MessageInput>} - </Message> - ) : ( - <Spinner /> - ) - } - <ul id="replies"> - { - !loading ? replies.map((msg) => ( - <li id={msg.rid} key={msg.rid} className="msg"> - <Comment msg={msg} visitor={props.visitor} active={active} setActive={setActive} postComment={postComment} /> - </li> - )) : ( - <> - {Array(loaders).fill().map((it, i) => <Spinner key={i} />)} - </> - ) - } - </ul> - </> - ); -} - -const linkStyle = { - cursor: 'pointer' -}; - -Thread.propTypes = { - location: ReactRouterPropTypes.location, - history: ReactRouterPropTypes.history, - match: ReactRouterPropTypes.match, - visitor: UserType.isRequired, - connection: PropTypes.object.isRequired -}; |