Improvements for keyboard navigation in feeds (#35853)

This commit is contained in:
diondiondion 2025-08-22 11:57:39 +02:00 committed by GitHub
commit 118c30fbc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 196 additions and 331 deletions

View file

@ -45,7 +45,7 @@ const getAccounts = createSelector(
const getStatus = makeGetStatus();
export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown }) => {
export const Conversation = ({ conversation, scrollKey }) => {
const id = conversation.get('id');
const unread = conversation.get('unread');
const lastStatusId = conversation.get('last_status');
@ -110,14 +110,6 @@ export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown })
dispatch(deleteConversation(id));
}, [dispatch, id]);
const handleHotkeyMoveUp = useCallback(() => {
onMoveUp(id);
}, [id, onMoveUp]);
const handleHotkeyMoveDown = useCallback(() => {
onMoveDown(id);
}, [id, onMoveDown]);
const handleConversationMute = useCallback(() => {
if (lastStatus.get('muted')) {
dispatch(unmuteStatus(lastStatus.get('id')));
@ -161,8 +153,6 @@ export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown })
const handlers = {
reply: handleReply,
open: handleClick,
moveUp: handleHotkeyMoveUp,
moveDown: handleHotkeyMoveDown,
toggleHidden: handleShowMore,
};
@ -224,6 +214,4 @@ export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown })
Conversation.propTypes = {
conversation: ImmutablePropTypes.map.isRequired,
scrollKey: PropTypes.string,
onMoveUp: PropTypes.func,
onMoveDown: PropTypes.func,
};

View file

@ -10,20 +10,6 @@ import ScrollableList from 'mastodon/components/scrollable_list';
import { Conversation } from './conversation';
const focusChild = (node, index, alignTop) => {
const element = node.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
if (element) {
if (alignTop && node.scrollTop > element.offsetTop) {
element.scrollIntoView(true);
} else if (!alignTop && node.scrollTop + node.clientHeight < element.offsetTop + element.offsetHeight) {
element.scrollIntoView(false);
}
element.focus();
}
};
export const ConversationsList = ({ scrollKey, ...other }) => {
const listRef = useRef();
const conversations = useSelector(state => state.getIn(['conversations', 'items']));
@ -32,16 +18,6 @@ export const ConversationsList = ({ scrollKey, ...other }) => {
const dispatch = useDispatch();
const lastStatusId = conversations.last()?.get('last_status');
const handleMoveUp = useCallback(id => {
const elementIndex = conversations.findIndex(x => x.get('id') === id) - 1;
focusChild(listRef.current.node, elementIndex, true);
}, [listRef, conversations]);
const handleMoveDown = useCallback(id => {
const elementIndex = conversations.findIndex(x => x.get('id') === id) + 1;
focusChild(listRef.current.node, elementIndex, false);
}, [listRef, conversations]);
const debouncedLoadMore = useMemo(() => debounce(id => {
dispatch(expandConversations({ maxId: id }));
}, 300, { leading: true }), [dispatch]);
@ -58,8 +34,6 @@ export const ConversationsList = ({ scrollKey, ...other }) => {
<Conversation
key={item.get('id')}
conversation={item}
onMoveUp={handleMoveUp}
onMoveDown={handleMoveDown}
scrollKey={scrollKey}
/>
))}