Avoid two-step rendering of statuses as much as possible

Cache width shared by Video player, MediaGallery and Cards at the
ScrollableList level, pass it down through StatusList and Notifications.
pull/915/head
Thibaut Girka 2019-02-09 20:54:11 +01:00 committed by ThibG
parent 68f3d003d6
commit 049c9a3b97
6 changed files with 48 additions and 6 deletions

View File

@ -224,6 +224,8 @@ export default class MediaGallery extends React.PureComponent {
size: PropTypes.object, size: PropTypes.object,
onOpenMedia: PropTypes.func.isRequired, onOpenMedia: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
defaultWidth: PropTypes.number,
cacheWidth: PropTypes.func,
}; };
static defaultProps = { static defaultProps = {
@ -232,6 +234,7 @@ export default class MediaGallery extends React.PureComponent {
state = { state = {
visible: this.props.revealed === undefined ? (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all') : this.props.revealed, visible: this.props.revealed === undefined ? (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all') : this.props.revealed,
width: this.props.defaultWidth,
}; };
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
@ -259,6 +262,7 @@ export default class MediaGallery extends React.PureComponent {
handleRef = (node) => { handleRef = (node) => {
this.node = node; this.node = node;
if (node && node.offsetWidth && node.offsetWidth != this.state.width) { if (node && node.offsetWidth && node.offsetWidth != this.state.width) {
if (this.props.cacheWidth) this.props.cacheWidth(node.offsetWidth);
this.setState({ this.setState({
width: node.offsetWidth, width: node.offsetWidth,
}); });
@ -271,10 +275,12 @@ export default class MediaGallery extends React.PureComponent {
} }
render () { render () {
const { media, intl, sensitive, letterbox, fullwidth } = this.props; const { media, intl, sensitive, letterbox, fullwidth, defaultWidth } = this.props;
const { width, visible } = this.state; const { visible } = this.state;
const size = media.take(4).size; const size = media.take(4).size;
const width = this.state.width || defaultWidth;
let children; let children;
const style = {}; const style = {};

View File

@ -40,6 +40,7 @@ export default class ScrollableList extends PureComponent {
state = { state = {
fullscreen: null, fullscreen: null,
cachedMediaWidth: 300,
}; };
intersectionObserverWrapper = new IntersectionObserverWrapper(); intersectionObserverWrapper = new IntersectionObserverWrapper();
@ -141,6 +142,10 @@ export default class ScrollableList extends PureComponent {
this.setScrollTop(newScrollTop); this.setScrollTop(newScrollTop);
} }
cacheMediaWidth = (width) => {
if (width && this.state.cachedMediaWidth != width) this.setState({ cachedMediaWidth: width });
}
getSnapshotBeforeUpdate (prevProps, prevState) { getSnapshotBeforeUpdate (prevProps, prevState) {
const someItemInserted = React.Children.count(prevProps.children) > 0 && const someItemInserted = React.Children.count(prevProps.children) > 0 &&
React.Children.count(prevProps.children) < React.Children.count(this.props.children) && React.Children.count(prevProps.children) < React.Children.count(this.props.children) &&
@ -252,7 +257,12 @@ export default class ScrollableList extends PureComponent {
intersectionObserverWrapper={this.intersectionObserverWrapper} intersectionObserverWrapper={this.intersectionObserverWrapper}
saveHeightKey={trackScroll ? `${this.context.router.route.location.key}:${scrollKey}` : null} saveHeightKey={trackScroll ? `${this.context.router.route.location.key}:${scrollKey}` : null}
> >
{React.cloneElement(child, {getScrollPosition: this.getScrollPosition, updateScrollBottom: this.updateScrollBottom})} {React.cloneElement(child, {
getScrollPosition: this.getScrollPosition,
updateScrollBottom: this.updateScrollBottom,
cachedMediaWidth: this.state.cachedMediaWidth,
cacheMediaWidth: this.cacheMediaWidth,
})}
</IntersectionObserverArticleContainer> </IntersectionObserverArticleContainer>
))} ))}

View File

@ -72,6 +72,8 @@ export default class Status extends ImmutablePureComponent {
updateScrollBottom: PropTypes.func, updateScrollBottom: PropTypes.func,
expanded: PropTypes.bool, expanded: PropTypes.bool,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
cacheMediaWidth: PropTypes.func,
cachedMediaWidth: PropTypes.number,
}; };
state = { state = {
@ -445,6 +447,8 @@ export default class Status extends ImmutablePureComponent {
fullwidth={settings.getIn(['media', 'fullwidth'])} fullwidth={settings.getIn(['media', 'fullwidth'])}
preventPlayback={isCollapsed || !isExpanded} preventPlayback={isCollapsed || !isExpanded}
onOpenVideo={this.handleOpenVideo} onOpenVideo={this.handleOpenVideo}
width={this.props.cachedMediaWidth}
cacheWidth={this.props.cacheMediaWidth}
/>)} />)}
</Bundle> </Bundle>
); );
@ -460,6 +464,8 @@ export default class Status extends ImmutablePureComponent {
fullwidth={settings.getIn(['media', 'fullwidth'])} fullwidth={settings.getIn(['media', 'fullwidth'])}
hidden={isCollapsed || !isExpanded} hidden={isCollapsed || !isExpanded}
onOpenMedia={this.props.onOpenMedia} onOpenMedia={this.props.onOpenMedia}
cacheWidth={this.props.cacheMediaWidth}
defaultWidth={this.props.cachedMediaWidth}
/> />
)} )}
</Bundle> </Bundle>
@ -476,6 +482,8 @@ export default class Status extends ImmutablePureComponent {
onOpenMedia={this.props.onOpenMedia} onOpenMedia={this.props.onOpenMedia}
card={status.get('card')} card={status.get('card')}
compact compact
cacheWidth={this.props.cacheMediaWidth}
defaultWidth={this.props.cachedMediaWidth}
/> />
); );
mediaIcon = 'link'; mediaIcon = 'link';

View File

@ -18,6 +18,9 @@ export default class Notification extends ImmutablePureComponent {
onMention: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired,
getScrollPosition: PropTypes.func, getScrollPosition: PropTypes.func,
updateScrollBottom: PropTypes.func, updateScrollBottom: PropTypes.func,
cacheMediaWidth: PropTypes.func,
cachedMediaWidth: PropTypes.number,
onUnmount: PropTypes.func,
}; };
render () { render () {
@ -57,6 +60,9 @@ export default class Notification extends ImmutablePureComponent {
contextType='notifications' contextType='notifications'
getScrollPosition={getScrollPosition} getScrollPosition={getScrollPosition}
updateScrollBottom={updateScrollBottom} updateScrollBottom={updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
onUnmount={this.props.onUnmount}
withDismiss withDismiss
/> />
); );
@ -75,6 +81,9 @@ export default class Notification extends ImmutablePureComponent {
onMention={onMention} onMention={onMention}
getScrollPosition={getScrollPosition} getScrollPosition={getScrollPosition}
updateScrollBottom={updateScrollBottom} updateScrollBottom={updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
onUnmount={this.props.onUnmount}
withDismiss withDismiss
/> />
); );
@ -93,6 +102,9 @@ export default class Notification extends ImmutablePureComponent {
onMention={onMention} onMention={onMention}
getScrollPosition={getScrollPosition} getScrollPosition={getScrollPosition}
updateScrollBottom={updateScrollBottom} updateScrollBottom={updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
onUnmount={this.props.onUnmount}
withDismiss withDismiss
/> />
); );

View File

@ -60,6 +60,8 @@ export default class Card extends React.PureComponent {
maxDescription: PropTypes.number, maxDescription: PropTypes.number,
onOpenMedia: PropTypes.func.isRequired, onOpenMedia: PropTypes.func.isRequired,
compact: PropTypes.bool, compact: PropTypes.bool,
defaultWidth: PropTypes.number,
cacheWidth: PropTypes.func,
}; };
static defaultProps = { static defaultProps = {
@ -68,7 +70,7 @@ export default class Card extends React.PureComponent {
}; };
state = { state = {
width: 280, width: this.props.defaultWidth || 280,
embedded: false, embedded: false,
}; };
@ -111,6 +113,7 @@ export default class Card extends React.PureComponent {
setRef = c => { setRef = c => {
if (c) { if (c) {
if (this.props.cacheWidth) this.props.cacheWidth(c.offsetWidth);
this.setState({ width: c.offsetWidth }); this.setState({ width: c.offsetWidth });
} }
} }
@ -133,7 +136,7 @@ export default class Card extends React.PureComponent {
} }
render () { render () {
const { card, maxDescription, compact } = this.props; const { card, maxDescription, compact, defaultWidth } = this.props;
const { width, embedded } = this.state; const { width, embedded } = this.state;
if (card === null) { if (card === null) {

View File

@ -103,6 +103,7 @@ export default class Video extends React.PureComponent {
inline: PropTypes.bool, inline: PropTypes.bool,
preventPlayback: PropTypes.bool, preventPlayback: PropTypes.bool,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
cacheWidth: PropTypes.func,
}; };
state = { state = {
@ -111,7 +112,7 @@ export default class Video extends React.PureComponent {
volume: 0.5, volume: 0.5,
paused: true, paused: true,
dragging: false, dragging: false,
containerWidth: false, containerWidth: this.props.width,
fullscreen: false, fullscreen: false,
hovered: false, hovered: false,
muted: false, muted: false,
@ -131,6 +132,7 @@ export default class Video extends React.PureComponent {
this.player = c; this.player = c;
if (c && c.offsetWidth && c.offsetWidth != this.state.containerWidth) { if (c && c.offsetWidth && c.offsetWidth != this.state.containerWidth) {
if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth);
this.setState({ this.setState({
containerWidth: c.offsetWidth, containerWidth: c.offsetWidth,
}); });
@ -275,6 +277,7 @@ export default class Video extends React.PureComponent {
componentDidUpdate (prevProps) { componentDidUpdate (prevProps) {
if (this.player && this.player.offsetWidth && this.player.offsetWidth != this.state.containerWidth && !this.state.fullscreen) { if (this.player && this.player.offsetWidth && this.player.offsetWidth != this.state.containerWidth && !this.state.fullscreen) {
if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth);
this.setState({ this.setState({
containerWidth: this.player.offsetWidth, containerWidth: this.player.offsetWidth,
}); });