aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2018-06-18 17:07:00 +0300
committerGravatar Vitaly Takmazov2023-01-13 10:37:52 +0300
commit94cb8eaecbca57b104061943ea0670fc618e4236 (patch)
treee8062294a2466e8548abf91454b495cbfe8f61a8
parent2e6771c6a7b01fada5bd1792b33ba97a4438c01d (diff)
Thread replies
-rw-r--r--vnext/src/components/Message.js12
-rw-r--r--vnext/src/components/Thread.js145
2 files changed, 139 insertions, 18 deletions
diff --git a/vnext/src/components/Message.js b/vnext/src/components/Message.js
index 53c2a033..5667047c 100644
--- a/vnext/src/components/Message.js
+++ b/vnext/src/components/Message.js
@@ -12,7 +12,7 @@ export default function Message(props) {
const msg = props.data;
const visitor = props.visitor;
return (
- <article itemProp="blogPost" itemScope="" itemType="http://schema.org/BlogPosting" itemRef="org">
+ <div className="msg-cont" itemProp="blogPost" itemScope="" itemType="http://schema.org/BlogPosting" itemRef="org">
<header className="h">
<span itemProp="author" itemScope="" itemType="http://schema.org/Person">
<a href={`/${msg.user.uname}/`} itemProp="url" rel="author"><span itemProp="name">{msg.user.uname}</span></a>
@@ -30,7 +30,9 @@ export default function Message(props) {
<Tags data={msg.tags || []} />
</div>
</header>
- <p itemProp="description" dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid, (msg.tags || []).indexOf('code') >= 0) }}></p>
+ <div className="msg-txt">
+ <p itemProp="description" dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid, (msg.tags || []).indexOf('code') >= 0) }}></p>
+ </div>
{msg.photo &&
<p className="ir"><a href={`//i.juick.com/p/${msg.mid}.${msg.attach}`} data-fname={`${msg.mid}.${msg.attach}`}>
<img itemProp="image" src={`//i.juick.com/p/${msg.mid}.${msg.attach}`} alt="" /></a>
@@ -87,7 +89,8 @@ export default function Message(props) {
<a href="#" className="a-privacy">Открыть доступ</a>
)}
</nav>
- </article>
+ {props.children}
+ </div>
);
}
@@ -103,7 +106,8 @@ Message.propTypes = {
user: UserType,
timestamp: PropTypes.string.isRequired,
body: PropTypes.string
- })
+ }),
+ children: PropTypes.node
};
Tags.propTypes = {
diff --git a/vnext/src/components/Thread.js b/vnext/src/components/Thread.js
index 16a662cc..9b26e378 100644
--- a/vnext/src/components/Thread.js
+++ b/vnext/src/components/Thread.js
@@ -1,23 +1,29 @@
import React from 'react';
import * as qs from 'query-string';
+import moment from 'moment';
import Message from './Message';
import Spinner from './Spinner';
+import Avatar from './Avatar';
+
+import { format } from '../utils/embed';
export default class Thread extends React.Component {
constructor(props) {
super(props);
this.state = {
+ msg: {},
replies: []
};
+ this.loaded = this.loaded.bind(this);
}
componentDidMount() {
this.loadReplies();
}
loadReplies() {
- this.setState({ replies: []})
+ this.setState({ replies: [] })
const { mid } = this.props.match.params;
- let params = {
+ let params = {
mid: mid
}
if (this.props.visitor && this.props.visitor.hash) {
@@ -25,20 +31,131 @@ export default class Thread extends React.Component {
};
const url = `https://api.juick.com/thread?${qs.stringify(params)}`;
fetch(url)
- .then(response => {
- return response.json()
+ .then(response => {
+ return response.json()
+ })
+ .then(data => {
+ let msg = data.shift();
+ this.setState({
+ msg: msg,
+ replies: data
})
- .then(data =>
- this.setState({ replies: data })
- ).catch(ex => {
- console.log(ex);
- });
+ }
+ ).catch(ex => {
+ console.log(ex);
+ });
+ }
+ loaded() {
+ return this.state.msg.mid;
}
render() {
- return this.state.replies && this.state.replies.length > 0 ? (
- <Message data={this.state.replies[0]} visitor={this.props.visitor}/>
- ) : (
- <Spinner />
- );
+ const msg = this.state.msg;
+ return (
+ <React.Fragment>
+ <ul id="0">
+ <li className="msg msgthread">
+ {
+ this.loaded() ? (
+ <Message data={msg} visitor={this.props.visitor}>
+ <form className="msg-comment-target">
+ <input type="hidden" name="mid" value={msg.mid} />
+ <div className="msg-comment">
+ <div className="ta-wrapper">
+ <textarea name="body" rows="1" className="reply" placeholder="Write a comment..."></textarea>
+ </div>
+ </div>
+ </form>
+ {
+ msg.recomm && (
+ <div className="msg-recomms">{`Recommended by (${msg.recomm.length}):`}
+ {
+ msg.recomm.map((it, index) => (
+ <a href="/{{ it }}/">{it}</a>
+ ))
+ }
+ </div>
+ )
+ }
+ </Message>
+ ) : (
+ <Spinner />
+ )
+ }
+ </li>
+ </ul>
+ {
+ this.loaded() && (
+ <React.Fragment>
+ <div className="title2">
+ {
+ this.props.visitor.uid > 0 &&
+ <img src={`https://api.juick.com/thread/mark_read/${msg.mid}-${msg.rid || 0}.gif?hash=${this.props.visitor.hash}`} />
+ }
+ <h2>{`Replies (${msg.replies})`}</h2>
+ </div>
+ <ul id="replies">
+ {
+ this.state.replies.map((msg) => (
+ <li id={msg.rid} key={msg.rid} className="msg">
+ <div className="msg-cont">
+ <div className="msg-header">
+ {!msg.user.banned ? (
+ <React.Fragment>
+ <span itemProp="author" itemScope="" itemType="http://schema.org/Person">
+ <a href={`/${msg.user.uname}/`} itemProp="url" rel="author"><span itemProp="name">{msg.user.uname}</span></a>
+ </span><Avatar user={msg.user} />
+ </React.Fragment>) : (
+ <React.Fragment>
+ <span>[удалено]:</span><Avatar user={{ uid: 0 }} />
+ </React.Fragment>
+ )}
+ <div className="msg-ts">
+ <a href={`/${msg.user.uname}/${msg.mid}`}>
+ <time itemProp="datePublished dateModified" itemType="http://schema.org/Date" dateTime={msg.timestamp}
+ title={moment.utc(msg.timestamp).local().format('lll')}>
+ {moment.utc(msg.timestamp).fromNow()}
+ </time>
+ </a>
+ </div>
+ </div>
+ <div className="msg-txt"><p dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid, (msg.tags || []).indexOf('code') >= 0) }}></p></div>
+ {
+ msg.photo &&
+ <p className="ir"><a href={`//i.juick.com/p/${msg.mid}.${msg.attach}`} data-fname={`${msg.mid}.${msg.attach}`}>
+ <img itemProp="image" src={`//i.juick.com/p/${msg.mid}.${msg.attach}`} alt="" /></a>
+ </p>
+ }
+ <div className="msg-links">{`/${msg.rid}`}&nbsp;
+ {
+ msg.replyto > 0 &&
+ (
+ <a href={`#${msg.replyto}`}> in reply to {msg.to.uname}&nbsp;</a>
+ )
+ }
+ {
+ this.props.visitor.uid > 0 ? (
+ <React.Fragment>
+ <span>&middot; </span>
+ <a href={`/post?body=%23${msg.mid}/${msg.rid}%20`} className="a-thread-comment">Reply</a>
+ <div className="msg-comment-target msg-comment-hidden"></div>
+ </React.Fragment>
+ ) : (
+ <React.Fragment>
+ <span>&nbsp;&middot; </span><a href="#" className="a-login">Reply</a>
+ </React.Fragment>
+ )
+ }
+ </div>
+ </div>
+ </li>
+ ))
+ }
+ </ul>
+ </React.Fragment>
+ )
+ }
+ </React.Fragment>
+ )
+
}
}