diff --git a/web/chat/inline-engagement.css b/web/chat/inline-engagement.css index 310e283f0..56ec0da66 100644 --- a/web/chat/inline-engagement.css +++ b/web/chat/inline-engagement.css @@ -1,57 +1,64 @@ div.inlineEngagementContainer { display: flex; + flex-direction: row; + align-items: center; } div.centerContainer { justify-content: center; } div.leftContainer { justify-content: flex-start; position: relative; top: -10px; left: 12px; margin-right: 12px; } div.rightContainer { justify-content: flex-end; position: relative; top: -10px; right: 31px; margin-left: 31px; } -.inlineEngagementContent { + +a.threadsContainer, +a.threadsSplitContainer, +a.reactionsContainer, +a.reactionsSplitContainer { 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: 8px; + gap: 4px; flex-direction: row; display: flex; - border-radius: 16px; - padding: 8px; - cursor: pointer; - gap: 12px; align-items: center; - transition: background 0.2s ease-in-out; } -.inlineEngagementContent:hover { - background: var(--inline-engagement-bg-hover); +a.threadsContainer, +a.reactionsContainer { + border-radius: 16px; } - -div.reactionsContainer { - flex-direction: row; - display: flex; - gap: 4px; +a.threadsSplitContainer { + border-radius: 16px 0 0 16px; } -div.replies { - flex-direction: row; - display: flex; - align-items: center; - gap: 4px; +a.reactionsSplitContainer { + border-radius: 0 16px 16px 0; } + +a.threadsContainer:hover, +a.threadsSplitContainer:hover, +a.reactionsContainer:hover, +a.reactionsSplitContainer:hover { + background: var(--inline-engagement-bg-hover); +} + div.unread { font-weight: bold; } svg.inlineEngagementIcon { color: #666666; } diff --git a/web/chat/inline-engagement.react.js b/web/chat/inline-engagement.react.js index 7ba4a6eaf..96bcd0daf 100644 --- a/web/chat/inline-engagement.react.js +++ b/web/chat/inline-engagement.react.js @@ -1,73 +1,98 @@ // @flow import classNames from 'classnames'; import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; import useInlineEngagementText from 'lib/hooks/inline-engagement-text.react'; import type { MessageReactionInfo } from 'lib/selectors/chat-selectors'; import { stringForReactionList } from 'lib/shared/reaction-utils'; import type { ThreadInfo } from 'lib/types/thread-types'; import CommIcon from '../CommIcon.react'; +import MessageReactionsModal from '../modals/chat/message-reactions-modal.react'; import { useOnClickThread } from '../selectors/thread-selectors'; import css from './inline-engagement.css'; type Props = { +threadInfo: ?ThreadInfo, +reactions?: $ReadOnlyMap, +positioning: 'left' | 'center' | 'right', }; function InlineEngagement(props: Props): React.Node { - const { threadInfo, positioning, reactions } = props; + const { threadInfo, reactions, positioning } = props; + const { pushModal, popModal } = useModalContext(); const repliesText = useInlineEngagementText(threadInfo); const containerClasses = classNames([ css.inlineEngagementContainer, { [css.leftContainer]: positioning === 'left', [css.centerContainer]: positioning === 'center', [css.rightContainer]: positioning === 'right', }, ]); - const reactionsList = React.useMemo(() => { - if (!reactions || reactions.size === 0) { - return null; - } - - const reactionText = stringForReactionList(reactions); + const reactionsExist = reactions && reactions.size > 0; - return
{reactionText}
; - }, [reactions]); + const threadsContainerClasses = classNames({ + [css.threadsContainer]: threadInfo && !reactionsExist, + [css.threadsSplitContainer]: threadInfo && reactionsExist, + }); - const onClick = useOnClickThread(threadInfo); + const reactionsContainerClasses = classNames({ + [css.reactionsContainer]: reactionsExist && !threadInfo, + [css.reactionsSplitContainer]: reactionsExist && threadInfo, + }); - const threadInfoExists = !!threadInfo; + const onClickThread = useOnClickThread(threadInfo); const sidebarItem = React.useMemo(() => { - if (!threadInfoExists || !repliesText) { + if (!threadInfo || !repliesText) { return null; } return ( -
+ {repliesText} -
+ + ); + }, [threadInfo, repliesText, onClickThread, threadsContainerClasses]); + + const onClickReactions = React.useCallback( + (event: SyntheticEvent) => { + event.preventDefault(); + if (!reactions) { + return; + } + pushModal( + , + ); + }, + [popModal, pushModal, reactions], + ); + + const reactionsList = React.useMemo(() => { + if (!reactions || reactions.size === 0) { + return null; + } + + const reactionText = stringForReactionList(reactions); + + return ( + + {reactionText} + ); - }, [threadInfoExists, repliesText]); + }, [reactions, onClickReactions, reactionsContainerClasses]); return (
- - {sidebarItem} - {reactionsList} - + {sidebarItem} + {reactionsList}
); } export default InlineEngagement;