From c71e4718d0da5b62eb93156ec8e1c118c4bc8e8b Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Tue, 20 Jul 2021 11:14:56 +0800 Subject: [PATCH 1/3] Remove (revert) reaction-fetch hardstop Root-cause is known, so removing it to detect other issues. --- ui/component/commentsList/view.jsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ui/component/commentsList/view.jsx b/ui/component/commentsList/view.jsx index 450127a86..433103792 100644 --- a/ui/component/commentsList/view.jsx +++ b/ui/component/commentsList/view.jsx @@ -76,8 +76,6 @@ function CommentList(props: Props) { const [page, setPage] = React.useState(0); const totalFetchedComments = allCommentIds ? allCommentIds.length : 0; - const [reactionFetchCount, setReactionFetchCount] = React.useState(0); - // Display comments immediately if not fetching reactions // If not, wait to show comments until reactions are fetched const [readyToDisplayComments, setReadyToDisplayComments] = React.useState( @@ -138,9 +136,7 @@ function CommentList(props: Props) { }); } - if (idsForReactionFetch.length !== 0 && reactionFetchCount < 500) { - setReactionFetchCount(reactionFetchCount + 1); - + if (idsForReactionFetch.length !== 0) { fetchReacts(idsForReactionFetch) .then(() => { setReadyToDisplayComments(true); @@ -158,8 +154,6 @@ function CommentList(props: Props) { activeChannelId, fetchingChannels, isFetchingReacts, - reactionFetchCount, - setReactionFetchCount, ]); // Scroll to linked-comment From 08738ffcee0573df1eb6e21cad15064d1c6a114f Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Tue, 20 Jul 2021 14:38:29 +0800 Subject: [PATCH 2/3] Reaction-fetch: handle "deleted all channels" - use `selectActiveChannelClaim` as that takes the current channel list into account (i.e. correct state when all channels are deleted). - `selectActiveChannelId` should probably be removed or not exposed through a selector, as it is not updated when channel list changes? --- ui/component/comment/index.js | 7 ++++--- ui/component/commentReactions/index.js | 5 +++-- ui/component/commentsList/index.js | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ui/component/comment/index.js b/ui/component/comment/index.js index 9e4ed5825..26e604e64 100644 --- a/ui/component/comment/index.js +++ b/ui/component/comment/index.js @@ -11,12 +11,13 @@ import { doToast } from 'redux/actions/notifications'; import { doSetPlayingUri } from 'redux/actions/content'; import { selectUserVerifiedEmail } from 'redux/selectors/user'; import { selectLinkedCommentAncestors, makeSelectOthersReactionsForComment } from 'redux/selectors/comments'; -import { selectActiveChannelId, selectActiveChannelClaim } from 'redux/selectors/app'; +import { selectActiveChannelClaim } from 'redux/selectors/app'; import { selectPlayingUri } from 'redux/selectors/content'; import Comment from './view'; const select = (state, props) => { - const activeChannelId = selectActiveChannelId(state); + const activeChannelClaim = selectActiveChannelClaim(state); + const activeChannelId = activeChannelClaim && activeChannelClaim.claim_id; const reactionKey = activeChannelId ? `${props.commentId}:${activeChannelId}` : props.commentId; return { @@ -25,7 +26,7 @@ const select = (state, props) => { channelIsBlocked: props.authorUri && makeSelectChannelIsMuted(props.authorUri)(state), commentingEnabled: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true, othersReacts: makeSelectOthersReactionsForComment(reactionKey)(state), - activeChannelClaim: selectActiveChannelClaim(state), + activeChannelClaim, myChannels: selectMyChannelClaims(state), playingUri: selectPlayingUri(state), stakedLevel: makeSelectStakedLevelForChannelUri(props.authorUri)(state), diff --git a/ui/component/commentReactions/index.js b/ui/component/commentReactions/index.js index 585cb7a10..eb72e7362 100644 --- a/ui/component/commentReactions/index.js +++ b/ui/component/commentReactions/index.js @@ -4,10 +4,11 @@ import { makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux'; import { doToast } from 'redux/actions/notifications'; import { makeSelectMyReactionsForComment, makeSelectOthersReactionsForComment } from 'redux/selectors/comments'; import { doCommentReact } from 'redux/actions/comments'; -import { selectActiveChannelId } from 'redux/selectors/app'; +import { selectActiveChannelClaim } from 'redux/selectors/app'; const select = (state, props) => { - const activeChannelId = selectActiveChannelId(state); + const activeChannelClaim = selectActiveChannelClaim(state); + const activeChannelId = activeChannelClaim && activeChannelClaim.claim_id; const reactionKey = activeChannelId ? `${props.commentId}:${activeChannelId}` : props.commentId; return { diff --git a/ui/component/commentsList/index.js b/ui/component/commentsList/index.js index 72a5b2916..dac16d16d 100644 --- a/ui/component/commentsList/index.js +++ b/ui/component/commentsList/index.js @@ -13,10 +13,11 @@ import { } from 'redux/selectors/comments'; import { doCommentReset, doCommentList, doCommentById, doCommentReactList } from 'redux/actions/comments'; import { selectUserVerifiedEmail } from 'redux/selectors/user'; -import { selectActiveChannelId } from 'redux/selectors/app'; +import { selectActiveChannelClaim } from 'redux/selectors/app'; import CommentsList from './view'; const select = (state, props) => { + const activeChannelClaim = selectActiveChannelClaim(state); return { myChannels: selectMyChannelClaims(state), allCommentIds: makeSelectCommentIdsForUri(props.uri)(state), @@ -31,7 +32,7 @@ const select = (state, props) => { fetchingChannels: selectFetchingMyChannels(state), myReactsByCommentId: selectMyReactionsByCommentId(state), othersReactsById: selectOthersReactsById(state), - activeChannelId: selectActiveChannelId(state), + activeChannelId: activeChannelClaim && activeChannelClaim.claim_id, }; }; From e5f32b21c4f13b3c1801be6a74b059326ca7b884 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Tue, 20 Jul 2021 14:55:26 +0800 Subject: [PATCH 3/3] Reaction-fetch: handle "no results" If there are no API errors but no reactions returned, consider the requested IDs as "done" and stop requesting again. When a channel is being confirmed, Commentron doesn't return the reaction object. Also added extra guard in case Commentron does return an object in the future, but an empty one. --- ui/redux/actions/comments.js | 5 +++-- ui/redux/reducers/comments.js | 23 ++++++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ui/redux/actions/comments.js b/ui/redux/actions/comments.js index beeb0a246..b3349ec26 100644 --- a/ui/redux/actions/comments.js +++ b/ui/redux/actions/comments.js @@ -236,9 +236,10 @@ export function doCommentReactList(commentIds: Array) { dispatch({ type: ACTIONS.COMMENT_REACTION_LIST_COMPLETED, data: { - myReactions: myReactions || {}, + myReactions, othersReactions, channelId: activeChannelClaim ? activeChannelClaim.claim_id : undefined, + commentIds, }, }); }) @@ -379,7 +380,7 @@ export function doCommentCreate( livestream?: boolean = false, txid?: string, payment_intent_id?: string, - environment?: string, + environment?: string ) { return async (dispatch: Dispatch, getState: GetState) => { const state = getState(); diff --git a/ui/redux/reducers/comments.js b/ui/redux/reducers/comments.js index 5065fa9bd..6c09339f3 100644 --- a/ui/redux/reducers/comments.js +++ b/ui/redux/reducers/comments.js @@ -182,12 +182,15 @@ export default handleActions( }, [ACTIONS.COMMENT_REACTION_LIST_COMPLETED]: (state: CommentsState, action: any): CommentsState => { - const { myReactions, othersReactions, channelId } = action.data; + const { myReactions, othersReactions, channelId, commentIds } = action.data; const myReacts = Object.assign({}, state.myReactsByCommentId); const othersReacts = Object.assign({}, state.othersReactsByCommentId); - if (myReactions) { - Object.entries(myReactions).forEach(([commentId, reactions]) => { + const myReactionsEntries = myReactions ? Object.entries(myReactions) : []; + const othersReactionsEntries = othersReactions ? Object.entries(othersReactions) : []; + + if (myReactionsEntries.length > 0) { + myReactionsEntries.forEach(([commentId, reactions]) => { const key = channelId ? `${commentId}:${channelId}` : commentId; myReacts[key] = Object.entries(reactions).reduce((acc, [name, count]) => { if (count === 1) { @@ -196,13 +199,23 @@ export default handleActions( return acc; }, []); }); + } else { + commentIds.forEach((commentId) => { + const key = channelId ? `${commentId}:${channelId}` : commentId; + myReacts[key] = []; + }); } - if (othersReactions) { - Object.entries(othersReactions).forEach(([commentId, reactions]) => { + if (othersReactionsEntries.length > 0) { + othersReactionsEntries.forEach(([commentId, reactions]) => { const key = channelId ? `${commentId}:${channelId}` : commentId; othersReacts[key] = reactions; }); + } else { + commentIds.forEach((commentId) => { + const key = channelId ? `${commentId}:${channelId}` : commentId; + othersReacts[key] = {}; + }); } return {