[MM-62987] Include description on aria-label for last reply time, make link focused when using up/down arrows. (#30837)
* [MM-62987] Include description on aria-label for last reply time, make link focused when using up/down arrows. * PR feedback --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c33dbe8d37
Коммит
0058edb806
@@ -1,7 +1,9 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/threading/global_threads/thread_item should report total number of replies 1`] = `
|
||||
<div
|
||||
<Fragment>
|
||||
<div
|
||||
aria-describedby="ThreadItem__timestamp_1y8hpek81byspd4enyk9mp1ncw"
|
||||
aria-label="Thread by Someone"
|
||||
className="ThreadItem"
|
||||
id=""
|
||||
@@ -9,7 +11,7 @@ exports[`components/threading/global_threads/thread_item should report total num
|
||||
onKeyDown={[Function]}
|
||||
role="link"
|
||||
tabIndex={0}
|
||||
>
|
||||
>
|
||||
<header>
|
||||
<div
|
||||
className="ThreadItem__author"
|
||||
@@ -115,11 +117,37 @@ exports[`components/threading/global_threads/thread_item should report total num
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
className="sr-only"
|
||||
id="ThreadItem__timestamp_1y8hpek81byspd4enyk9mp1ncw"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Last reply "
|
||||
id="threading.threadItem.timestamp"
|
||||
/>
|
||||
<MockTimestamp
|
||||
className="alt-hidden"
|
||||
day="numeric"
|
||||
units={
|
||||
Array [
|
||||
"now",
|
||||
"minute",
|
||||
"hour",
|
||||
"day",
|
||||
"week",
|
||||
]
|
||||
}
|
||||
useTime={false}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`components/threading/global_threads/thread_item should report unread mentions 1`] = `
|
||||
<div
|
||||
<Fragment>
|
||||
<div
|
||||
aria-describedby="ThreadItem__timestamp_1y8hpek81byspd4enyk9mp1ncw"
|
||||
aria-label="Thread by Someone"
|
||||
className="ThreadItem has-unreads"
|
||||
id=""
|
||||
@@ -127,7 +155,7 @@ exports[`components/threading/global_threads/thread_item should report unread me
|
||||
onKeyDown={[Function]}
|
||||
role="link"
|
||||
tabIndex={0}
|
||||
>
|
||||
>
|
||||
<header>
|
||||
<div
|
||||
className="indicator"
|
||||
@@ -242,11 +270,37 @@ exports[`components/threading/global_threads/thread_item should report unread me
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
className="sr-only"
|
||||
id="ThreadItem__timestamp_1y8hpek81byspd4enyk9mp1ncw"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Last reply "
|
||||
id="threading.threadItem.timestamp"
|
||||
/>
|
||||
<MockTimestamp
|
||||
className="alt-hidden"
|
||||
day="numeric"
|
||||
units={
|
||||
Array [
|
||||
"now",
|
||||
"minute",
|
||||
"hour",
|
||||
"day",
|
||||
"week",
|
||||
]
|
||||
}
|
||||
useTime={false}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`components/threading/global_threads/thread_item should report unread messages 1`] = `
|
||||
<div
|
||||
<Fragment>
|
||||
<div
|
||||
aria-describedby="ThreadItem__timestamp_1y8hpek81byspd4enyk9mp1ncw"
|
||||
aria-label="Thread by Someone"
|
||||
className="ThreadItem has-unreads"
|
||||
id=""
|
||||
@@ -254,7 +308,7 @@ exports[`components/threading/global_threads/thread_item should report unread me
|
||||
onKeyDown={[Function]}
|
||||
role="link"
|
||||
tabIndex={0}
|
||||
>
|
||||
>
|
||||
<header>
|
||||
<div
|
||||
className="indicator"
|
||||
@@ -367,5 +421,29 @@ exports[`components/threading/global_threads/thread_item should report unread me
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
className="sr-only"
|
||||
id="ThreadItem__timestamp_1y8hpek81byspd4enyk9mp1ncw"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Last reply "
|
||||
id="threading.threadItem.timestamp"
|
||||
/>
|
||||
<MockTimestamp
|
||||
className="alt-hidden"
|
||||
day="numeric"
|
||||
units={
|
||||
Array [
|
||||
"now",
|
||||
"minute",
|
||||
"hour",
|
||||
"day",
|
||||
"week",
|
||||
]
|
||||
}
|
||||
useTime={false}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
@@ -266,7 +266,7 @@ describe('components/threading/global_threads/thread_item', () => {
|
||||
|
||||
test('should allow marking as unread on alt + click', () => {
|
||||
const wrapper = shallow(<ThreadItem {...props}/>);
|
||||
wrapper.simulate('click', {altKey: true});
|
||||
wrapper.find('div.ThreadItem').simulate('click', {altKey: true});
|
||||
expect(updateThreadRead).not.toHaveBeenCalled();
|
||||
expect(markLastPostInThreadAsUnread).toHaveBeenCalledWith('user_id', 'tid', '1y8hpek81byspd4enyk9mp1ncw');
|
||||
expect(manuallyMarkThreadAsUnread).toHaveBeenCalledWith('1y8hpek81byspd4enyk9mp1ncw', 1611786714912);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, {memo, useCallback, useEffect, useMemo} from 'react';
|
||||
import React, {memo, useCallback, useEffect, useMemo, useRef} from 'react';
|
||||
import type {MouseEvent, KeyboardEvent} from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
@@ -94,6 +94,7 @@ function ThreadItem({
|
||||
const postAuthor = ensureString(post.props?.override_username) || displayName;
|
||||
const getMentionKeysForPost = useMemo(() => makeGetMentionKeysForPost(), []);
|
||||
const mentionsKeys = useSelector((state: GlobalState) => getMentionKeysForPost(state, post, channel));
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (channel?.teammate_id) {
|
||||
@@ -107,6 +108,12 @@ function ThreadItem({
|
||||
}
|
||||
}, [channel, thread?.post.channel_id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isSelected) {
|
||||
ref.current?.focus();
|
||||
}
|
||||
}, [isSelected, threadId]);
|
||||
|
||||
const participantIds = useMemo(() => {
|
||||
const ids = (thread?.participants || []).flatMap(({id}) => {
|
||||
if (id === post.user_id) {
|
||||
@@ -188,6 +195,7 @@ function ThreadItem({
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
style={style}
|
||||
className={classNames('ThreadItem', {
|
||||
@@ -200,9 +208,11 @@ function ThreadItem({
|
||||
{id: 'threading.threadItem.ariaLabel', defaultMessage: 'Thread by {author}'},
|
||||
{author: postAuthor},
|
||||
)}
|
||||
aria-describedby={`ThreadItem__timestamp_${threadId}`}
|
||||
id={isFirstThreadInList ? 'tutorial-threads-mobile-list' : ''}
|
||||
onClick={selectHandler}
|
||||
onKeyDown={selectHandler}
|
||||
ref={ref}
|
||||
>
|
||||
<header>
|
||||
{Boolean(newMentions || newReplies) && (
|
||||
@@ -315,7 +325,22 @@ function ThreadItem({
|
||||
)}
|
||||
</div>
|
||||
{showListTutorialTip && isFirstThreadInList && isMobileView && (<CRTListTutorialTip/>)}
|
||||
<span
|
||||
className='sr-only'
|
||||
id={`ThreadItem__timestamp_${threadId}`}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='threading.threadItem.timestamp'
|
||||
defaultMessage='Last reply '
|
||||
/>
|
||||
<Timestamp
|
||||
{...THREADING_TIME}
|
||||
className='alt-hidden'
|
||||
value={lastReplyAt}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,9 +120,7 @@ const ThreadList = ({
|
||||
}
|
||||
}
|
||||
select(data[threadIdToSelect]);
|
||||
|
||||
// hacky way to ensure the thread item loses focus.
|
||||
ref.current?.focus();
|
||||
e.preventDefault();
|
||||
}, [selectedThreadId, data]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -5497,6 +5497,7 @@
|
||||
"threading.threadHeader.menu": "More Actions",
|
||||
"threading.threadItem.ariaLabel": "Thread by {author}",
|
||||
"threading.threadItem.menu": "Actions",
|
||||
"threading.threadItem.timestamp": "Last reply ",
|
||||
"threading.threadList.markRead": "Mark all threads as read",
|
||||
"threading.threadList.tabsLabel": "Filter visible threads",
|
||||
"threading.threadMenu.copy": "Copy link",
|
||||
|
||||
Ссылка в новой задаче
Block a user