aboutsummaryrefslogtreecommitdiff
path: root/vnext/src
diff options
context:
space:
mode:
Diffstat (limited to 'vnext/src')
-rw-r--r--vnext/src/ui/Thread.js64
-rw-r--r--vnext/src/ui/UserInfo.js4
2 files changed, 36 insertions, 32 deletions
diff --git a/vnext/src/ui/Thread.js b/vnext/src/ui/Thread.js
index ae5e4f3cf..cae601394 100644
--- a/vnext/src/ui/Thread.js
+++ b/vnext/src/ui/Thread.js
@@ -17,6 +17,17 @@ import './Thread.css';
let isMounted;
+/**
+ * @param {{
+ msg: import('../api').Message,
+ draft: string,
+ visitor: import('../api').User,
+ active: number,
+ setActive: function,
+ onStartEditing: function,
+ postComment: function
+ }} props
+ */
function Comment({ msg, draft, visitor, active, setActive, onStartEditing, postComment }) {
const embedRef = useRef();
const msgRef = useRef();
@@ -58,7 +69,7 @@ function Comment({ msg, draft, visitor, active, setActive, onStartEditing, postC
msg.body &&
<div style={bubbleStyle(visitor, msg)}>
<div ref={msgRef}>
- <p dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid, (msg.tags || []).indexOf('code') >= 0) }} />
+ <p dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid.toString(), (msg.tags || []).indexOf('code') >= 0) }} />
</div>
</div>
}
@@ -97,40 +108,38 @@ function Comment({ msg, draft, visitor, active, setActive, onStartEditing, postC
</div>
);
}
-/*
-Comment.propTypes = {
- msg: MessageType.isRequired,
- draft: PropTypes.string.isRequired,
- visitor: UserType.isRequired,
- active: PropTypes.number.isRequired,
- setActive: PropTypes.func.isRequired,
- onStartEditing: PropTypes.func.isRequired,
- postComment: PropTypes.func.isRequired
-};*/
+/**
+ * @param {{
+ match: import('react-router').match,
+ location: import('history').Location,
+ visitor: import('../api').SecureUser
+ connection: EventSource
+ }} props
+ */
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);
const [editing, setEditing] = useState({});
+ const [hash, setHash] = useState(props.visitor.hash);
+ const { mid } = props.match.params;
- let loadReplies = () => {
+ 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;
- }
+ params.hash = hash;
getMessages('/api/thread', params)
.then(response => {
- setMessage(response.data.shift());
+ if (!message.mid) {
+ setMessage(response.data.shift());
+ }
setReplies(response.data);
setLoading(false);
setActive(0);
@@ -138,7 +147,7 @@ export default function Thread(props) {
).catch(ex => {
console.log(ex);
});
- };
+ }, [hash, message.mid, mid]);
let onReply = useCallback((json) => {
const msg = JSON.parse(json.data);
if (msg.mid == message.mid) {
@@ -148,7 +157,7 @@ export default function Thread(props) {
}
}, [message]);
- let postComment = (template) => {
+ let postComment = useCallback((template) => {
const { mid, rid, body, attach } = template;
let commentAction = editing.rid ? update(mid, editing.rid, body) : comment(mid, rid, body, attach);
commentAction.then(res => {
@@ -156,7 +165,7 @@ export default function Thread(props) {
loadReplies();
})
.catch(console.log);
- };
+ }, [editing.rid, loadReplies]);
let startEditing = (reply) => {
setActive(reply.replyto);
@@ -166,7 +175,7 @@ export default function Thread(props) {
useEffect(() => {
setActive(0);
loadReplies();
- }, []);
+ }, [loadReplies]);
useEffect(() => {
if (props.connection.addEventListener && message.mid) {
props.connection.addEventListener('msg', onReply);
@@ -209,14 +218,9 @@ export default function Thread(props) {
);
}
+/**
+ * @type React.CSSProperties
+ */
const linkStyle = {
cursor: 'pointer'
};
-/*
-Thread.propTypes = {
- location: ReactRouterPropTypes.location,
- history: ReactRouterPropTypes.history,
- match: ReactRouterPropTypes.match,
- visitor: UserType.isRequired,
- connection: PropTypes.object.isRequired,
-};*/
diff --git a/vnext/src/ui/UserInfo.js b/vnext/src/ui/UserInfo.js
index faa2ebd63..6ff649315 100644
--- a/vnext/src/ui/UserInfo.js
+++ b/vnext/src/ui/UserInfo.js
@@ -39,7 +39,7 @@ export default function UserInfo(props) {
return () => {
isMounted = false;
};
- }, [onUpdate, user, user.avatar]);
+ }, [onUpdate, user, user.avatar, setUser]);
return (
<>
<div className="userinfo">
@@ -112,7 +112,7 @@ export function UserLink(props) {
return () => {
isMounted = false;
};
- }, [user.uid, user.uri]);
+ }, [user.uid, user.uri, setUser]);
return (
user.uid ?
<Link key={user.uid} to={`/${user.uname}/`} className="info-avatar"><img src={user.avatar} />{user.uname}</Link>