Mention users in comments (#429)

Mention users in comments (#429)
This commit is contained in:
MrPercheul
2022-06-01 13:23:21 +02:00
committed by GitHub
parent cbc9633fe2
commit f6a78dd0b4
17 changed files with 194 additions and 24 deletions

View File

@@ -1,4 +1,5 @@
import React, { useState, useRef, useEffect } from 'react';
import { MentionsInput, Mention } from 'react-mentions';
import PropTypes from 'prop-types';
import { format } from 'timeago.js';
import { usePopup } from '../../utils/hooks/';
@@ -25,6 +26,7 @@ function CommentForm(props) {
const [madeChanges, setMadeChanges] = useState(false);
const [textareaFocused, setTextareaFocused] = useState(false);
const [textareaLineHeight, setTextareaLineHeight] = useState(-1);
const [userList, setUsersList] = useState('');
const [loginUrl] = useState(
!MemberContext._currentValue.is.anonymous
@@ -42,6 +44,17 @@ function CommentForm(props) {
setTextareaFocused(false);
}
function onUsersLoad()
{
const userList =[...MediaPageStore.get('users')];
const cleanList = []
userList.forEach(user => {
cleanList.push({id : user.username, display : user.name});
});
setUsersList(cleanList);
}
function onCommentSubmit() {
textareaRef.current.style.height = '';
@@ -61,6 +74,21 @@ function CommentForm(props) {
setMadeChanges(false);
}
function onChangeWithMention(event, newValue, newPlainTextValue, mentions) {
textareaRef.current.style.height = '';
setValue(newValue);
setMadeChanges(true);
const contentHeight = textareaRef.current.scrollHeight;
const contentLineHeight =
0 < textareaLineHeight ? textareaLineHeight : parseFloat(window.getComputedStyle(textareaRef.current).lineHeight);
setTextareaLineHeight(contentLineHeight);
textareaRef.current.style.height =
Math.max(20, textareaLineHeight * Math.ceil(contentHeight / contentLineHeight)) + 'px';
}
function onChange(event) {
textareaRef.current.style.height = '';
@@ -81,7 +109,7 @@ function CommentForm(props) {
return;
}
const val = textareaRef.current.value.trim();
const val = value.trim();
if ('' !== val) {
MediaPageActions.submitComment(val);
@@ -91,10 +119,18 @@ function CommentForm(props) {
useEffect(() => {
MediaPageStore.on('comment_submit', onCommentSubmit);
MediaPageStore.on('comment_submit_fail', onCommentSubmitFail);
if (MediaCMS.features.media.actions.comment_mention === true)
{
MediaPageStore.on('users_load', onUsersLoad);
}
return () => {
MediaPageStore.removeListener('comment_submit', onCommentSubmit);
MediaPageStore.removeListener('comment_submit_fail', onCommentSubmitFail);
if (MediaCMS.features.media.actions.comment_mention === true)
{
MediaPageStore.removeListener('users_load', onUsersLoad);
}
};
});
@@ -104,16 +140,33 @@ function CommentForm(props) {
<UserThumbnail />
<div className="form">
<div className={'form-textarea-wrap' + (textareaFocused ? ' focused' : '')}>
<textarea
ref={textareaRef}
className="form-textarea"
rows="1"
placeholder={'Add a ' + commentsText.single + '...'}
value={value}
onChange={onChange}
onFocus={onFocus}
onBlur={onBlur}
></textarea>
{ MediaCMS.features.media.actions.comment_mention ?
<MentionsInput
inputRef={textareaRef}
className="form-textarea"
rows="1"
placeholder={'Add a ' + commentsText.single + '...'}
value={value}
onChange={onChangeWithMention}
onFocus={onFocus}
onBlur={onBlur}>
<Mention
data={userList}
markup="@(___id___)[___display___]"
/>
</MentionsInput>
:
<textarea
ref={textareaRef}
className="form-textarea"
rows="1"
placeholder={'Add a ' + commentsText.single + '...'}
value={value}
onChange={onChange}
onFocus={onFocus}
onBlur={onBlur}
></textarea>
}
</div>
<div className="form-buttons">
<button className={'' === value.trim() ? 'disabled' : ''} onClick={submitComment}>
@@ -236,6 +289,10 @@ function Comment(props) {
};
}, []);
function parseComment(text) {
return { __html: text.replace(/\n/g, `<br />`) };
}
return (
<div className="comment">
<div className="comment-inner">
@@ -255,7 +312,7 @@ function Comment(props) {
<div
ref={commentTextInnerRef}
className="comment-text-inner"
dangerouslySetInnerHTML={{ __html: props.text }}
dangerouslySetInnerHTML={parseComment(props.text)}
></div>
</div>
{enabledViewMoreContent ? (
@@ -370,12 +427,25 @@ export default function CommentsList(props) {
function onCommentsLoad() {
const retrievedComments = [...MediaPageStore.get('media-comments')];
retrievedComments.forEach(comment => {
comment.text = setTimestampAnchors(comment.text);
if (MediaCMS.features.media.actions.comment_mention === true)
{
retrievedComments.forEach(comment => {
comment.text = setMentions(comment.text);
});
displayCommentsRelatedAlert();
setComments(retrievedComments);
}
retrievedComments.forEach(comment => {
comment.text = setTimestampAnchors(comment.text);
});
displayCommentsRelatedAlert();
setComments(retrievedComments);
}
function setMentions(text)
{
let sanitizedComment = text.split('@(_').join("<a href=\"/user/");
sanitizedComment = sanitizedComment.split('_)[_').join("\">");
return sanitizedComment.split('_]').join("</a>");
}
function setTimestampAnchors(text)