diff options
Diffstat (limited to 'vnext/src')
-rw-r--r-- | vnext/src/components/MessageInput.js | 2 | ||||
-rw-r--r-- | vnext/src/components/Thread.js | 182 |
2 files changed, 85 insertions, 99 deletions
diff --git a/vnext/src/components/MessageInput.js b/vnext/src/components/MessageInput.js index 5ace3317..311284cf 100644 --- a/vnext/src/components/MessageInput.js +++ b/vnext/src/components/MessageInput.js @@ -21,7 +21,7 @@ export default function MessageInput({ text, data, rows, children, onSend }) { } }; useEffect(() => { - textareaRef.current.value = text; + textareaRef.current.value = text || ''; updateFocus(); }, []); diff --git a/vnext/src/components/Thread.js b/vnext/src/components/Thread.js index 6d8a5fd3..4946cf5f 100644 --- a/vnext/src/components/Thread.js +++ b/vnext/src/components/Thread.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import ReactRouterPropTypes from 'react-router-prop-types'; import { UserType } from './Types'; @@ -16,133 +16,119 @@ import { format } from '../utils/embed'; import { getMessages, comment, markReadTracker } from '../api'; -export default class Thread extends React.Component { - constructor(props) { - super(props); - const { msg } = (this.props.location.state || {}); - this.state = { - msg: msg || {}, - replies: [], - loading: false, - active: 0 - }; - } - componentDidMount() { - this.loadReplies(); - } - loadReplies() { +export default function Thread(props) { + const [message, setMessage] = useState(props.location.state || {}); + const [replies, setReplies] = useState([]); + const [loading, setLoading] = useState(false); + const [active, setActive] = useState(0); + useEffect(() => { + setActive(0); + loadReplies(); + }, []); + let loadReplies = () => { document.body.scrollTop = 0; document.documentElement.scrollTop = 0; - this.setState({ replies: [], loading: true }); - const { mid } = this.props.match.params; + + setReplies([]); + setLoading(true); + const { mid } = props.match.params; let params = { mid: mid }; - if (this.props.visitor && this.props.visitor.hash) { - params.hash = this.props.visitor.hash; + if (props.visitor && props.visitor.hash) { + params.hash = props.visitor.hash; } getMessages('/api/thread', params) .then(response => { - let msg = response.data.shift(); - this.setState({ - msg: { ...msg }, - replies: response.data, - loading: false, - active: 0 - }); + setMessage(response.data.shift()); + setReplies(response.data); + setLoading(false); + setActive(0); } ).catch(ex => { console.log(ex); }); } - setActive(msg, event) { - this.setState({ - active: msg.rid || 0 - }); - } - onReply = (msg) => { - if (msg.mid == this.state.msg.mid) { + let onReply = (msg) => { + if (msg.mid == message.mid) { this.setState({ replies: [...this.state.replies, msg] }); } } - postComment = (template) => { + let postComment = (template) => { const { mid, rid, body, attach } = template; comment(mid, rid, body, attach).then(res => { - this.loadReplies(); + loadReplies(); }) .catch(console.log); } - render() { - const msg = this.state.msg; - const loaders = Math.min(msg.replies || 0, 10); - return ( - <> + 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"> { - msg.mid ? ( - <Message data={msg} visitor={this.props.visitor}> - {this.state.active === (msg.rid || 0) && <MessageInput data={msg} onSend={this.postComment}>Write a comment...</MessageInput>} - </Message> - ) : ( - <Spinner /> - ) - } - <ul id="replies"> - { - !this.state.loading ? this.state.replies.map((msg) => ( - <li id={msg.rid} key={msg.rid} className="msg"> - <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 }}/> - : - <div className="msg-txt"> - <p dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid, (msg.tags || []).indexOf('code') >= 0) }} /> + !loading ? replies.map((msg) => ( + <li id={msg.rid} key={msg.rid} className="msg"> + <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 }} /> + : + <div className="msg-txt"> + <p dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid, (msg.tags || []).indexOf('code') >= 0) }} /> + </div> + } + { + msg.photo && + <p className="ir"><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> + </p> + } + <div className="msg-links"> { - msg.photo && - <p className="ir"><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> - </p> - } - <div className="msg-links"> - { - this.props.visitor.uid > 0 ? ( + props.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>} + </> + ) : ( <> - {this.state.active === msg.rid || <span style={linkStyle} onClick={() => this.setActive(msg)}>Reply</span>} - {this.state.active === msg.rid && <MessageInput data={msg} onSend={this.postComment}>Write a comment...</MessageInput>} + <span> · </span>{active === msg.rid || <Button>Reply</Button>} </> - ) : ( - <> - <span> · </span>{this.state.active === msg.rid || <Button>Reply</Button>} - </> - ) - } - </div> + ) + } </div> - </li> - )) : ( - <> - {Array(loaders).fill().map((it, i) => <Spinner key={i} />)} - </> - ) - } - </ul> - </> - ); - } + </div> + </li> + )) : ( + <> + {Array(loaders).fill().map((it, i) => <Spinner key={i} />)} + </> + ) + } + </ul> + </> + ); } const linkStyle = { |