[MM-46218] Set focus to highlighted post (#23082)

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Konstantinos Pittas
2023-05-03 08:43:31 +03:00
committed by GitHub
parent 86f3a8bb1f
commit b6caed652a

View File

@@ -10,7 +10,7 @@ import {
isMeMessage as checkIsMeMessage,
isPostPendingOrFailed} from 'mattermost-redux/utils/post_utils';
import Constants, {A11yCustomEventTypes, AppEvents, Locations} from 'utils/constants';
import Constants, {A11yCustomEventTypes, A11yFocusEventDetail, AppEvents, Locations} from 'utils/constants';
import * as PostUtils from 'utils/post_utils';
@@ -38,6 +38,7 @@ import PostBodyAdditionalContent from 'components/post_view/post_body_additional
import PostMessageContainer from 'components/post_view/post_message_view';
import {getDateForUnixTicks, makeIsEligibleForClick} from 'utils/utils';
import {getHistory} from 'utils/browser_history';
import {isKeyPressed} from 'utils/keyboard';
import {trackEvent} from 'actions/telemetry_actions';
@@ -119,7 +120,7 @@ export type Props = {
};
const PostComponent = (props: Props): JSX.Element => {
const {post, togglePostMenu} = props;
const {post, shouldHighlight, togglePostMenu} = props;
const isSearchResultItem = (props.matches && props.matches.length > 0) || props.isMentionSearch || (props.term && props.term.length > 0);
const isRHS = props.location === Locations.RHS_ROOT || props.location === Locations.RHS_COMMENT || props.location === Locations.SEARCH;
@@ -133,24 +134,43 @@ const PostComponent = (props: Props): JSX.Element => {
const [fileDropdownOpened, setFileDropdownOpened] = useState(false);
const [fadeOutHighlight, setFadeOutHighlight] = useState(false);
const [alt, setAlt] = useState(false);
const [hasReceivedA11yFocus, setHasReceivedA11yFocus] = useState(false);
const isSystemMessage = PostUtils.isSystemMessage(post);
const fromAutoResponder = PostUtils.fromAutoResponder(post);
useEffect(() => {
if (props.shouldHighlight) {
if (shouldHighlight) {
const timer = setTimeout(() => setFadeOutHighlight(true), Constants.PERMALINK_FADEOUT);
return () => {
clearTimeout(timer);
};
}
return undefined;
}, [props.shouldHighlight]);
}, [shouldHighlight]);
const handleA11yActivateEvent = () => setA11y(true);
const handleA11yDeactivateEvent = () => setA11y(false);
const handleAlt = (e: KeyboardEvent) => setAlt(e.altKey);
const handleA11yKeyboardFocus = useCallback((e: KeyboardEvent) => {
if (!hasReceivedA11yFocus && shouldHighlight && isKeyPressed(e, Constants.KeyCodes.TAB) && e.shiftKey) {
e.preventDefault();
e.stopPropagation();
setHasReceivedA11yFocus(true);
document.dispatchEvent(new CustomEvent<A11yFocusEventDetail>(
A11yCustomEventTypes.FOCUS, {
detail: {
target: postRef.current,
keyboardOnly: true,
},
},
));
}
}, [hasReceivedA11yFocus, shouldHighlight]);
useEffect(() => {
if (a11yActive) {
postRef.current?.dispatchEvent(new Event(A11yCustomEventTypes.UPDATE));
@@ -186,6 +206,14 @@ const PostComponent = (props: Props): JSX.Element => {
};
}, [hover]);
useEffect(() => {
document.addEventListener('keyup', handleA11yKeyboardFocus);
return () => {
document.removeEventListener('keyup', handleA11yKeyboardFocus);
};
}, [handleA11yKeyboardFocus]);
const hasSameRoot = (props: Props) => {
if (props.isFirstReply) {
return false;
@@ -255,7 +283,7 @@ const PostComponent = (props: Props): JSX.Element => {
const hovered =
hover || fileDropdownOpened || dropdownOpened || a11yActive || props.isPostBeingEdited;
return classNames('a11y__section post', {
'post--highlight': props.shouldHighlight && !fadeOutHighlight,
'post--highlight': shouldHighlight && !fadeOutHighlight,
'same--root': hasSameRoot(props),
'other--root': !hasSameRoot(props) && !isSystemMessage,
'post--bot': PostUtils.isFromBot(post),