From b01b175fdc2ed81263d99df8fc2004d16d35a9ac Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 2 Aug 2021 17:46:18 +0200 Subject: [PATCH 1/2] Memoize ancestorIds and descendantIds in detailed status view --- app/soapbox/features/status/index.js | 70 +++++++++++++++++----------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/app/soapbox/features/status/index.js b/app/soapbox/features/status/index.js index 0ecf98e8c..6809b3ba3 100644 --- a/app/soapbox/features/status/index.js +++ b/app/soapbox/features/status/index.js @@ -41,6 +41,7 @@ import StatusContainer from '../../containers/status_container'; import { openModal } from '../../actions/modal'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; +import { createSelector } from 'reselect'; import { HotKeys } from 'react-hotkeys'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen'; import { textForScreenReader, defaultMediaVisibility } from '../../components/status'; @@ -66,43 +67,58 @@ const messages = defineMessages({ const makeMapStateToProps = () => { const getStatus = makeGetStatus(); - const mapStateToProps = (state, props) => { - const status = getStatus(state, { - id: props.params.statusId, - username: props.params.username, + const getAncestorsIds = createSelector([ + (_, { id }) => id, + state => state.getIn(['contexts', 'inReplyTos']), + ], (statusId, inReplyTos) => { + let ancestorsIds = Immutable.List(); + ancestorsIds = ancestorsIds.withMutations(mutable => { + let id = statusId; + + while (id) { + mutable.unshift(id); + id = inReplyTos.get(id); + } }); - let ancestorsIds = Immutable.List(); + return ancestorsIds; + }); + + const getDescendantsIds = createSelector([ + (_, { id }) => id, + state => state.getIn(['contexts', 'replies']), + ], (statusId, contextReplies) => { let descendantsIds = Immutable.List(); + descendantsIds = descendantsIds.withMutations(mutable => { + const ids = [statusId]; - if (status) { - ancestorsIds = ancestorsIds.withMutations(mutable => { - let id = state.getIn(['contexts', 'inReplyTos', status.get('id')]); + while (ids.length > 0) { + let id = ids.shift(); + const replies = contextReplies.get(id); - while (id) { - mutable.unshift(id); - id = state.getIn(['contexts', 'inReplyTos', id]); + if (statusId !== id) { + mutable.push(id); } - }); - descendantsIds = descendantsIds.withMutations(mutable => { - const ids = [status.get('id')]; + if (replies) { + replies.reverse().forEach(reply => { + ids.unshift(reply); + }); + } + } + }); - while (ids.length > 0) { - let id = ids.shift(); - const replies = state.getIn(['contexts', 'replies', id]); + return descendantsIds; + }); - if (status.get('id') !== id) { - mutable.push(id); - } + const mapStateToProps = (state, props) => { + const status = getStatus(state, { id: props.params.statusId }); + let ancestorsIds = Immutable.List(); + let descendantsIds = Immutable.List(); - if (replies) { - replies.reverse().forEach(reply => { - ids.unshift(reply); - }); - } - } - }); + if (status) { + ancestorsIds = getAncestorsIds(state, { id: state.getIn(['contexts', 'inReplyTos', status.get('id')]) }); + descendantsIds = getDescendantsIds(state, { id: status.get('id') }); } const soapbox = getSoapboxConfig(state); From 0877574c287fda982037bfb6e73f099e8f3caa50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 3 Aug 2021 10:50:08 +0200 Subject: [PATCH 2/2] Use OrderedSet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/features/status/index.js | 42 +++++++++++++--------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/app/soapbox/features/status/index.js b/app/soapbox/features/status/index.js index 6809b3ba3..0a687b855 100644 --- a/app/soapbox/features/status/index.js +++ b/app/soapbox/features/status/index.js @@ -71,15 +71,13 @@ const makeMapStateToProps = () => { (_, { id }) => id, state => state.getIn(['contexts', 'inReplyTos']), ], (statusId, inReplyTos) => { - let ancestorsIds = Immutable.List(); - ancestorsIds = ancestorsIds.withMutations(mutable => { - let id = statusId; + let ancestorsIds = Immutable.OrderedSet(); + let id = statusId; - while (id) { - mutable.unshift(id); - id = inReplyTos.get(id); - } - }); + while (id) { + ancestorsIds = Immutable.OrderedSet([id]).union(ancestorsIds); + id = inReplyTos.get(id); + } return ancestorsIds; }); @@ -88,25 +86,23 @@ const makeMapStateToProps = () => { (_, { id }) => id, state => state.getIn(['contexts', 'replies']), ], (statusId, contextReplies) => { - let descendantsIds = Immutable.List(); - descendantsIds = descendantsIds.withMutations(mutable => { - const ids = [statusId]; + let descendantsIds = Immutable.OrderedSet(); + const ids = [statusId]; - while (ids.length > 0) { - let id = ids.shift(); - const replies = contextReplies.get(id); + while (ids.length > 0) { + let id = ids.shift(); + const replies = contextReplies.get(id); - if (statusId !== id) { - mutable.push(id); - } + if (statusId !== id) { + descendantsIds = descendantsIds.union([id]); + } - if (replies) { - replies.reverse().forEach(reply => { - ids.unshift(reply); - }); - } + if (replies) { + replies.reverse().forEach(reply => { + ids.unshift(reply); + }); } - }); + } return descendantsIds; });