diff --git a/lib/shared/reaction-utils.js b/lib/shared/reaction-utils.js index 5f8e64c96..8f0d3e705 100644 --- a/lib/shared/reaction-utils.js +++ b/lib/shared/reaction-utils.js @@ -1,127 +1,109 @@ // @flow import _sortBy from 'lodash/fp/sortBy.js'; import * as React from 'react'; import { relationshipBlockedInEitherDirection } from './relationship-utils.js'; import { threadHasPermission } from './thread-utils.js'; import { stringForUserExplicit } from './user-utils.js'; import { useENSNames } from '../hooks/ens-cache.js'; import type { ReactionInfo } from '../selectors/chat-selectors.js'; import type { RobotextMessageInfo, ComposableMessageInfo, } from '../types/message-types.js'; import { threadPermissions } from '../types/thread-permission-types.js'; import { type ThreadInfo } from '../types/thread-types.js'; import { useSelector } from '../utils/redux-utils.js'; -function stringForReactionList(reactions: ReactionInfo): string { - const reactionText = []; - - for (const reaction in reactions) { - const reactionInfo = reactions[reaction]; - - reactionText.push(reaction); - const { length: numberOfReacts } = reactionInfo.users; - if (numberOfReacts <= 1) { - continue; - } - reactionText.push(numberOfReacts > 9 ? '9+' : numberOfReacts.toString()); - } - - return reactionText.join(' '); -} - function useViewerAlreadySelectedMessageReactions( reactions: ReactionInfo, ): $ReadOnlyArray { return React.useMemo(() => { const alreadySelectedEmojis = []; for (const reaction in reactions) { const reactionInfo = reactions[reaction]; if (reactionInfo.viewerReacted) { alreadySelectedEmojis.push(reaction); } } return alreadySelectedEmojis; }, [reactions]); } type MessageReactionListInfo = { +id: string, +isViewer: boolean, +reaction: string, +username: string, }; function useMessageReactionsList( reactions: ReactionInfo, ): $ReadOnlyArray { const withoutENSNames = React.useMemo(() => { const result = []; for (const reaction in reactions) { const reactionInfo = reactions[reaction]; reactionInfo.users.forEach(user => { result.push({ ...user, username: stringForUserExplicit(user), reaction, }); }); } const sortByNumReactions = (reactionInfo: MessageReactionListInfo) => { const numOfReactions = reactions[reactionInfo.reaction].users.length; return numOfReactions ? -numOfReactions : 0; }; return _sortBy( ([sortByNumReactions, 'username']: $ReadOnlyArray< ((reactionInfo: MessageReactionListInfo) => mixed) | string, >), )(result); }, [reactions]); return useENSNames(withoutENSNames); } function useCanCreateReactionFromMessage( threadInfo: ThreadInfo, targetMessageInfo: ComposableMessageInfo | RobotextMessageInfo, ): boolean { const targetMessageCreatorRelationship = useSelector( state => state.userStore.userInfos[targetMessageInfo.creator.id] ?.relationshipStatus, ); if ( !targetMessageInfo.id || threadInfo.sourceMessageID === targetMessageInfo.id ) { return false; } const creatorRelationshipHasBlock = targetMessageCreatorRelationship && relationshipBlockedInEitherDirection(targetMessageCreatorRelationship); const hasPermission = threadHasPermission( threadInfo, threadPermissions.REACT_TO_MESSAGE, ); return hasPermission && !creatorRelationshipHasBlock; } export { - stringForReactionList, useViewerAlreadySelectedMessageReactions, useMessageReactionsList, useCanCreateReactionFromMessage, }; diff --git a/lib/shared/reaction-utils.test.js b/lib/shared/reaction-utils.test.js deleted file mode 100644 index afc362408..000000000 --- a/lib/shared/reaction-utils.test.js +++ /dev/null @@ -1,158 +0,0 @@ -// @flow - -import { stringForReactionList } from './reaction-utils.js'; -import type { ReactionInfo } from '../selectors/chat-selectors.js'; - -describe('stringForReactionList(reactions: ReactionInfo)', () => { - it( - 'should return (👍 3) for a message with three user likes' + - ' including the viewer', - () => { - const messageLikesUsers = [ - { id: '83810', isViewer: true, username: 'ginsu' }, - { id: '86622', isViewer: false, username: 'ashoat' }, - { id: '83889', isViewer: false, username: 'atul' }, - ]; - const messageLikesInfo = { - users: messageLikesUsers, - viewerReacted: true, - }; - - const reactions: ReactionInfo = { - '👍': messageLikesInfo, - }; - - expect(stringForReactionList(reactions)).toBe('👍 3'); - }, - ); - - it( - 'should return (👍 3) for a message with three user likes' + - ' not including the viewer', - () => { - const messageLikesUsers = [ - { id: '83810', isViewer: false, username: 'ginsu' }, - { id: '86622', isViewer: false, username: 'ashoat' }, - { id: '83889', isViewer: false, username: 'atul' }, - ]; - const messageLikesInfo = { - users: messageLikesUsers, - viewerReacted: false, - }; - - const reactions: ReactionInfo = { - '👍': messageLikesInfo, - }; - - expect(stringForReactionList(reactions)).toBe('👍 3'); - }, - ); - - it( - 'should return (👍) for a message with one user like' + - ' including the viewer', - () => { - const messageLikesUsers = [ - { id: '83810', isViewer: false, username: 'ginsu' }, - ]; - const messageLikesInfo = { - users: messageLikesUsers, - viewerReacted: true, - }; - - const reactions: ReactionInfo = { - '👍': messageLikesInfo, - }; - - expect(stringForReactionList(reactions)).toBe('👍'); - }, - ); - - it( - 'should return (👍) for a message with one user like' + - ' not including the viewer', - () => { - const messageLikesUsers = [ - { id: '83810', isViewer: false, username: 'ashoat' }, - ]; - const messageLikesInfo = { - users: messageLikesUsers, - viewerReacted: false, - }; - - const reactions: ReactionInfo = { - '👍': messageLikesInfo, - }; - - expect(stringForReactionList(reactions)).toBe('👍'); - }, - ); - - it('should return an empty string for a message no reactions', () => { - const reactions: ReactionInfo = {}; - - expect(stringForReactionList(reactions)).toBe(''); - }); - - it( - 'should return (👍 😆 3) for a message with one like not including' + - ' the viewer and three laugh reactions including the viewer', - () => { - const messageLikesUsers = [ - { id: '83810', isViewer: false, username: 'varun' }, - ]; - const messageLikesInfo = { - users: messageLikesUsers, - viewerReacted: false, - }; - - const messageLaughsUsers = [ - { id: '12345', isViewer: true, username: 'ginsu' }, - { id: '67890', isViewer: false, username: 'ashoat' }, - { id: '83889', isViewer: false, username: 'atul' }, - ]; - const messageLaughsInfo = { - users: messageLaughsUsers, - viewerReacted: true, - }; - - const reactions: ReactionInfo = { - '👍': messageLikesInfo, - '😆': messageLaughsInfo, - }; - - expect(stringForReactionList(reactions)).toBe('👍 😆 3'); - }, - ); - - it( - 'should return (👍 9+) for a message with 12 user likes' + - ' not including the viewer', - () => { - const messageLikesUsers = [ - { id: '86622', isViewer: false, username: 'ginsu' }, - { id: '12345', isViewer: false, username: 'ashoat' }, - { id: '67890', isViewer: false, username: 'atul' }, - { id: '83889', isViewer: false, username: 'varun' }, - { id: '49203', isViewer: false, username: 'tomek' }, - { id: '83029', isViewer: false, username: 'max' }, - { id: '72902', isViewer: false, username: 'jon' }, - { id: '49022', isViewer: false, username: 'mark' }, - { id: '48902', isViewer: false, username: 'kamil' }, - { id: '80922', isViewer: false, username: 'marcin' }, - { id: '12890', isViewer: false, username: 'inka' }, - { id: '67891', isViewer: false, username: 'przemek' }, - ]; - const messageLikesInfo = { - users: messageLikesUsers, - viewerReacted: false, - }; - - const reactions: ReactionInfo = { - '👍': messageLikesInfo, - }; - - expect(stringForReactionList(reactions)).toBe('👍 9+'); - }, - ); -});