MM-50577 Replaced makeCreateAriaLabelForPost with better memoized usePostAriaLabel (#22833)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
024a5472ff
Коммит
21b72c7607
@@ -1,36 +1,24 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useRef} from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
import {useIntl} from 'react-intl';
|
||||
import React from 'react';
|
||||
|
||||
import {Post} from '@mattermost/types/posts';
|
||||
|
||||
import {GlobalState} from 'types/store';
|
||||
|
||||
import {makeCreateAriaLabelForPost} from 'utils/post_utils';
|
||||
import {usePostAriaLabel} from 'utils/post_utils';
|
||||
|
||||
export type Props = React.HTMLProps<HTMLDivElement> & {
|
||||
labelPrefix?: string;
|
||||
post: Post;
|
||||
}
|
||||
|
||||
const PostAriaLabelDiv = React.forwardRef((props: Props, ref: React.Ref<HTMLDivElement>) => {
|
||||
const {
|
||||
children,
|
||||
labelPrefix,
|
||||
post,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
const createAriaLabelForPost = useRef(makeCreateAriaLabelForPost());
|
||||
let ariaLabel = useSelector<GlobalState, string>((state) => createAriaLabelForPost.current(state, post)(intl));
|
||||
if (labelPrefix) {
|
||||
ariaLabel = labelPrefix + ariaLabel;
|
||||
}
|
||||
const ariaLabel = usePostAriaLabel(post);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -77,4 +77,18 @@ describe('LatestPostReader', () => {
|
||||
expect(span.prop('children')).toContain(author.username);
|
||||
expect(span.prop('children')).toContain('enero');
|
||||
});
|
||||
|
||||
test('should be able to handle an empty post array', () => {
|
||||
const {mountOptions} = mockStore(baseState);
|
||||
|
||||
const props = {
|
||||
...baseProps,
|
||||
postIds: [],
|
||||
};
|
||||
|
||||
const wrapper = mount(<LatestPostReader {...props}/>, mountOptions);
|
||||
const span = wrapper.childAt(0);
|
||||
|
||||
expect(span.prop('children')).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useMemo, useRef} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import React, {useMemo} from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
|
||||
import {getPost} from 'mattermost-redux/selectors/entities/posts';
|
||||
@@ -11,27 +10,18 @@ import {Post} from '@mattermost/types/posts';
|
||||
|
||||
import {GlobalState} from 'types/store';
|
||||
|
||||
import {getLatestPostId, makeCreateAriaLabelForPost} from 'utils/post_utils';
|
||||
import {getLatestPostId, usePostAriaLabel} from 'utils/post_utils';
|
||||
|
||||
interface Props {
|
||||
postIds?: string[];
|
||||
}
|
||||
|
||||
const LatestPostReader = (props: Props): JSX.Element => {
|
||||
const intl = useIntl();
|
||||
|
||||
const {postIds} = props;
|
||||
const latestPostId = useMemo(() => getLatestPostId(postIds || []), [postIds]);
|
||||
const latestPost = useSelector<GlobalState, Post>((state) => getPost(state, latestPostId));
|
||||
|
||||
const createAriaLabelForPost = useRef(makeCreateAriaLabelForPost());
|
||||
const ariaLabel = useSelector<GlobalState, string>((state) => {
|
||||
if (!latestPost) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return createAriaLabelForPost.current(state, latestPost)(intl);
|
||||
});
|
||||
const ariaLabel = usePostAriaLabel(latestPost);
|
||||
|
||||
return (
|
||||
<span
|
||||
|
||||
@@ -71,13 +71,13 @@ export function getReactionsForPosts(state: GlobalState): RelationOneToOne<Post,
|
||||
|
||||
export function makeGetReactionsForPost(): (state: GlobalState, postId: Post['id']) => {
|
||||
[x: string]: Reaction;
|
||||
} | undefined | null {
|
||||
} | undefined {
|
||||
return createSelector('makeGetReactionsForPost', getReactionsForPosts, (state: GlobalState, postId: string) => postId, (reactions, postId) => {
|
||||
if (reactions[postId]) {
|
||||
return reactions[postId];
|
||||
}
|
||||
|
||||
return null;
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {IntlShape} from 'react-intl';
|
||||
import {IntlShape, useIntl} from 'react-intl';
|
||||
|
||||
import {useMemo} from 'react';
|
||||
|
||||
import {useSelector} from 'react-redux';
|
||||
|
||||
import {createSelector} from 'reselect';
|
||||
|
||||
@@ -17,6 +21,8 @@ import {haveIChannelPermission} from 'mattermost-redux/selectors/entities/roles'
|
||||
import {getCurrentTeamId, getTeam} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {makeGetDisplayName, getCurrentUserId, getUser, UserMentionKey, getUsersByUsername} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {memoizeResult} from 'mattermost-redux/utils/helpers';
|
||||
|
||||
import {Channel} from '@mattermost/types/channels';
|
||||
import {ClientConfig, ClientLicense} from '@mattermost/types/config';
|
||||
import {ServerError} from '@mattermost/types/errors';
|
||||
@@ -42,8 +48,8 @@ import {allAtMentions} from 'utils/text_formatting';
|
||||
import {isMobile} from 'utils/user_agent';
|
||||
import * as Utils from 'utils/utils';
|
||||
|
||||
import * as Emoticons from './emoticons';
|
||||
import EmojiMap from './emoji_map';
|
||||
import * as Emoticons from './emoticons';
|
||||
|
||||
const CHANNEL_SWITCH_IGNORE_ENTER_THRESHOLD_MS = 500;
|
||||
|
||||
@@ -443,27 +449,41 @@ export function makeGetMentionsFromMessage(): (state: GlobalState, post: Post) =
|
||||
);
|
||||
}
|
||||
|
||||
export function makeCreateAriaLabelForPost(): (state: GlobalState, post: Post) => (intl: IntlShape) => string {
|
||||
const getReactionsForPost = makeGetUniqueReactionsToPost();
|
||||
const getDisplayName = makeGetDisplayName();
|
||||
const getMentionsFromMessage = makeGetMentionsFromMessage();
|
||||
export function usePostAriaLabel(post: Post | undefined) {
|
||||
const intl = useIntl();
|
||||
|
||||
return createSelector(
|
||||
'makeCreateAriaLabelForPost',
|
||||
(state: GlobalState, post: Post) => post,
|
||||
(state: GlobalState, post: Post) => getDisplayName(state, post.user_id),
|
||||
(state: GlobalState, post: Post) => getReactionsForPost(state, post.id),
|
||||
(state: GlobalState, post: Post) => get(state, Preferences.CATEGORY_FLAGGED_POST, post.id, null) != null,
|
||||
getEmojiMap,
|
||||
(state: GlobalState, post: Post) => getMentionsFromMessage(state, post),
|
||||
(state: GlobalState) => getTeammateNameDisplaySetting(state),
|
||||
(post, author, reactions, isFlagged, emojiMap, mentions, teammateNameDisplaySetting) => {
|
||||
return (intl: IntlShape) => createAriaLabelForPost(post, author, isFlagged, reactions ?? {}, intl, emojiMap, mentions, teammateNameDisplaySetting);
|
||||
},
|
||||
);
|
||||
const getDisplayName = useMemo(makeGetDisplayName, []);
|
||||
const getReactionsForPost = useMemo(makeGetReactionsForPost, []);
|
||||
const getMentionsFromMessage = useMemo(makeGetMentionsFromMessage, []);
|
||||
|
||||
const createAriaLabelMemoized = memoizeResult(createAriaLabelForPost);
|
||||
|
||||
return useSelector((state: GlobalState) => {
|
||||
if (!post) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const authorDisplayName = getDisplayName(state, post.user_id);
|
||||
const reactions = getReactionsForPost(state, post?.id);
|
||||
const isFlagged = get(state, Preferences.CATEGORY_FLAGGED_POST, post.id, null) != null;
|
||||
const emojiMap = getEmojiMap(state);
|
||||
const mentions = getMentionsFromMessage(state, post);
|
||||
const teammateNameDisplaySetting = getTeammateNameDisplaySetting(state);
|
||||
|
||||
return createAriaLabelMemoized(
|
||||
post,
|
||||
authorDisplayName,
|
||||
isFlagged,
|
||||
reactions,
|
||||
intl,
|
||||
emojiMap,
|
||||
mentions,
|
||||
teammateNameDisplaySetting,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function createAriaLabelForPost(post: Post, author: string, isFlagged: boolean, reactions: Record<string, Reaction>, intl: IntlShape, emojiMap: EmojiMap, mentions: Record<string, UserProfile>, teammateNameDisplaySetting: string): string {
|
||||
export function createAriaLabelForPost(post: Post, author: string, isFlagged: boolean, reactions: Record<string, Reaction> | undefined, intl: IntlShape, emojiMap: EmojiMap, mentions: Record<string, UserProfile>, teammateNameDisplaySetting: string): string {
|
||||
const {formatMessage, formatTime, formatDate} = intl;
|
||||
|
||||
let message = post.state === Posts.POST_DELETED ? formatMessage({
|
||||
|
||||
Ссылка в новой задаче
Block a user