diff options
Diffstat (limited to 'vnext/src')
-rw-r--r-- | vnext/src/ui/Message.js | 42 | ||||
-rw-r--r-- | vnext/src/ui/Thread.js | 24 |
2 files changed, 54 insertions, 12 deletions
diff --git a/vnext/src/ui/Message.js b/vnext/src/ui/Message.js index d45395bb..3bb59a4a 100644 --- a/vnext/src/ui/Message.js +++ b/vnext/src/ui/Message.js @@ -15,8 +15,15 @@ import { format, embedUrls } from '../utils/embed'; import { useVisitor } from './VisitorContext'; /** + * @callback ToggleSubscriptionCallback + * @param { import('../client').Message } message + */ + +/** * @typedef {object} MessageProps * @property { import('../client').Message } data data + * @property {boolean} isThread + * @property {ToggleSubscriptionCallback} onToggleSubscription */ /** @@ -24,7 +31,7 @@ import { useVisitor } from './VisitorContext'; * * @param {React.PropsWithChildren<{}> & MessageProps} props props */ -export default function Message({ data, children }) { +export default function Message({ data, isThread = false, onToggleSubscription, children }) { const [visitor] = useVisitor(); const isCode = (data.tags || []).indexOf('code') >= 0; const likesSummary = data.likes ? `${data.likes}` : 'Recommend'; @@ -68,7 +75,7 @@ export default function Message({ data, children }) { <span> · </span> <Link to={{ pathname: '/post', - }} state={{data: data}}>Edit</Link> + }} state={{ data: data }}>Edit</Link> </> } </div> @@ -109,16 +116,31 @@ export default function Message({ data, children }) { <span>{likesSummary}</span> </Link> )} - {data.user && canComment && ( - <Link to={`/${data.user.uname}/${data.mid}`} className="a-comment msg-button" - state={{ data: data }}> - <Icon name="ei-comment" size="s" /> - <span>{commentsSummary}</span> - </Link> - )} + { + data.user && canComment && (( + isThread ? ( + <Link className="msg-button" onClick={() => { onToggleSubscription(data); }}> + { + data.subscribed ? (<> + <Icon name="ei-check" size="s" /> + <span>Subscribed</span> + </>) : (<> + <Icon name="ei-eye" size="s" /> + <span>Subscribe</span> + </>)} + </Link> + ) : ( + <Link to={`/${data.user.uname}/${data.mid}`} className="a-comment msg-button" + state={{ data: data }}> + <Icon name="ei-comment" size="s" /> + <span>{commentsSummary}</span> + </Link> + ) + )) + } </nav> {children} - </div> + </div > ); } diff --git a/vnext/src/ui/Thread.js b/vnext/src/ui/Thread.js index de1d74b2..2919e830 100644 --- a/vnext/src/ui/Thread.js +++ b/vnext/src/ui/Thread.js @@ -6,7 +6,7 @@ import Message from './Message'; import MessageInput from './MessageInput'; import Spinner from './Spinner'; -import { getMessages, comment, update } from '../api'; +import { getMessages, comment, update, post } from '../api'; import { useVisitor } from './VisitorContext'; import { Helmet } from 'react-helmet'; /** @@ -104,6 +104,26 @@ export default function Thread(props) { const loaders = Math.min(message.replies || 0, 10); const pageTitle = `${params.user} ${message && message.tags || 'thread'}`; + /** @type { import('./Message').ToggleSubscriptionCallback } */ + const handleSubsciptionToggle = (message) => { + if (message.subscribed) { + if (confirm('Unsubscribe?')) { + post(`U #${message.mid}`).then((response) => { + if (response.status === 200) { + setMessage({...message, subscribed: false}); + } + }).catch(console.error); + } + } else { + if (confirm('Subscribe?')) { + post(`S #${message.mid}`).then((response) => { + if (response.status === 200) { + setMessage({...message, subscribed: true}); + } + }).catch(console.error); + } + } + }; return ( <> <Helmet> @@ -111,7 +131,7 @@ export default function Thread(props) { </Helmet> { message.mid ? ( - <Message data={message}> + <Message key={message.mid} data={message} isThread={true} onToggleSubscription={handleSubsciptionToggle}> {active === (message.rid || 0) && <MessageInput data={message} text={editing.body || ''} onSend={postComment}>Write a comment...</MessageInput>} </Message> ) : ( |