diff --git a/flow-typed/Comment.js b/flow-typed/Comment.js index c851d297d..0a497a324 100644 --- a/flow-typed/Comment.js +++ b/flow-typed/Comment.js @@ -45,6 +45,7 @@ declare type CommentsState = { isLoading: boolean, isLoadingById: boolean, isLoadingByParentId: { [string]: boolean }, + isCommenting: boolean, myComments: ?Set, isFetchingReacts: boolean, myReactsByCommentId: ?{ [string]: Array }, // {"CommentId:MyChannelId": ["like", "dislike", ...]} diff --git a/package.json b/package.json index adc63c7a6..7ab3b9eff 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ }, "dependencies": { "@ungap/from-entries": "^0.2.1", - "proxy-polyfill": "0.1.6", "auto-launch": "^5.0.5", "electron-dl": "^1.11.0", "electron-log": "^2.2.12", @@ -61,6 +60,8 @@ "if-env": "^1.0.4", "match-sorter": "^6.3.0", "parse-duration": "^1.0.0", + "proxy-polyfill": "0.1.6", + "re-reselect": "^4.0.0", "react-datetime-picker": "^3.2.1", "react-plastic": "^1.1.1", "react-top-loading-bar": "^2.0.1", diff --git a/ui/component/channelMentionSuggestions/index.js b/ui/component/channelMentionSuggestions/index.js index d6b4af95b..c1f635011 100644 --- a/ui/component/channelMentionSuggestions/index.js +++ b/ui/component/channelMentionSuggestions/index.js @@ -4,12 +4,12 @@ import { selectSubscriptions } from 'redux/selectors/subscriptions'; import { withRouter } from 'react-router'; import { makeSelectClaimForUri } from 'redux/selectors/claims'; import { doResolveUris } from 'redux/actions/claims'; -import { makeSelectTopLevelCommentsForUri } from 'redux/selectors/comments'; +import { selectTopLevelCommentsForUri } from 'redux/selectors/comments'; import ChannelMentionSuggestions from './view'; const select = (state, props) => { const subscriptionUris = selectSubscriptions(state).map(({ uri }) => uri); - const topLevelComments = makeSelectTopLevelCommentsForUri(props.uri)(state); + const topLevelComments = selectTopLevelCommentsForUri(state, props.uri); const commentorUris = []; // Avoid repeated commentors diff --git a/ui/component/claimPreview/index.js b/ui/component/claimPreview/index.js index 5e5cdd378..f0640d697 100644 --- a/ui/component/claimPreview/index.js +++ b/ui/component/claimPreview/index.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import { - makeSelectClaimForUri, + selectClaimForUri, makeSelectIsUriResolving, makeSelectClaimIsMine, makeSelectClaimIsPending, @@ -9,7 +9,7 @@ import { makeSelectClaimWasPurchased, makeSelectClaimIsStreamPlaceholder, makeSelectTitleForUri, - makeSelectDateForUri, + selectDateForUri, } from 'redux/selectors/claims'; import { makeSelectStreamingUrlForUri } from 'redux/selectors/file_info'; import { @@ -32,14 +32,14 @@ import ClaimPreview from './view'; import formatMediaDuration from 'util/formatMediaDuration'; const select = (state, props) => { - const claim = props.uri && makeSelectClaimForUri(props.uri)(state); + const claim = props.uri && selectClaimForUri(state, props.uri); const media = claim && claim.value && (claim.value.video || claim.value.audio); const mediaDuration = media && media.duration && formatMediaDuration(media.duration, { screenReader: true }); return { claim, mediaDuration, - date: props.uri && makeSelectDateForUri(props.uri)(state), + date: props.uri && selectDateForUri(state, props.uri), title: props.uri && makeSelectTitleForUri(props.uri)(state), pending: props.uri && makeSelectClaimIsPending(props.uri)(state), reflectingProgress: props.uri && makeSelectReflectingClaimForUri(props.uri)(state), @@ -47,7 +47,6 @@ const select = (state, props) => { claimIsMine: props.uri && makeSelectClaimIsMine(props.uri)(state), isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), isResolvingRepost: props.uri && makeSelectIsUriResolving(props.repostUrl)(state), - repostClaim: props.uri && makeSelectClaimForUri(props.uri)(state), nsfw: props.uri && makeSelectClaimIsNsfw(props.uri)(state), blackListedOutpoints: selectBlackListedOutpoints(state), filteredOutpoints: selectFilteredOutpoints(state), diff --git a/ui/component/claimPreviewTile/index.js b/ui/component/claimPreviewTile/index.js index 6209a71ae..3f5661a98 100644 --- a/ui/component/claimPreviewTile/index.js +++ b/ui/component/claimPreviewTile/index.js @@ -7,7 +7,7 @@ import { makeSelectChannelForClaimUri, makeSelectClaimIsNsfw, makeSelectClaimIsStreamPlaceholder, - makeSelectDateForUri, + selectDateForUri, } from 'redux/selectors/claims'; import { doFileGet } from 'redux/actions/file'; import { doResolveUri } from 'redux/actions/claims'; @@ -26,7 +26,7 @@ const select = (state, props) => { return { claim, mediaDuration, - date: props.uri && makeSelectDateForUri(props.uri)(state), + date: props.uri && selectDateForUri(state, props.uri), channel: props.uri && makeSelectChannelForClaimUri(props.uri)(state), isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), thumbnail: props.uri && makeSelectThumbnailForUri(props.uri)(state), diff --git a/ui/component/claimTags/index.js b/ui/component/claimTags/index.js index a0280f138..385aca981 100644 --- a/ui/component/claimTags/index.js +++ b/ui/component/claimTags/index.js @@ -1,10 +1,10 @@ import { connect } from 'react-redux'; -import { makeSelectTagsForUri } from 'redux/selectors/claims'; +import { selectTagsForUri } from 'redux/selectors/claims'; import { selectFollowedTags } from 'redux/selectors/tags'; import ClaimTags from './view'; const select = (state, props) => ({ - tags: makeSelectTagsForUri(props.uri)(state), + tags: selectTagsForUri(state, props.uri), followedTags: selectFollowedTags(state), }); diff --git a/ui/component/comment/index.js b/ui/component/comment/index.js index 712b0e34b..ffe06dd37 100644 --- a/ui/component/comment/index.js +++ b/ui/component/comment/index.js @@ -12,7 +12,7 @@ import { doSetPlayingUri } from 'redux/actions/content'; import { selectUserVerifiedEmail } from 'redux/selectors/user'; import { selectLinkedCommentAncestors, - makeSelectOthersReactionsForComment, + selectOthersReactsForComment, makeSelectTotalReplyPagesForParentId, } from 'redux/selectors/comments'; import { selectActiveChannelClaim } from 'redux/selectors/app'; @@ -29,7 +29,7 @@ const select = (state, props) => { thumbnail: props.authorUri && makeSelectThumbnailForUri(props.authorUri)(state), channelIsBlocked: props.authorUri && makeSelectChannelIsMuted(props.authorUri)(state), commentingEnabled: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true, - othersReacts: makeSelectOthersReactionsForComment(reactionKey)(state), + othersReacts: selectOthersReactsForComment(state, reactionKey), activeChannelClaim, myChannels: selectMyChannelClaims(state), playingUri: selectPlayingUri(state), diff --git a/ui/component/commentReactions/index.js b/ui/component/commentReactions/index.js index 9f640d619..b2de27008 100644 --- a/ui/component/commentReactions/index.js +++ b/ui/component/commentReactions/index.js @@ -3,7 +3,7 @@ import Comment from './view'; import { makeSelectClaimIsMine, makeSelectClaimForUri } from 'redux/selectors/claims'; import { doResolveUri } from 'redux/actions/claims'; import { doToast } from 'redux/actions/notifications'; -import { makeSelectMyReactionsForComment, makeSelectOthersReactionsForComment } from 'redux/selectors/comments'; +import { selectMyReactsForComment, selectOthersReactsForComment } from 'redux/selectors/comments'; import { doCommentReact } from 'redux/actions/comments'; import { selectActiveChannelClaim } from 'redux/selectors/app'; @@ -15,8 +15,8 @@ const select = (state, props) => { return { claim: makeSelectClaimForUri(props.uri)(state), claimIsMine: makeSelectClaimIsMine(props.uri)(state), - myReacts: makeSelectMyReactionsForComment(reactionKey)(state), - othersReacts: makeSelectOthersReactionsForComment(reactionKey)(state), + myReacts: selectMyReactsForComment(state, reactionKey), + othersReacts: selectOthersReactsForComment(state, reactionKey), activeChannelId, }; }; diff --git a/ui/component/commentReactions/view.jsx b/ui/component/commentReactions/view.jsx index a121e35ed..68187d907 100644 --- a/ui/component/commentReactions/view.jsx +++ b/ui/component/commentReactions/view.jsx @@ -73,12 +73,12 @@ export default function CommentReactions(props: Props) { const shouldHide = !canCreatorReact && hideCreatorLike; const creatorLiked = getCountForReact(REACTION_TYPES.CREATOR_LIKE) > 0; const likeIcon = SIMPLE_SITE - ? myReacts.includes(REACTION_TYPES.LIKE) + ? myReacts && myReacts.includes(REACTION_TYPES.LIKE) ? ICONS.FIRE_ACTIVE : ICONS.FIRE : ICONS.UPVOTE; const dislikeIcon = SIMPLE_SITE - ? myReacts.includes(REACTION_TYPES.DISLIKE) + ? myReacts && myReacts.includes(REACTION_TYPES.DISLIKE) ? ICONS.SLIME_ACTIVE : ICONS.SLIME : ICONS.DOWNVOTE; diff --git a/ui/component/commentsList/index.js b/ui/component/commentsList/index.js index d2e64843e..4b09b9b4f 100644 --- a/ui/component/commentsList/index.js +++ b/ui/component/commentsList/index.js @@ -7,17 +7,17 @@ import { selectMyChannelClaims, } from 'redux/selectors/claims'; import { - makeSelectTopLevelCommentsForUri, + selectTopLevelCommentsForUri, makeSelectTopLevelTotalPagesForUri, selectIsFetchingComments, selectIsFetchingCommentsById, selectIsFetchingReacts, makeSelectTotalCommentsCountForUri, - selectOthersReactsById, - selectMyReactionsByCommentId, + selectOthersReacts, + selectMyReacts, makeSelectCommentIdsForUri, selectSettingsByChannelId, - makeSelectPinnedCommentsForUri, + selectPinnedCommentsForUri, } from 'redux/selectors/comments'; import { doCommentReset, doCommentList, doCommentById, doCommentReactList } from 'redux/actions/comments'; import { selectActiveChannelClaim } from 'redux/selectors/app'; @@ -25,7 +25,7 @@ import CommentsList from './view'; const select = (state, props) => { const activeChannelClaim = selectActiveChannelClaim(state); - const topLevelComments = makeSelectTopLevelCommentsForUri(props.uri)(state); + const topLevelComments = selectTopLevelCommentsForUri(state, props.uri); const resolvedComments = topLevelComments && topLevelComments.length > 0 @@ -37,7 +37,7 @@ const select = (state, props) => { resolvedComments, myChannels: selectMyChannelClaims(state), allCommentIds: makeSelectCommentIdsForUri(props.uri)(state), - pinnedComments: makeSelectPinnedCommentsForUri(props.uri)(state), + pinnedComments: selectPinnedCommentsForUri(state, props.uri), topLevelTotalPages: makeSelectTopLevelTotalPagesForUri(props.uri)(state), totalComments: makeSelectTotalCommentsCountForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state), @@ -47,8 +47,8 @@ const select = (state, props) => { isFetchingReacts: selectIsFetchingReacts(state), fetchingChannels: selectFetchingMyChannels(state), settingsByChannelId: selectSettingsByChannelId(state), - myReactsByCommentId: selectMyReactionsByCommentId(state), - othersReactsById: selectOthersReactsById(state), + myReactsByCommentId: selectMyReacts(state), + othersReactsById: selectOthersReacts(state), activeChannelId: activeChannelClaim && activeChannelClaim.claim_id, }; }; diff --git a/ui/component/commentsReplies/index.js b/ui/component/commentsReplies/index.js index 4eba49c34..d7ac34b2e 100644 --- a/ui/component/commentsReplies/index.js +++ b/ui/component/commentsReplies/index.js @@ -1,12 +1,12 @@ import { connect } from 'react-redux'; import { doResolveUris } from 'redux/actions/claims'; import { makeSelectClaimIsMine, selectMyChannelClaims, makeSelectClaimForUri } from 'redux/selectors/claims'; -import { selectIsFetchingCommentsByParentId, makeSelectRepliesForParentId } from 'redux/selectors/comments'; +import { selectIsFetchingCommentsByParentId, selectRepliesForParentId } from 'redux/selectors/comments'; import { selectUserVerifiedEmail } from 'redux/selectors/user'; import CommentsReplies from './view'; const select = (state, props) => { - const fetchedReplies = makeSelectRepliesForParentId(props.parentId)(state); + const fetchedReplies = selectRepliesForParentId(state, props.parentId); const resolvedReplies = fetchedReplies && fetchedReplies.length > 0 ? fetchedReplies.filter(({ channel_url }) => makeSelectClaimForUri(channel_url)(state) !== undefined) diff --git a/ui/component/dateTime/index.js b/ui/component/dateTime/index.js index 367ac4ab1..24fc98280 100644 --- a/ui/component/dateTime/index.js +++ b/ui/component/dateTime/index.js @@ -1,11 +1,11 @@ import { connect } from 'react-redux'; -import { makeSelectDateForUri } from 'redux/selectors/claims'; +import { selectDateForUri } from 'redux/selectors/claims'; import * as SETTINGS from 'constants/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import DateTime from './view'; const select = (state, props) => ({ - date: props.date || makeSelectDateForUri(props.uri)(state), + date: props.date || selectDateForUri(state, props.uri), clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state), }); export default connect(select)(DateTime); diff --git a/ui/component/fileDescription/index.js b/ui/component/fileDescription/index.js index 5004b7220..f0646e415 100644 --- a/ui/component/fileDescription/index.js +++ b/ui/component/fileDescription/index.js @@ -2,7 +2,6 @@ import { connect } from 'react-redux'; import { makeSelectClaimForUri, makeSelectMetadataForUri, - makeSelectTagsForUri, makeSelectClaimIsMine, } from 'redux/selectors/claims'; import { makeSelectPendingAmountByUri } from 'redux/selectors/wallet'; @@ -15,7 +14,6 @@ const select = (state, props) => ({ claimIsMine: makeSelectClaimIsMine(props.uri)(state), metadata: makeSelectMetadataForUri(props.uri)(state), user: selectUser(state), - tags: makeSelectTagsForUri(props.uri)(state), pendingAmount: makeSelectPendingAmountByUri(props.uri)(state), }); diff --git a/ui/component/fileDescription/view.jsx b/ui/component/fileDescription/view.jsx index 4b045822e..05310ea39 100644 --- a/ui/component/fileDescription/view.jsx +++ b/ui/component/fileDescription/view.jsx @@ -16,7 +16,6 @@ type Props = { claim: StreamClaim, metadata: StreamMetadata, user: ?any, - tags: any, pendingAmount: number, doOpenModal: (id: string, {}) => void, claimIsMine: boolean, diff --git a/ui/component/livestreamComment/index.js b/ui/component/livestreamComment/index.js index 8c6a97de5..b18a96a36 100644 --- a/ui/component/livestreamComment/index.js +++ b/ui/component/livestreamComment/index.js @@ -1,9 +1,9 @@ import { connect } from 'react-redux'; -import { makeSelectStakedLevelForChannelUri, makeSelectClaimForUri } from 'redux/selectors/claims'; +import { makeSelectStakedLevelForChannelUri, selectClaimForUri } from 'redux/selectors/claims'; import LivestreamComment from './view'; const select = (state, props) => ({ - claim: makeSelectClaimForUri(props.uri)(state), + claim: selectClaimForUri(state, props.uri), stakedLevel: makeSelectStakedLevelForChannelUri(props.authorUri)(state), }); diff --git a/ui/component/livestreamComments/index.js b/ui/component/livestreamComments/index.js index f68fc3372..e7b3d263d 100644 --- a/ui/component/livestreamComments/index.js +++ b/ui/component/livestreamComments/index.js @@ -1,20 +1,22 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, selectMyChannelClaims } from 'redux/selectors/claims'; +import { selectClaimForUri, selectMyChannelClaims } from 'redux/selectors/claims'; import { doCommentSocketConnect, doCommentSocketDisconnect } from 'redux/actions/websocket'; import { doCommentList, doSuperChatList } from 'redux/actions/comments'; import { - makeSelectTopLevelCommentsForUri, + selectTopLevelCommentsForUri, selectIsFetchingComments, makeSelectSuperChatsForUri, makeSelectSuperChatTotalAmountForUri, - makeSelectPinnedCommentsForUri, + selectPinnedCommentsForUri, } from 'redux/selectors/comments'; import LivestreamComments from './view'; +const MAX_LIVESTREAM_COMMENTS = 75; + const select = (state, props) => ({ - claim: makeSelectClaimForUri(props.uri)(state), - comments: makeSelectTopLevelCommentsForUri(props.uri)(state).slice(0, 75), - pinnedComments: makeSelectPinnedCommentsForUri(props.uri)(state), + claim: selectClaimForUri(state, props.uri), + comments: selectTopLevelCommentsForUri(state, props.uri, MAX_LIVESTREAM_COMMENTS), + pinnedComments: selectPinnedCommentsForUri(state, props.uri), fetchingComments: selectIsFetchingComments(state), superChats: makeSelectSuperChatsForUri(props.uri)(state), superChatsTotalAmount: makeSelectSuperChatTotalAmountForUri(props.uri)(state), diff --git a/ui/component/livestreamComments/view.jsx b/ui/component/livestreamComments/view.jsx index a9db254de..535a37ac2 100644 --- a/ui/component/livestreamComments/view.jsx +++ b/ui/component/livestreamComments/view.jsx @@ -63,11 +63,11 @@ export default function LivestreamComments(props: Props) { const pinnedComment = pinnedComments.length > 0 ? pinnedComments[0] : null; - function restoreScrollPos() { + const restoreScrollPos = React.useCallback(() => { if (discussionElement) { discussionElement.scrollTop = 0; } - } + }, [discussionElement]); React.useEffect(() => { if (claimId) { @@ -139,10 +139,10 @@ export default function LivestreamComments(props: Props) { const clonedSuperchats = JSON.parse(JSON.stringify(superChatsByTipAmount)); // for top to bottom display, oldest superchat on top most recent on bottom - superChatsReversed = clonedSuperchats - .sort((a, b) => { - return b.timestamp - a.timestamp; - }); } + superChatsReversed = clonedSuperchats.sort((a, b) => { + return b.timestamp - a.timestamp; + }); + } // todo: implement comment_list --mine in SDK so redux can grab with selectCommentIsMine function isMyComment(channelId: string) { diff --git a/ui/component/supportsLiquidate/index.js b/ui/component/supportsLiquidate/index.js index c7626b769..f2ff697d4 100644 --- a/ui/component/supportsLiquidate/index.js +++ b/ui/component/supportsLiquidate/index.js @@ -8,7 +8,7 @@ import { selectAbandonClaimSupportError, } from 'redux/selectors/wallet'; -import { makeSelectMetadataForUri, makeSelectClaimForUri } from 'redux/selectors/claims'; +import { makeSelectClaimForUri } from 'redux/selectors/claims'; import { doSupportAbandonForClaim } from 'redux/actions/wallet'; import SupportsLiquidate from './view'; @@ -19,7 +19,6 @@ const select = (state, props) => ({ supportsBalance: selectSupportsBalance(state) || undefined, tipsBalance: selectTipsBalance(state) || undefined, claim: makeSelectClaimForUri(props.uri)(state), - metadata: makeSelectMetadataForUri(props.uri)(state), abandonClaimError: selectAbandonClaimSupportError(state), }); diff --git a/ui/component/supportsLiquidate/view.jsx b/ui/component/supportsLiquidate/view.jsx index 3c5771b99..441139b6b 100644 --- a/ui/component/supportsLiquidate/view.jsx +++ b/ui/component/supportsLiquidate/view.jsx @@ -15,7 +15,6 @@ type Props = { supportsBalance: number, tipsBalance: number, claim: any, - metaData: any, handleClose: () => void, abandonSupportForClaim: (string, string, boolean | string, boolean) => any, abandonClaimError: ?string, @@ -37,14 +36,14 @@ const SupportsLiquidate = (props: Props) => { useEffect(() => { if (claimId && abandonSupportForClaim) { - abandonSupportForClaim(claimId, type, false, true).then(r => { + abandonSupportForClaim(claimId, type, false, true).then((r) => { setPreviewBalance(r.total_input); }); } }, [abandonSupportForClaim, claimId, type, setPreviewBalance]); function handleSubmit() { - abandonSupportForClaim(claimId, type, keep, false).then(r => { + abandonSupportForClaim(claimId, type, keep, false).then((r) => { if (r) { handleClose(); } @@ -141,7 +140,7 @@ const SupportsLiquidate = (props: Props) => { step={0.01} max={previewBalance} value={Number(amount) >= 0 ? amount : previewBalance / 4} // by default, set it to 25% of available - onChange={e => handleChange(e.target.value)} + onChange={(e) => handleChange(e.target.value)} />