From e4ea80d8089110790bf11f7d4021dbe7b6a866de Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 13:14:30 +0200 Subject: [PATCH] Change thread view to scroll to the selected post rather than the post being replied to (#24685) --- .../mastodon/features/status/index.jsx | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index e5f91071e..4f58c7d2f 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -196,8 +196,8 @@ class Status extends ImmutablePureComponent { dispatch: PropTypes.func.isRequired, status: ImmutablePropTypes.map, isLoading: PropTypes.bool, - ancestorsIds: ImmutablePropTypes.list, - descendantsIds: ImmutablePropTypes.list, + ancestorsIds: ImmutablePropTypes.list.isRequired, + descendantsIds: ImmutablePropTypes.list.isRequired, intl: PropTypes.object.isRequired, askReplyConfirmation: PropTypes.bool, multiColumn: PropTypes.bool, @@ -224,14 +224,9 @@ class Status extends ImmutablePureComponent { UNSAFE_componentWillReceiveProps (nextProps) { if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) { - this._scrolledIntoView = false; this.props.dispatch(fetchStatus(nextProps.params.statusId)); } - if (nextProps.params.statusId && nextProps.ancestorsIds.size > this.props.ancestorsIds.size) { - this._scrolledIntoView = false; - } - if (nextProps.status && nextProps.status.get('id') !== this.state.loadedStatusId) { this.setState({ showMedia: defaultMediaVisibility(nextProps.status), loadedStatusId: nextProps.status.get('id') }); } @@ -584,20 +579,23 @@ class Status extends ImmutablePureComponent { this.node = c; }; - componentDidUpdate () { - if (this._scrolledIntoView) { - return; - } - - const { status, ancestorsIds } = this.props; - - if (status && ancestorsIds && ancestorsIds.size > 0) { - const element = this.node.querySelectorAll('.focusable')[ancestorsIds.size - 1]; + componentDidUpdate (prevProps) { + const { status, ancestorsIds, multiColumn } = this.props; + if (status && (ancestorsIds.size > prevProps.ancestorsIds.size || prevProps.status?.get('id') !== status.get('id'))) { window.requestAnimationFrame(() => { - element.scrollIntoView(true); + this.node?.querySelector('.detailed-status__wrapper')?.scrollIntoView(true); + + // In the single-column interface, `scrollIntoView` will put the post behind the header, + // so compensate for that. + if (!multiColumn) { + const offset = document.querySelector('.column-header__wrapper')?.getBoundingClientRect()?.bottom; + if (offset) { + const scrollingElement = document.scrollingElement || document.body; + scrollingElement.scrollBy(0, -offset); + } + } }); - this._scrolledIntoView = true; } }