[MM-46218] Set focus to highlighted post (#23082)
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
86f3a8bb1f
Коммит
b6caed652a
@@ -10,7 +10,7 @@ import {
|
|||||||
isMeMessage as checkIsMeMessage,
|
isMeMessage as checkIsMeMessage,
|
||||||
isPostPendingOrFailed} from 'mattermost-redux/utils/post_utils';
|
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';
|
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 PostMessageContainer from 'components/post_view/post_message_view';
|
||||||
import {getDateForUnixTicks, makeIsEligibleForClick} from 'utils/utils';
|
import {getDateForUnixTicks, makeIsEligibleForClick} from 'utils/utils';
|
||||||
import {getHistory} from 'utils/browser_history';
|
import {getHistory} from 'utils/browser_history';
|
||||||
|
import {isKeyPressed} from 'utils/keyboard';
|
||||||
|
|
||||||
import {trackEvent} from 'actions/telemetry_actions';
|
import {trackEvent} from 'actions/telemetry_actions';
|
||||||
|
|
||||||
@@ -119,7 +120,7 @@ export type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const PostComponent = (props: Props): JSX.Element => {
|
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 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;
|
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 [fileDropdownOpened, setFileDropdownOpened] = useState(false);
|
||||||
const [fadeOutHighlight, setFadeOutHighlight] = useState(false);
|
const [fadeOutHighlight, setFadeOutHighlight] = useState(false);
|
||||||
const [alt, setAlt] = useState(false);
|
const [alt, setAlt] = useState(false);
|
||||||
|
const [hasReceivedA11yFocus, setHasReceivedA11yFocus] = useState(false);
|
||||||
|
|
||||||
const isSystemMessage = PostUtils.isSystemMessage(post);
|
const isSystemMessage = PostUtils.isSystemMessage(post);
|
||||||
const fromAutoResponder = PostUtils.fromAutoResponder(post);
|
const fromAutoResponder = PostUtils.fromAutoResponder(post);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.shouldHighlight) {
|
if (shouldHighlight) {
|
||||||
const timer = setTimeout(() => setFadeOutHighlight(true), Constants.PERMALINK_FADEOUT);
|
const timer = setTimeout(() => setFadeOutHighlight(true), Constants.PERMALINK_FADEOUT);
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [props.shouldHighlight]);
|
}, [shouldHighlight]);
|
||||||
|
|
||||||
const handleA11yActivateEvent = () => setA11y(true);
|
const handleA11yActivateEvent = () => setA11y(true);
|
||||||
const handleA11yDeactivateEvent = () => setA11y(false);
|
const handleA11yDeactivateEvent = () => setA11y(false);
|
||||||
const handleAlt = (e: KeyboardEvent) => setAlt(e.altKey);
|
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(() => {
|
useEffect(() => {
|
||||||
if (a11yActive) {
|
if (a11yActive) {
|
||||||
postRef.current?.dispatchEvent(new Event(A11yCustomEventTypes.UPDATE));
|
postRef.current?.dispatchEvent(new Event(A11yCustomEventTypes.UPDATE));
|
||||||
@@ -186,6 +206,14 @@ const PostComponent = (props: Props): JSX.Element => {
|
|||||||
};
|
};
|
||||||
}, [hover]);
|
}, [hover]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('keyup', handleA11yKeyboardFocus);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('keyup', handleA11yKeyboardFocus);
|
||||||
|
};
|
||||||
|
}, [handleA11yKeyboardFocus]);
|
||||||
|
|
||||||
const hasSameRoot = (props: Props) => {
|
const hasSameRoot = (props: Props) => {
|
||||||
if (props.isFirstReply) {
|
if (props.isFirstReply) {
|
||||||
return false;
|
return false;
|
||||||
@@ -255,7 +283,7 @@ const PostComponent = (props: Props): JSX.Element => {
|
|||||||
const hovered =
|
const hovered =
|
||||||
hover || fileDropdownOpened || dropdownOpened || a11yActive || props.isPostBeingEdited;
|
hover || fileDropdownOpened || dropdownOpened || a11yActive || props.isPostBeingEdited;
|
||||||
return classNames('a11y__section post', {
|
return classNames('a11y__section post', {
|
||||||
'post--highlight': props.shouldHighlight && !fadeOutHighlight,
|
'post--highlight': shouldHighlight && !fadeOutHighlight,
|
||||||
'same--root': hasSameRoot(props),
|
'same--root': hasSameRoot(props),
|
||||||
'other--root': !hasSameRoot(props) && !isSystemMessage,
|
'other--root': !hasSameRoot(props) && !isSystemMessage,
|
||||||
'post--bot': PostUtils.isFromBot(post),
|
'post--bot': PostUtils.isFromBot(post),
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user