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 c0a564feaa
commit aee93bfc9c
6 changed files with 134 additions and 12 deletions

View file

@ -35,6 +35,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 = () => {
@ -129,6 +133,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}
/>
);
}
@ -149,7 +157,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>
);
@ -171,7 +189,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

@ -61,6 +61,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 = {
@ -69,7 +71,7 @@ export default class Card extends React.PureComponent {
};
state = {
width: 280,
width: this.props.defaultWidth || 280,
embedded: false,
};
@ -112,6 +114,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

@ -100,6 +100,7 @@ class Video extends React.PureComponent {
onCloseVideo: PropTypes.func,
detailed: PropTypes.bool,
inline: PropTypes.bool,
cacheWidth: PropTypes.func,
intl: PropTypes.object.isRequired,
};
@ -109,7 +110,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,
@ -129,6 +130,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,
});