diff --git a/web/chat/inline-engagement.css b/web/chat/inline-engagement.css
index 27a000c0f..2ed4427a8 100644
--- a/web/chat/inline-engagement.css
+++ b/web/chat/inline-engagement.css
@@ -1,78 +1,71 @@
div.inlineEngagementContainer {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
gap: 4px;
}
div.centerContainer {
justify-content: center;
}
div.leftContainer {
justify-content: flex-start;
position: relative;
top: -10px;
left: 44px;
margin-right: 80px;
}
div.rightContainer {
position: relative;
top: -10px;
right: 33px;
margin-left: 80px;
flex-direction: row-reverse;
}
-a.sidebarContainer,
-a.reactionContainer {
+a.sidebarContainer {
background: var(--inline-engagement-bg);
color: var(--inline-engagement-color);
font-size: var(--s-font-14);
line-height: var(--line-height-text);
transition: background 0.2s ease-in-out;
padding: 4px 8px;
border-radius: 8px;
display: flex;
align-items: center;
gap: 4px;
}
-a.sidebarContainer:hover,
-a.reactionContainer:hover {
+a.sidebarContainer:hover {
background: var(--inline-engagement-bg-hover);
}
-a.reactionContainerSelected {
- border: 1px solid var(--inline-engagement-color);
- padding: 3px 7px;
-}
-
div.unread {
font-weight: bold;
}
svg.inlineEngagementIcon {
color: #666666;
}
div.messageLabel {
display: flex;
flex-shrink: 0;
/* This is the height of the sidebar/reaction pills */
height: 29px;
}
div.messageLabel > span {
font-size: 12px;
padding: 0 3px;
color: var(--message-label-color);
align-self: center;
}
div.messageLabelLeft {
margin-left: 8px;
}
div.messageLabelRight {
margin-right: 8px;
}
diff --git a/web/chat/inline-engagement.react.js b/web/chat/inline-engagement.react.js
index 802652567..efb1cf75b 100644
--- a/web/chat/inline-engagement.react.js
+++ b/web/chat/inline-engagement.react.js
@@ -1,141 +1,114 @@
// @flow
import classNames from 'classnames';
import * as React from 'react';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import type { ReactionInfo } from 'lib/selectors/chat-selectors.js';
import { getInlineEngagementSidebarText } from 'lib/shared/inline-engagement-utils.js';
-import { useNextLocalID } from 'lib/shared/message-utils.js';
import type { MessageInfo } from 'lib/types/message-types.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
import css from './inline-engagement.css';
-import { useSendReaction } from './reaction-message-utils.js';
+import ReactionPill from './reaction-pill.react.js';
import CommIcon from '../CommIcon.react.js';
import { useOnClickThread } from '../selectors/thread-selectors.js';
type Props = {
+messageInfo: MessageInfo,
+threadInfo: ThreadInfo,
+sidebarThreadInfo: ?ThreadInfo,
+reactions: ReactionInfo,
+positioning: 'left' | 'center' | 'right',
+label?: ?string,
};
function InlineEngagement(props: Props): React.Node {
const {
messageInfo,
threadInfo,
sidebarThreadInfo,
reactions,
positioning,
label,
} = props;
const { popModal } = useModalContext();
const isLeft = positioning === 'left';
const labelClasses = classNames({
[css.messageLabel]: true,
[css.messageLabelLeft]: isLeft,
[css.messageLabelRight]: !isLeft,
});
const editedLabel = React.useMemo(() => {
if (!label) {
return null;
}
return (
{label}
);
}, [label, labelClasses]);
const onClickSidebarInner = useOnClickThread(sidebarThreadInfo);
const onClickSidebar = React.useCallback(
(event: SyntheticEvent) => {
popModal();
onClickSidebarInner(event);
},
[popModal, onClickSidebarInner],
);
const repliesText = getInlineEngagementSidebarText(sidebarThreadInfo);
const sidebarItem = React.useMemo(() => {
if (!sidebarThreadInfo || !repliesText) {
return null;
}
return (
{repliesText}
);
}, [sidebarThreadInfo, repliesText, onClickSidebar]);
- const localID = useNextLocalID();
- const sendReaction = useSendReaction(
- messageInfo.id,
- localID,
- threadInfo.id,
- reactions,
- );
-
- const onClickReaction = React.useCallback(
- (event: SyntheticEvent, reaction: string) => {
- event.preventDefault();
- sendReaction(reaction);
- },
- [sendReaction],
- );
-
const reactionsList = React.useMemo(() => {
if (Object.keys(reactions).length === 0) {
return null;
}
- return Object.keys(reactions).map(reaction => {
- const reactionInfo = reactions[reaction];
- const numOfReacts = reactionInfo.users.length;
-
- const reactionClassName = classNames({
- [css.reactionContainer]: true,
- [css.reactionContainerSelected]: reactionInfo.viewerReacted,
- });
-
- return (
- onClickReaction(event, reaction)}
- className={reactionClassName}
- key={reaction}
- >
- {`${reaction} ${numOfReacts}`}
-
- );
- });
- }, [reactions, onClickReaction]);
+ return Object.keys(reactions).map(reaction => (
+
+ ));
+ }, [reactions, messageInfo.id, threadInfo.id]);
const containerClasses = classNames([
css.inlineEngagementContainer,
{
[css.leftContainer]: positioning === 'left',
[css.centerContainer]: positioning === 'center',
[css.rightContainer]: positioning === 'right',
},
]);
return (
{editedLabel}
{sidebarItem}
{reactionsList}
);
}
export default InlineEngagement;
diff --git a/web/chat/reaction-pill.css b/web/chat/reaction-pill.css
new file mode 100644
index 000000000..d56280155
--- /dev/null
+++ b/web/chat/reaction-pill.css
@@ -0,0 +1,21 @@
+a.reactionContainer {
+ background: var(--inline-engagement-bg);
+ color: var(--inline-engagement-color);
+ font-size: var(--s-font-14);
+ line-height: var(--line-height-text);
+ transition: background 0.2s ease-in-out;
+ padding: 4px 8px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+a.reactionContainer:hover {
+ background: var(--inline-engagement-bg-hover);
+}
+
+a.reactionContainerSelected {
+ border: 1px solid var(--inline-engagement-color);
+ padding: 3px 7px;
+}
diff --git a/web/chat/reaction-pill.react.js b/web/chat/reaction-pill.react.js
new file mode 100644
index 000000000..7eda90677
--- /dev/null
+++ b/web/chat/reaction-pill.react.js
@@ -0,0 +1,48 @@
+// @flow
+
+import classNames from 'classnames';
+import * as React from 'react';
+
+import type { ReactionInfo } from 'lib/selectors/chat-selectors.js';
+import { useNextLocalID } from 'lib/shared/message-utils.js';
+
+import { useSendReaction } from './reaction-message-utils.js';
+import css from './reaction-pill.css';
+
+type Props = {
+ +reaction: string,
+ +messageID: ?string,
+ +threadID: string,
+ +reactions: ReactionInfo,
+};
+
+function ReactionPill(props: Props): React.Node {
+ const { reaction, messageID, threadID, reactions } = props;
+
+ const localID = useNextLocalID();
+ const sendReaction = useSendReaction(messageID, localID, threadID, reactions);
+
+ const onClickReaction = React.useCallback(
+ (event: SyntheticEvent) => {
+ event.preventDefault();
+ sendReaction(reaction);
+ },
+ [reaction, sendReaction],
+ );
+
+ const reactionInfo = reactions[reaction];
+ const numOfReacts = reactionInfo.users.length;
+
+ const reactionClassName = classNames({
+ [css.reactionContainer]: true,
+ [css.reactionContainerSelected]: reactionInfo.viewerReacted,
+ });
+
+ return (
+
+ {`${reaction} ${numOfReacts}`}
+
+ );
+}
+
+export default ReactionPill;