diff --git a/app/soapbox/components/scrollable_list.tsx b/app/soapbox/components/scrollable_list.tsx index c2497547b..3cd3f5132 100644 --- a/app/soapbox/components/scrollable_list.tsx +++ b/app/soapbox/components/scrollable_list.tsx @@ -42,6 +42,7 @@ interface IScrollableList extends VirtuosoProps { onRefresh?: () => Promise, className?: string, itemClassName?: string, + id?: string, style?: React.CSSProperties, useWindowScroll?: boolean } @@ -60,6 +61,7 @@ const ScrollableList = React.forwardRef(({ onLoadMore, className, itemClassName, + id, hasMore, placeholderComponent: Placeholder, placeholderCount = 0, @@ -133,6 +135,7 @@ const ScrollableList = React.forwardRef(({ const renderFeed = (): JSX.Element => ( { } handleHotkeyMoveUp = (e?: KeyboardEvent): void => { - // FIXME: what's going on here? - // this.props.onMoveUp(this.props.status.id, e?.target?.getAttribute('data-featured')); + this.props.onMoveUp(this.props.status.id, this.props.featured); } handleHotkeyMoveDown = (e?: KeyboardEvent): void => { - // FIXME: what's going on here? - // this.props.onMoveDown(this.props.status.id, e?.target?.getAttribute('data-featured')); + this.props.onMoveDown(this.props.status.id, this.props.featured); } handleHotkeyToggleHidden = (): void => { @@ -601,7 +599,7 @@ class Status extends ImmutablePureComponent { return (
{ + const element = document.querySelector(`#status-list [data-index="${index}"] .focusable`); - if (element) { - if (align_top && container.scrollTop > element.offsetTop) { - element.scrollIntoView(true); - } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) { - element.scrollIntoView(false); - } - element.focus(); - } + if (element) { + element.focus(); + } + }, + }); } handleDequeueTimeline = () => { @@ -216,6 +216,7 @@ export default class StatusList extends ImmutablePureComponent { message={messages.queue} />, { const elementIndex = this.getCurrentIndex(id) - 1; - this._selectChild(elementIndex, true); + this._selectChild(elementIndex); } handleMoveDown = id => { const elementIndex = this.getCurrentIndex(id) + 1; - this._selectChild(elementIndex, false); + this._selectChild(elementIndex); } - _selectChild(index, align_top) { - const container = this.node.node; - const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`); + _selectChild(index) { + this.node.scrollIntoView({ + index, + behavior: 'smooth', + done: () => { + const element = document.querySelector(`#direct-list [data-index="${index}"] .focusable`); - if (element) { - if (align_top && container.scrollTop > element.offsetTop) { - element.scrollIntoView(true); - } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) { - element.scrollIntoView(false); - } - element.focus(); - } + if (element) { + element.focus(); + } + }, + }); } setRef = c => { @@ -58,7 +58,9 @@ export default class ConversationsList extends ImmutablePureComponent { diff --git a/app/soapbox/features/notifications/index.js b/app/soapbox/features/notifications/index.js index 69c18799e..05fed79a7 100644 --- a/app/soapbox/features/notifications/index.js +++ b/app/soapbox/features/notifications/index.js @@ -111,32 +111,37 @@ class Notifications extends React.PureComponent { this.props.dispatch(scrollTopNotifications(false)); }, 100); + setRef = c => { + this.node = c; + } + setColumnRef = c => { this.column = c; } handleMoveUp = id => { const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1; - this._selectChild(elementIndex, true); + this._selectChild(elementIndex); } handleMoveDown = id => { const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1; - this._selectChild(elementIndex, false); + this._selectChild(elementIndex); } - _selectChild(index, align_top) { - const container = this.column; - const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`); + _selectChild(index) { + this.node.scrollIntoView({ + index, + behavior: 'smooth', + done: () => { + const container = this.column; + const element = container.querySelector(`[data-index="${index}"] .focusable`); - if (element) { - if (align_top && container.scrollTop > element.offsetTop) { - element.scrollIntoView(true); - } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) { - element.scrollIntoView(false); - } - element.focus(); - } + if (element) { + element.focus(); + } + }, + }); } handleDequeueNotifications = () => { @@ -161,6 +166,7 @@ class Notifications extends React.PureComponent { const scrollContainer = ( {