Fix timeline jumps (#10001)

* 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.

* Adjust scroll when new preview cards appear

* Adjust scroll when statuses above the current scroll position are deleted
This commit is contained in:
ThibG
2019-02-11 13:19:59 +01:00
committed by Eugen Rochko
parent d9f0c7fb84
commit e1dbdf7377
6 changed files with 134 additions and 12 deletions

View File

@ -34,6 +34,10 @@ class Notification extends ImmutablePureComponent {
onToggleHidden: PropTypes.func.isRequired,
status: PropTypes.option,
intl: PropTypes.object.isRequired,
getScrollPosition: PropTypes.func,
updateScrollBottom: PropTypes.func,
cacheMediaWidth: PropTypes.func,
cachedMediaWidth: PropTypes.number,
};
handleMoveUp = () => {
@ -128,6 +132,10 @@ class Notification extends ImmutablePureComponent {
onMoveDown={this.handleMoveDown}
onMoveUp={this.handleMoveUp}
contextType='notifications'
getScrollPosition={this.props.getScrollPosition}
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
/>
);
}
@ -148,7 +156,17 @@ class Notification extends ImmutablePureComponent {
</span>
</div>
<StatusContainer id={notification.get('status')} account={notification.get('account')} muted withDismiss hidden={!!this.props.hidden} />
<StatusContainer
id={notification.get('status')}
account={notification.get('account')}
muted
withDismiss
hidden={!!this.props.hidden}
getScrollPosition={this.props.getScrollPosition}
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
/>
</div>
</HotKeys>
);
@ -170,7 +188,17 @@ class Notification extends ImmutablePureComponent {
</span>
</div>
<StatusContainer id={notification.get('status')} account={notification.get('account')} muted withDismiss hidden={this.props.hidden} />
<StatusContainer
id={notification.get('status')}
account={notification.get('account')}
muted
withDismiss
hidden={this.props.hidden}
getScrollPosition={this.props.getScrollPosition}
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
/>
</div>
</HotKeys>
);

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 });
}
}

View File

@ -99,6 +99,7 @@ class Video extends React.PureComponent {
onCloseVideo: PropTypes.func,
detailed: PropTypes.bool,
inline: PropTypes.bool,
cacheWidth: PropTypes.func,
intl: PropTypes.object.isRequired,
};
@ -108,7 +109,7 @@ class Video extends React.PureComponent {
volume: 0.5,
paused: true,
dragging: false,
containerWidth: false,
containerWidth: this.props.width,
fullscreen: false,
hovered: false,
muted: false,
@ -128,6 +129,7 @@ class Video extends React.PureComponent {
this.player = c;
if (c) {
if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth);
this.setState({
containerWidth: c.offsetWidth,
});