Page MenuHomePhabricator

D6302.id21273.diff
No OneTemporary

D6302.id21273.diff

diff --git a/lib/shared/reaction-utils.js b/lib/shared/reaction-utils.js
--- a/lib/shared/reaction-utils.js
+++ b/lib/shared/reaction-utils.js
@@ -1,6 +1,7 @@
// @flow
import invariant from 'invariant';
+import _sortBy from 'lodash/fp/sortBy';
import type { MessageReactionInfo } from '../selectors/chat-selectors';
import type {
@@ -11,6 +12,7 @@
import { useSelector } from '../utils/redux-utils';
import { relationshipBlockedInEitherDirection } from './relationship-utils';
import { threadHasPermission } from './thread-utils';
+import { stringForUserExplicit } from './user-utils';
function stringForReactionList(
reactions: $ReadOnlyMap<string, MessageReactionInfo>,
@@ -32,6 +34,40 @@
return reactionText.join(' ');
}
+type MessageReactionListInfo = {
+ +id: string,
+ +isViewer: boolean,
+ +reaction: string,
+ +username: string,
+};
+
+function createMessageReactionsList(
+ reactions: $ReadOnlyMap<string, MessageReactionInfo>,
+): $ReadOnlyArray<MessageReactionListInfo> {
+ const result = [];
+
+ for (const [reaction, reactionInfo] of reactions) {
+ reactionInfo.users.forEach(user => {
+ result.push({
+ ...user,
+ username: stringForUserExplicit(user),
+ reaction,
+ });
+ });
+ }
+
+ const sortByNumReactions = (reactionInfo: MessageReactionListInfo) => {
+ const numOfReactions = reactions.get(reactionInfo.reaction)?.users.length;
+ return numOfReactions ? -numOfReactions : 0;
+ };
+
+ return _sortBy(
+ ([sortByNumReactions, 'username']: $ReadOnlyArray<
+ ((reactionInfo: MessageReactionListInfo) => mixed) | string,
+ >),
+ )(result);
+}
+
function useCanCreateReactionFromMessage(
threadInfo: ThreadInfo,
targetMessageInfo: ComposableMessageInfo | RobotextMessageInfo,
@@ -61,4 +97,8 @@
return hasPermission && !creatorRelationshipHasBlock;
}
-export { stringForReactionList, useCanCreateReactionFromMessage };
+export {
+ stringForReactionList,
+ createMessageReactionsList,
+ useCanCreateReactionFromMessage,
+};
diff --git a/web/modals/chat/message-reactions-modal.css b/web/modals/chat/message-reactions-modal.css
new file mode 100644
--- /dev/null
+++ b/web/modals/chat/message-reactions-modal.css
@@ -0,0 +1,16 @@
+div.modalContentContainer {
+ padding: 24px 32px 32px 32px;
+ color: var(--fg);
+ background-color: var(--modal-bg);
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ font-size: var(--l-font-18);
+ gap: 16px;
+}
+
+div.userRowContainer {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+}
diff --git a/web/modals/chat/message-reactions-modal.react.js b/web/modals/chat/message-reactions-modal.react.js
new file mode 100644
--- /dev/null
+++ b/web/modals/chat/message-reactions-modal.react.js
@@ -0,0 +1,37 @@
+// @flow
+
+import * as React from 'react';
+
+import type { MessageReactionInfo } from 'lib/selectors/chat-selectors';
+import { createMessageReactionsList } from 'lib/shared/reaction-utils';
+
+import Modal from '../modal.react';
+import css from './message-reactions-modal.css';
+
+type Props = {
+ +onClose: () => void,
+ +reactions: $ReadOnlyMap<string, MessageReactionInfo>,
+};
+
+function MessageReactionsModal(props: Props): React.Node {
+ const { onClose, reactions } = props;
+
+ const reactionsList = React.useMemo(() => {
+ const messageReactionsList = createMessageReactionsList(reactions);
+
+ return messageReactionsList.map(messageReactionUser => (
+ <div key={messageReactionUser.id} className={css.userRowContainer}>
+ <div>{messageReactionUser.username}</div>
+ <div>{messageReactionUser.reaction}</div>
+ </div>
+ ));
+ }, [reactions]);
+
+ return (
+ <Modal size="large" name="Reactions" onClose={onClose}>
+ <div className={css.modalContentContainer}>{reactionsList}</div>
+ </Modal>
+ );
+}
+
+export default MessageReactionsModal;

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 19, 4:05 PM (21 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2677638
Default Alt Text
D6302.id21273.diff (3 KB)

Event Timeline