mirror of
https://github.com/mastodon/mastodon.git
synced 2025-09-07 10:22:48 +00:00
fix: Fix glitchy status keyboard navigation (#35455)
This commit is contained in:
parent
760d00b7f7
commit
d36236cbcd
|
@ -40,6 +40,12 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
trackScroll: true,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.columnHeaderHeight = parseFloat(
|
||||
getComputedStyle(this.node.node).getPropertyValue('--column-header-height')
|
||||
) || 0;
|
||||
}
|
||||
|
||||
getFeaturedStatusCount = () => {
|
||||
return this.props.featuredStatusIds ? this.props.featuredStatusIds.size : 0;
|
||||
};
|
||||
|
@ -53,35 +59,68 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
};
|
||||
|
||||
handleMoveUp = (id, featured) => {
|
||||
const elementIndex = this.getCurrentStatusIndex(id, featured) - 1;
|
||||
this._selectChild(elementIndex, true);
|
||||
const index = this.getCurrentStatusIndex(id, featured);
|
||||
this._selectChild(id, index, -1);
|
||||
};
|
||||
|
||||
handleMoveDown = (id, featured) => {
|
||||
const elementIndex = this.getCurrentStatusIndex(id, featured) + 1;
|
||||
this._selectChild(elementIndex, false);
|
||||
const index = this.getCurrentStatusIndex(id, featured);
|
||||
this._selectChild(id, index, 1);
|
||||
};
|
||||
|
||||
_selectChild = (id, index, direction) => {
|
||||
const listContainer = this.node.node;
|
||||
let listItem = listContainer.querySelector(
|
||||
// :nth-child uses 1-based indexing
|
||||
`.item-list > :nth-child(${index + 1 + direction})`
|
||||
);
|
||||
|
||||
if (!listItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If selected container element is empty, we skip it
|
||||
if (listItem.matches(':empty')) {
|
||||
this._selectChild(id, index + direction, direction);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the list item is a post
|
||||
let targetElement = listItem.querySelector('.focusable');
|
||||
|
||||
// Otherwise, check if the item contains follow suggestions or
|
||||
// is a 'load more' button.
|
||||
if (
|
||||
!targetElement && (
|
||||
listItem.querySelector('.inline-follow-suggestions') ||
|
||||
listItem.matches('.load-more')
|
||||
)
|
||||
) {
|
||||
targetElement = listItem;
|
||||
}
|
||||
|
||||
if (targetElement) {
|
||||
const elementRect = targetElement.getBoundingClientRect();
|
||||
|
||||
const isFullyVisible =
|
||||
elementRect.top >= this.columnHeaderHeight &&
|
||||
elementRect.bottom <= window.innerHeight;
|
||||
|
||||
if (!isFullyVisible) {
|
||||
targetElement.scrollIntoView({
|
||||
block: direction === 1 ? 'start' : 'center',
|
||||
});
|
||||
}
|
||||
|
||||
targetElement.focus();
|
||||
}
|
||||
}
|
||||
|
||||
handleLoadOlder = debounce(() => {
|
||||
const { statusIds, lastId, onLoadMore } = this.props;
|
||||
onLoadMore(lastId || (statusIds.size > 0 ? statusIds.last() : undefined));
|
||||
}, 300, { leading: true });
|
||||
|
||||
_selectChild (index, align_top) {
|
||||
const container = this.node.node;
|
||||
// TODO: This breaks at the inline-follow-suggestions container
|
||||
const element = container.querySelector(`article:nth-of-type(${index + 1}) .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();
|
||||
}
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.node = c;
|
||||
};
|
||||
|
|
|
@ -2868,6 +2868,8 @@ a.account__display-name {
|
|||
}
|
||||
|
||||
&__main {
|
||||
--column-header-height: 62px;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
flex: 0 1 auto;
|
||||
|
@ -8815,6 +8817,10 @@ noscript {
|
|||
.conversation {
|
||||
position: relative;
|
||||
|
||||
// When scrolling these elements into view, take into account
|
||||
// the column header height
|
||||
scroll-margin-top: var(--column-header-height, 0);
|
||||
|
||||
&.unread {
|
||||
&::before {
|
||||
content: '';
|
||||
|
|
Loading…
Reference in New Issue
Block a user