debounce comment reacts on backend, not button, feedback immediate

This commit is contained in:
jessop 2020-10-01 20:25:30 -04:00 committed by Sean Yesmunt
parent ec3a763f5d
commit aa127e45aa
3 changed files with 29 additions and 17 deletions

View file

@ -1,16 +1,11 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import Comment from './view'; import Comment from './view';
import { import { makeSelectMyReactionsForComment, makeSelectOthersReactionsForComment } from 'redux/selectors/comments';
makeSelectMyReactionsForComment,
makeSelectOthersReactionsForComment,
selectPendingCommentReacts,
} from 'redux/selectors/comments';
import { doCommentReact } from 'redux/actions/comments'; import { doCommentReact } from 'redux/actions/comments';
const select = (state, props) => ({ const select = (state, props) => ({
myReacts: makeSelectMyReactionsForComment(props.commentId)(state), myReacts: makeSelectMyReactionsForComment(props.commentId)(state),
othersReacts: makeSelectOthersReactionsForComment(props.commentId)(state), othersReacts: makeSelectOthersReactionsForComment(props.commentId)(state),
pendingCommentReacts: selectPendingCommentReacts(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({

View file

@ -15,7 +15,7 @@ type Props = {
}; };
export default function CommentReactions(props: Props) { export default function CommentReactions(props: Props) {
const { myReacts, othersReacts, commentId, react, pendingCommentReacts } = props; const { myReacts, othersReacts, commentId, react } = props;
const [activeChannel] = usePersistedState('comment-channel'); const [activeChannel] = usePersistedState('comment-channel');
const getCountForReact = type => { const getCountForReact = type => {
@ -38,7 +38,7 @@ export default function CommentReactions(props: Props) {
className={classnames('comment__action', { className={classnames('comment__action', {
'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.LIKE), 'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.LIKE),
})} })}
disabled={!activeChannel || pendingCommentReacts.includes(commentId + REACTION_TYPES.LIKE)} disabled={!activeChannel}
onClick={() => react(commentId, REACTION_TYPES.LIKE)} onClick={() => react(commentId, REACTION_TYPES.LIKE)}
label={getCountForReact(REACTION_TYPES.LIKE)} label={getCountForReact(REACTION_TYPES.LIKE)}
/> />
@ -49,7 +49,7 @@ export default function CommentReactions(props: Props) {
className={classnames('comment__action', { className={classnames('comment__action', {
'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.DISLIKE), 'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.DISLIKE),
})} })}
disabled={!activeChannel || pendingCommentReacts.includes(commentId + REACTION_TYPES.DISLIKE)} disabled={!activeChannel}
onClick={() => react(commentId, REACTION_TYPES.DISLIKE)} onClick={() => react(commentId, REACTION_TYPES.DISLIKE)}
label={getCountForReact(REACTION_TYPES.DISLIKE)} label={getCountForReact(REACTION_TYPES.DISLIKE)}
/> />

View file

@ -103,7 +103,7 @@ export function doCommentReact(commentId: string, type: string) {
}); });
return; return;
} }
if (pendingReacts.includes(commentId + exclusiveTypes[type])) { if (pendingReacts.includes(commentId + exclusiveTypes[type]) || pendingReacts.includes(commentId + type)) {
// ignore dislikes during likes, for example // ignore dislikes during likes, for example
return; return;
} }
@ -134,31 +134,48 @@ export function doCommentReact(commentId: string, type: string) {
type: ACTIONS.COMMENT_REACT_STARTED, type: ACTIONS.COMMENT_REACT_STARTED,
data: commentId + type, data: commentId + type,
}); });
// simulate api return shape: ['like'] -> { 'like': 1 } // simulate api return shape: ['like'] -> { 'like': 1 }
const myReactsObj = myReacts.reduce((acc, el) => { const myReactsObj = myReacts.reduce((acc, el) => {
acc[el] = 1; acc[el] = 1;
return acc; return acc;
}, {}); }, {});
dispatch({
type: ACTIONS.COMMENT_REACTION_LIST_COMPLETED,
data: {
myReactions: { [commentId]: myReactsObj },
othersReactions: { [commentId]: othersReacts },
},
});
Lbry.comment_react(params) Lbry.comment_react(params)
.then((result: CommentReactListResponse) => { .then((result: CommentReactListResponse) => {
dispatch({ dispatch({
type: ACTIONS.COMMENT_REACT_COMPLETED, type: ACTIONS.COMMENT_REACT_COMPLETED,
data: commentId + type, data: commentId + type,
}); });
dispatch({
type: ACTIONS.COMMENT_REACTION_LIST_COMPLETED,
data: {
myReactions: { [commentId]: myReactsObj },
othersReactions: { [commentId]: othersReacts },
},
});
}) })
.catch(error => { .catch(error => {
dispatch({ dispatch({
type: ACTIONS.COMMENT_REACT_FAILED, type: ACTIONS.COMMENT_REACT_FAILED,
data: commentId + type, data: commentId + type,
}); });
const myRevertedReactsObj = myReacts
.filter(el => el !== type)
.reduce((acc, el) => {
acc[el] = 1;
return acc;
}, {});
dispatch({
type: ACTIONS.COMMENT_REACTION_LIST_COMPLETED,
data: {
myReactions: { [commentId]: myRevertedReactsObj },
othersReactions: { [commentId]: othersReacts },
},
});
}); });
}; };
} }