diff --git a/webapp/channels/src/components/threading/global_threads/thread_item/__snapshots__/thread_item.test.tsx.snap b/webapp/channels/src/components/threading/global_threads/thread_item/__snapshots__/thread_item.test.tsx.snap index 4ab9139b24..24c4b2943d 100644 --- a/webapp/channels/src/components/threading/global_threads/thread_item/__snapshots__/thread_item.test.tsx.snap +++ b/webapp/channels/src/components/threading/global_threads/thread_item/__snapshots__/thread_item.test.tsx.snap @@ -1,371 +1,449 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`components/threading/global_threads/thread_item should report total number of replies 1`] = ` -
-
-
- Someone -
-
- -
- -
+
- - - } - > - - - - - -
-
- +
+ Someone +
+
+ +
+ + +
+ + + } + > + + + + + +
+
+ + mentionKeys={Array []} + message="test msg" + options={ + Object { + "atMentions": true, + "mentionHighlight": false, + "singleline": true, + } + } + /> +
+
+ + +
+ + + +
-
- - -
-
+ `; exports[`components/threading/global_threads/thread_item should report unread mentions 1`] = ` -
-
-
-
- 2 -
-
-
- Someone -
-
- -
- -
+
- - - } - > - - - - - -
-
- +
+
+ 2 +
+
+
+ Someone +
+
+ +
+ + +
+ + + } + > + + + + + +
+
+ + mentionKeys={Array []} + message="test msg" + options={ + Object { + "atMentions": true, + "mentionHighlight": false, + "singleline": true, + } + } + /> +
+
+ + +
+ + + +
-
- - -
-
+ `; exports[`components/threading/global_threads/thread_item should report unread messages 1`] = ` -
-
-
-
-
-
- Someone -
-
- -
- -
+
- - - } - > - - - - - -
-
- +
+
+
+
+ Someone +
+
+ +
+ + +
+ + + } + > + + + + + +
+
+ + mentionKeys={Array []} + message="test msg" + options={ + Object { + "atMentions": true, + "mentionHighlight": false, + "singleline": true, + } + } + /> +
+
+ + +
+ + + +
-
- - -
-
+
`; diff --git a/webapp/channels/src/components/threading/global_threads/thread_item/thread_item.test.tsx b/webapp/channels/src/components/threading/global_threads/thread_item/thread_item.test.tsx index 90ed8c6c59..cf6969521b 100644 --- a/webapp/channels/src/components/threading/global_threads/thread_item/thread_item.test.tsx +++ b/webapp/channels/src/components/threading/global_threads/thread_item/thread_item.test.tsx @@ -266,7 +266,7 @@ describe('components/threading/global_threads/thread_item', () => { test('should allow marking as unread on alt + click', () => { const wrapper = shallow(); - 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); diff --git a/webapp/channels/src/components/threading/global_threads/thread_item/thread_item.tsx b/webapp/channels/src/components/threading/global_threads/thread_item/thread_item.tsx index 74b33ab961..50e25b9c06 100644 --- a/webapp/channels/src/components/threading/global_threads/thread_item/thread_item.tsx +++ b/webapp/channels/src/components/threading/global_threads/thread_item/thread_item.tsx @@ -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(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,134 +195,152 @@ function ThreadItem({ } return ( -
-
- {Boolean(newMentions || newReplies) && ( -
- {newMentions ? ( -
99})}> - {Math.min(newMentions, 99)} - {newMentions > 99 && '+'} -
- ) : ( -
+ <> +
+
+ {Boolean(newMentions || newReplies) && ( +
+ {newMentions ? ( +
99})}> + {Math.min(newMentions, 99)} + {newMentions > 99 && '+'} +
+ ) : ( +
+ )} +
+ )} +
{postAuthor}
+
+ {channel && postAuthor !== channel?.display_name && ( + + )} + {isPostPriorityEnabled && ( + thread.is_urgent && ( + + ) )}
- )} -
{postAuthor}
-
- {channel && postAuthor !== channel?.display_name && ( - +
+
+ + + )} + > + + + +
+ + {/* The strange interaction here where we need a click/keydown handler messes with the ESLint rules, so we just disable it */} + {/*eslint-disable-next-line jsx-a11y/no-static-element-interactions*/} +
+ {post.message ? ( + - )} - {isPostPriorityEnabled && ( - thread.is_urgent && ( - - ) + ) : ( + )}
- -
-
- + {participantIds?.length ? ( + + ) : null} + {Boolean(totalReplies) && ( + <> + {newReplies ? ( + + ) : ( + + )} + + )} +
+ {showListTutorialTip && isFirstThreadInList && isMobileView && ()} + - - )} - > - - - -
- - {/* The strange interaction here where we need a click/keydown handler messes with the ESLint rules, so we just disable it */} - {/*eslint-disable-next-line jsx-a11y/no-static-element-interactions*/} -
- {post.message ? ( - - ) : ( - - )} -
-
- {participantIds?.length ? ( - - ) : null} - {Boolean(totalReplies) && ( - <> - {newReplies ? ( - - ) : ( - - )} - - )} +
- {showListTutorialTip && isFirstThreadInList && isMobileView && ()} -
+ ); } diff --git a/webapp/channels/src/components/threading/global_threads/thread_list/thread_list.tsx b/webapp/channels/src/components/threading/global_threads/thread_list/thread_list.tsx index a8ba0542b7..75d61cbb70 100644 --- a/webapp/channels/src/components/threading/global_threads/thread_list/thread_list.tsx +++ b/webapp/channels/src/components/threading/global_threads/thread_list/thread_list.tsx @@ -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(() => { diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 51a87f50e8..c276012e5c 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -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",