From 7e9d5bdbb9125197afb5b3df69ce49a79451d697 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 5 Jan 2023 13:32:29 +0100 Subject: [PATCH] [Glitch] Fix unnecessary re-rendering of various components when typing in web UI (#2063) Port 9620ee90be7e04b3616ce4b851abb63dbba7af7f to glitch-soc Signed-off-by: Claire Signed-off-by: Claire Co-authored-by: Eugen Rochko --- .../flavours/glitch/components/status.js | 8 ++++---- .../glitch/containers/status_container.js | 9 +++------ .../status/components/detailed_status.js | 9 ++++++--- .../flavours/glitch/features/status/index.js | 19 ++++++++++++------- .../flavours/glitch/selectors/index.js | 12 +++++++++++- 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/app/javascript/flavours/glitch/components/status.js b/app/javascript/flavours/glitch/components/status.js index 4041b48194..409ec0adc5 100644 --- a/app/javascript/flavours/glitch/components/status.js +++ b/app/javascript/flavours/glitch/components/status.js @@ -102,7 +102,7 @@ class Status extends ImmutablePureComponent { scrollKey: PropTypes.string, deployPictureInPicture: PropTypes.func, settings: ImmutablePropTypes.map.isRequired, - pictureInPicture: PropTypes.shape({ + pictureInPicture: ImmutablePropTypes.contains({ inUse: PropTypes.bool, available: PropTypes.bool, }), @@ -603,7 +603,7 @@ class Status extends ImmutablePureComponent { attachments = status.get('media_attachments'); - if (pictureInPicture.inUse) { + if (pictureInPicture.get('inUse')) { media.push(); mediaIcons.push('video-camera'); } else if (attachments.size > 0) { @@ -631,7 +631,7 @@ class Status extends ImmutablePureComponent { width={this.props.cachedMediaWidth} height={110} cacheWidth={this.props.cacheMediaWidth} - deployPictureInPicture={pictureInPicture.available ? this.handleDeployPictureInPicture : undefined} + deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined} sensitive={status.get('sensitive')} blurhash={attachment.get('blurhash')} visible={this.state.showMedia} @@ -660,7 +660,7 @@ class Status extends ImmutablePureComponent { onOpenVideo={this.handleOpenVideo} width={this.props.cachedMediaWidth} cacheWidth={this.props.cacheMediaWidth} - deployPictureInPicture={pictureInPicture.available ? this.handleDeployPictureInPicture : undefined} + deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined} visible={this.state.showMedia} onToggleVisibility={this.handleToggleMediaVisibility} />)} diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index 947573fc7d..645919ebe8 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import Status from 'flavours/glitch/components/status'; import { List as ImmutableList } from 'immutable'; -import { makeGetStatus } from 'flavours/glitch/selectors'; +import { makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors'; import { replyCompose, mentionCompose, @@ -60,6 +60,7 @@ const messages = defineMessages({ const makeMapStateToProps = () => { const getStatus = makeGetStatus(); + const getPictureInPicture = makeGetPictureInPicture(); const mapStateToProps = (state, props) => { @@ -83,11 +84,7 @@ const makeMapStateToProps = () => { account: account || props.account, settings: state.get('local_settings'), prepend: prepend || props.prepend, - - pictureInPicture: { - inUse: state.getIn(['meta', 'layout']) !== 'mobile' && state.get('picture_in_picture').statusId === props.id, - available: state.getIn(['meta', 'layout']) !== 'mobile', - }, + pictureInPicture: getPictureInPicture(state, props), }; }; diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.js b/app/javascript/flavours/glitch/features/status/components/detailed_status.js index 7d2c2aace3..907fc3f1c1 100644 --- a/app/javascript/flavours/glitch/features/status/components/detailed_status.js +++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.js @@ -41,7 +41,10 @@ class DetailedStatus extends ImmutablePureComponent { domain: PropTypes.string.isRequired, compact: PropTypes.bool, showMedia: PropTypes.bool, - usingPiP: PropTypes.bool, + pictureInPicture: ImmutablePropTypes.contains({ + inUse: PropTypes.bool, + available: PropTypes.bool, + }), onToggleMediaVisibility: PropTypes.func, intl: PropTypes.object.isRequired, }; @@ -120,7 +123,7 @@ class DetailedStatus extends ImmutablePureComponent { render () { const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status; - const { expanded, onToggleHidden, settings, usingPiP, intl } = this.props; + const { expanded, onToggleHidden, settings, pictureInPicture, intl } = this.props; const outerStyle = { boxSizing: 'border-box' }; const { compact } = this.props; @@ -153,7 +156,7 @@ class DetailedStatus extends ImmutablePureComponent { outerStyle.height = `${this.state.height}px`; } - if (usingPiP) { + if (pictureInPicture.get('inUse')) { media.push(); mediaIcons.push('video-camera'); } else if (status.get('media_attachments').size > 0) { diff --git a/app/javascript/flavours/glitch/features/status/index.js b/app/javascript/flavours/glitch/features/status/index.js index c716e4f0f5..c22e7f0bd8 100644 --- a/app/javascript/flavours/glitch/features/status/index.js +++ b/app/javascript/flavours/glitch/features/status/index.js @@ -41,7 +41,7 @@ import { initMuteModal } from 'flavours/glitch/actions/mutes'; import { initBlockModal } from 'flavours/glitch/actions/blocks'; import { initReport } from 'flavours/glitch/actions/reports'; import { initBoostModal } from 'flavours/glitch/actions/boosts'; -import { makeGetStatus } from 'flavours/glitch/selectors'; +import { makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors'; import ScrollContainer from 'flavours/glitch/containers/scroll_container'; import ColumnBackButton from 'flavours/glitch/components/column_back_button'; import ColumnHeader from '../../components/column_header'; @@ -72,6 +72,7 @@ const messages = defineMessages({ const makeMapStateToProps = () => { const getStatus = makeGetStatus(); + const getPictureInPicture = makeGetPictureInPicture(); const getAncestorsIds = createSelector([ (_, { id }) => id, @@ -129,11 +130,12 @@ const makeMapStateToProps = () => { const mapStateToProps = (state, props) => { const status = getStatus(state, { id: props.params.statusId }); - let ancestorsIds = Immutable.List(); + + let ancestorsIds = Immutable.List(); let descendantsIds = Immutable.List(); if (status) { - ancestorsIds = getAncestorsIds(state, { id: status.get('in_reply_to_id') }); + ancestorsIds = getAncestorsIds(state, { id: status.get('in_reply_to_id') }); descendantsIds = getDescendantsIds(state, { id: status.get('id') }); } @@ -145,7 +147,7 @@ const makeMapStateToProps = () => { settings: state.get('local_settings'), askReplyConfirmation: state.getIn(['local_settings', 'confirm_before_clearing_draft']) && state.getIn(['compose', 'text']).trim().length !== 0, domain: state.getIn(['meta', 'domain']), - usingPiP: state.get('picture_in_picture').statusId === props.params.statusId, + pictureInPicture: getPictureInPicture(state, { id: props.params.statusId }), }; }; @@ -190,7 +192,10 @@ class Status extends ImmutablePureComponent { askReplyConfirmation: PropTypes.bool, multiColumn: PropTypes.bool, domain: PropTypes.string.isRequired, - usingPiP: PropTypes.bool, + pictureInPicture: ImmutablePropTypes.contains({ + inUse: PropTypes.bool, + available: PropTypes.bool, + }), }; state = { @@ -604,7 +609,7 @@ class Status extends ImmutablePureComponent { render () { let ancestors, descendants; - const { isLoading, status, settings, ancestorsIds, descendantsIds, intl, domain, multiColumn, usingPiP } = this.props; + const { isLoading, status, settings, ancestorsIds, descendantsIds, intl, domain, multiColumn, pictureInPicture } = this.props; const { fullscreen } = this.state; if (isLoading) { @@ -682,7 +687,7 @@ class Status extends ImmutablePureComponent { domain={domain} showMedia={this.state.showMedia} onToggleMediaVisibility={this.handleToggleMediaVisibility} - usingPiP={usingPiP} + pictureInPicture={pictureInPicture} /> { ); }; +export const makeGetPictureInPicture = () => { + return createSelector([ + (state, { id }) => state.get('picture_in_picture').statusId === id, + (state) => state.getIn(['meta', 'layout']) !== 'mobile', + ], (inUse, available) => ImmutableMap({ + inUse: inUse && available, + available, + })); +}; + const getAlertsBase = state => state.get('alerts'); export const getAlerts = createSelector([getAlertsBase], (base) => {