From 3644eed49bea225e8ad948c8c7943d202f8c8d6c Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 16 Mar 2021 14:37:19 -0400 Subject: [PATCH] fix first livestream comment not being displayed --- ui/component/commentCreate/index.js | 3 +- ui/component/livestreamComments/view.jsx | 4 +- ui/redux/actions/comments.js | 9 ++- ui/redux/actions/websocket.js | 4 +- ui/redux/reducers/comments.js | 82 +++++++++++++++++++----- 5 files changed, 79 insertions(+), 23 deletions(-) diff --git a/ui/component/commentCreate/index.js b/ui/component/commentCreate/index.js index 2f69ff259..35e1cb734 100644 --- a/ui/component/commentCreate/index.js +++ b/ui/component/commentCreate/index.js @@ -24,7 +24,8 @@ const select = (state, props) => ({ }); const perform = (dispatch, ownProps) => ({ - createComment: (comment, claimId, parentId) => dispatch(doCommentCreate(comment, claimId, parentId, ownProps.uri)), + createComment: (comment, claimId, parentId) => + dispatch(doCommentCreate(comment, claimId, parentId, ownProps.uri, ownProps.livestream)), openModal: (modal, props) => dispatch(doOpenModal(modal, props)), setActiveChannel: (claimId) => dispatch(doSetActiveChannel(claimId)), toast: (message) => dispatch(doToast({ message, isError: true })), diff --git a/ui/component/livestreamComments/view.jsx b/ui/component/livestreamComments/view.jsx index f00625b2c..33305e34e 100644 --- a/ui/component/livestreamComments/view.jsx +++ b/ui/component/livestreamComments/view.jsx @@ -12,7 +12,7 @@ type Props = { claim: ?StreamClaim, activeViewers: number, embed?: boolean, - doCommentSocketConnect: (string) => void, + doCommentSocketConnect: (string, string) => void, doCommentList: (string) => void, comments: Array, fetchingComments: boolean, @@ -29,7 +29,7 @@ export default function LivestreamFeed(props: Props) { React.useEffect(() => { if (claimId) { doCommentList(uri); - doCommentSocketConnect(claimId); + doCommentSocketConnect(uri, claimId); } }, [claimId, uri]); diff --git a/ui/redux/actions/comments.js b/ui/redux/actions/comments.js index 6683b2b2f..e5737c8c2 100644 --- a/ui/redux/actions/comments.js +++ b/ui/redux/actions/comments.js @@ -196,7 +196,13 @@ export function doCommentReact(commentId: string, type: string) { }; } -export function doCommentCreate(comment: string = '', claim_id: string = '', parent_id?: string, uri: string) { +export function doCommentCreate( + comment: string = '', + claim_id: string = '', + parent_id?: string, + uri: string, + livestream?: boolean = false +) { return (dispatch: Dispatch, getState: GetState) => { const state = getState(); const activeChannelClaim = selectActiveChannelClaim(state); @@ -228,6 +234,7 @@ export function doCommentCreate(comment: string = '', claim_id: string = '', par type: ACTIONS.COMMENT_CREATE_COMPLETED, data: { uri, + livestream, comment: result, claimId: claim_id, }, diff --git a/ui/redux/actions/websocket.js b/ui/redux/actions/websocket.js index 3651a97e1..fc76c35e5 100644 --- a/ui/redux/actions/websocket.js +++ b/ui/redux/actions/websocket.js @@ -55,7 +55,7 @@ export const doNotificationSocketConnect = () => (dispatch) => { }); }; -export const doCommentSocketConnect = (claimId) => (dispatch) => { +export const doCommentSocketConnect = (uri, claimId) => (dispatch) => { const url = `wss://comments.lbry.com/api/v2/live-chat/subscribe?subscription_id=${claimId}`; doSocketConnect(url, (response) => { @@ -63,7 +63,7 @@ export const doCommentSocketConnect = (claimId) => (dispatch) => { const newComment = response.data.comment; dispatch({ type: ACTIONS.COMMENT_RECEIVED, - data: { comment: newComment, claimId }, + data: { comment: newComment, claimId, uri }, }); } }); diff --git a/ui/redux/reducers/comments.js b/ui/redux/reducers/comments.js index ed199cb60..9307a698f 100644 --- a/ui/redux/reducers/comments.js +++ b/ui/redux/reducers/comments.js @@ -7,6 +7,9 @@ const defaultState: CommentsState = { byId: {}, // ClaimID -> list of comments repliesByParentId: {}, // ParentCommentID -> list of reply comments topLevelCommentsById: {}, // ClaimID -> list of top level comments + // TODO: + // Remove commentsByUri + // It is not needed and doesn't provide anything but confusion commentsByUri: {}, // URI -> claimId isLoading: false, isCommenting: false, @@ -35,7 +38,12 @@ export default handleActions( }), [ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => { - const { comment, claimId, uri }: { comment: Comment, claimId: string, uri: string } = action.data; + const { + comment, + claimId, + uri, + livestream, + }: { comment: Comment, claimId: string, uri: string, livestream: boolean } = action.data; const commentById = Object.assign({}, state.commentById); const byId = Object.assign({}, state.byId); const topLevelCommentsById = Object.assign({}, state.topLevelCommentsById); // was byId {ClaimId -> [commentIds...]} @@ -44,27 +52,31 @@ export default handleActions( const comments = byId[claimId] || []; const newCommentIds = comments.slice(); - // add the comment by its ID - commentById[comment.comment_id] = comment; + // If it was created during a livestream, let the websocket handler perform the state update + if (!livestream) { + // add the comment by its ID + commentById[comment.comment_id] = comment; - // push the comment_id to the top of ID list - newCommentIds.unshift(comment.comment_id); - byId[claimId] = newCommentIds; + // push the comment_id to the top of ID list + newCommentIds.unshift(comment.comment_id); + byId[claimId] = newCommentIds; - if (comment['parent_id']) { - if (!repliesByParentId[comment.parent_id]) { - repliesByParentId[comment.parent_id] = [comment.comment_id]; + if (comment['parent_id']) { + if (!repliesByParentId[comment.parent_id]) { + repliesByParentId[comment.parent_id] = [comment.comment_id]; + } else { + repliesByParentId[comment.parent_id].unshift(comment.comment_id); + } } else { - repliesByParentId[comment.parent_id].unshift(comment.comment_id); - } - } else { - if (!topLevelCommentsById[claimId]) { - commentsByUri[uri] = claimId; - topLevelCommentsById[claimId] = [comment.comment_id]; - } else { - topLevelCommentsById[claimId].unshift(comment.comment_id); + if (!topLevelCommentsById[claimId]) { + commentsByUri[uri] = claimId; + topLevelCommentsById[claimId] = [comment.comment_id]; + } else { + topLevelCommentsById[claimId].unshift(comment.comment_id); + } } } + return { ...state, topLevelCommentsById, @@ -205,6 +217,42 @@ export default handleActions( ...state, isLoading: false, }), + + [ACTIONS.COMMENT_RECEIVED]: (state: CommentsState, action: any) => { + const { uri, claimId, comment } = action.data; + const commentsByUri = Object.assign({}, state.commentsByUri); + const commentsByClaimId = Object.assign({}, state.byId); + const allCommentsById = Object.assign({}, state.commentById); + const topLevelCommentsById = Object.assign({}, state.topLevelCommentsById); + const commentsForId = topLevelCommentsById[claimId]; + + allCommentsById[comment.comment_id] = comment; + commentsByUri[uri] = claimId; + + if (commentsForId) { + const newCommentsForId = commentsForId.slice(); + const commentExists = newCommentsForId.includes(comment.comment_id); + if (!commentExists) { + newCommentsForId.unshift(comment.comment_id); + } + + topLevelCommentsById[claimId] = newCommentsForId; + } else { + topLevelCommentsById[claimId] = [comment.comment_id]; + } + + // We don't care to keep existing lower level comments since this is just for livestreams + commentsByClaimId[claimId] = topLevelCommentsById[claimId]; + + return { + ...state, + byId: commentsByClaimId, + commentById: allCommentsById, + commentsByUri, + topLevelCommentsById, + }; + }, + [ACTIONS.COMMENT_ABANDON_STARTED]: (state: CommentsState, action: any) => ({ ...state, isLoading: true,