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

View File

@ -40,6 +40,7 @@ export default class ScrollableList extends PureComponent {
state = {
fullscreen: null,
cachedMediaWidth: 300,
};
intersectionObserverWrapper = new IntersectionObserverWrapper();
@ -141,6 +142,10 @@ export default class ScrollableList extends PureComponent {
this.setScrollTop(newScrollTop);
}
cacheMediaWidth = (width) => {
if (width && this.state.cachedMediaWidth != width) this.setState({ cachedMediaWidth: width });
}
getSnapshotBeforeUpdate (prevProps, prevState) {
const someItemInserted = React.Children.count(prevProps.children) > 0 &&
React.Children.count(prevProps.children) < React.Children.count(this.props.children) &&
@ -252,7 +257,12 @@ export default class ScrollableList extends PureComponent {
intersectionObserverWrapper={this.intersectionObserverWrapper}
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>
))}

View File

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

View File

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

View File

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

View File

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