From 398f30c4befcf244b4e0f65a8a935484e55bcf72 Mon Sep 17 00:00:00 2001 From: dominic Date: Sat, 4 Jan 2025 10:31:32 +0000 Subject: [PATCH] refactor: open emoji picker in place of common reaction tray --- .../message-input/emoji-picker/styles.scss | 6 +- src/components/message/index.tsx | 1 + src/components/reaction-menu/index.tsx | 145 ++---------------- src/components/reaction-menu/styles.scss | 54 +------ 4 files changed, 18 insertions(+), 188 deletions(-) diff --git a/src/components/message-input/emoji-picker/styles.scss b/src/components/message-input/emoji-picker/styles.scss index 1efb59ec7..cef69ccb0 100644 --- a/src/components/message-input/emoji-picker/styles.scss +++ b/src/components/message-input/emoji-picker/styles.scss @@ -494,7 +494,7 @@ .emoji-mart-dark { @include glass-text-primary-color; border-color: #000; - background-color: #0a0a0abf; + background-color: rgba(10, 10, 10, 1); } .emoji-mart-dark .emoji-mart-bar { @@ -505,7 +505,7 @@ @include glass-text-primary-color; border-color: #000; - background-color: #0a0a0abf; + background-color: rgba(10, 10, 10, 1); } .emoji-mart-dark .emoji-mart-search-icon svg { @@ -519,7 +519,7 @@ .emoji-mart-dark .emoji-mart-category-label span { @include glass-text-primary-color; - background-color: #0a0a0abf; + background-color: rgba(10, 10, 10, 1); } .emoji-mart-dark .emoji-mart-skin-swatches { diff --git a/src/components/message/index.tsx b/src/components/message/index.tsx index 3fa911c8e..67b2910d9 100644 --- a/src/components/message/index.tsx +++ b/src/components/message/index.tsx @@ -547,6 +547,7 @@ export class Message extends React.Component { const reactionProps = { onOpenChange: this.handleOpenReactionMenu, onSelectReaction: this.onEmojiReaction, + isOwner: this.props.isOwner, }; const onClose = () => { diff --git a/src/components/reaction-menu/index.tsx b/src/components/reaction-menu/index.tsx index 0a96dfd1e..dc56fb016 100644 --- a/src/components/reaction-menu/index.tsx +++ b/src/components/reaction-menu/index.tsx @@ -1,39 +1,30 @@ import React, { createRef } from 'react'; import { createPortal } from 'react-dom'; -import { Emoji, Picker } from 'emoji-mart'; +import { Picker } from 'emoji-mart'; import { IconButton } from '@zero-tech/zui/components'; -import { IconDotsHorizontal, IconHeart } from '@zero-tech/zui/icons'; +import { IconHeart } from '@zero-tech/zui/icons'; import { ViewModes } from '../../shared-components/theme-engine'; import './styles.scss'; +import classNames from 'classnames'; export interface Properties { + isOwner: boolean; onOpenChange?: (isOpen: boolean) => void; onSelectReaction: (emoji) => void; } export interface State { - isReactionTrayOpen: boolean; isEmojiPickerOpen: boolean; isProcessing: boolean; } -const commonEmojiMapping = { - thumbsup: '👍', - heart: '❤️', - joy: '😂', - cry: '😢', - astonished: '😲', -}; - export class ReactionMenu extends React.Component { - ref = createRef(); triggerRef = createRef(); emojiPickerRef = createRef(); state = { - isReactionTrayOpen: false, isEmojiPickerOpen: false, isProcessing: false, }; @@ -51,14 +42,12 @@ export class ReactionMenu extends React.Component { if ( !( - (this.ref.current && this.ref.current.contains(event.target)) || (this.triggerRef.current && this.triggerRef.current.contains(event.target)) || (this.emojiPickerRef.current && this.emojiPickerRef.current.contains(event.target)) ) ) { this.setState( { - isReactionTrayOpen: false, isEmojiPickerOpen: false, isProcessing: false, }, @@ -69,126 +58,18 @@ export class ReactionMenu extends React.Component { } }; - onSelect = (emojiId) => { - console.log('Reaction clicked:', emojiId); - if (this.state.isProcessing) { - console.log('Processing state prevented click'); - return; - } - - this.setState({ isProcessing: true }, async () => { - console.log('Starting reaction processing'); - try { - const emojiCharacter = commonEmojiMapping[emojiId]; - if (emojiCharacter) { - console.log('Sending reaction:', emojiCharacter); - await this.props.onSelectReaction(emojiCharacter); - console.log('Reaction sent successfully'); - this.setState( - { - isReactionTrayOpen: false, - isEmojiPickerOpen: false, - }, - () => { - this.props.onOpenChange?.(false); - } - ); - } - } catch (error) { - console.error('Error processing reaction:', error); - } finally { - console.log('Finishing reaction processing'); - this.setState({ isProcessing: false }); - } - }); - }; - - toggleReactionTray = () => { - this.setState((prevState) => { - const isReactionTrayOpen = !prevState.isReactionTrayOpen; - this.props.onOpenChange?.(isReactionTrayOpen); - return { isReactionTrayOpen, isEmojiPickerOpen: false }; - }); - }; - toggleEmojiPicker = () => { this.setState((prevState) => ({ isEmojiPickerOpen: !prevState.isEmojiPickerOpen, - isReactionTrayOpen: false, })); }; - renderCommonReactions() { - const commonReactions = [ - 'thumbsup', - 'heart', - 'joy', - 'cry', - 'astonished', - ]; - - return commonReactions.map((emojiId) => ( - { - e.stopPropagation(); // Stop event from reaching the underlay - this.onSelect(emojiId); - }} - > - - - )); - } - - renderReactionTray() { - if (!this.triggerRef.current) { - return null; - } - - const triggerRect = this.triggerRef.current.getBoundingClientRect(); - const viewportHeight = window.innerHeight; - const trayHeight = 56; - const trayWidth = 256; - - const shouldRenderAbove = triggerRect.bottom + trayHeight > viewportHeight; - - const trayStyles = { - top: shouldRenderAbove - ? `${triggerRect.top + window.scrollY - trayHeight - 8}px` - : `${triggerRect.bottom + window.scrollY + 8}px`, - left: `${triggerRect.left + window.scrollX + triggerRect.width / 2 - trayWidth / 2}px`, - transformOrigin: shouldRenderAbove ? 'bottom center' : 'top center', - transform: 'translateY(0)', - }; - - return createPortal( - <> -
- -
- {this.renderCommonReactions()} - -
- { - e.stopPropagation(); - this.toggleEmojiPicker(); - }} - /> -
-
- , - document.body - ); - } - renderEmojiPicker() { return createPortal( -
+
{ }; render() { - const { isReactionTrayOpen, isEmojiPickerOpen } = this.state; + const { isEmojiPickerOpen } = this.state; return (
- +
- {isReactionTrayOpen && this.renderReactionTray()} {isEmojiPickerOpen && this.renderEmojiPicker()}
); diff --git a/src/components/reaction-menu/styles.scss b/src/components/reaction-menu/styles.scss index 8d9120f79..c3a500233 100644 --- a/src/components/reaction-menu/styles.scss +++ b/src/components/reaction-menu/styles.scss @@ -1,53 +1,6 @@ @use '~@zero-tech/zui/styles/theme' as theme; @import '../../glass'; -.reaction-tray { - @include flat-thick; - @include glass-shadow-and-blur; - - display: flex; - flex-direction: row; - align-items: center; - padding: 4px; - border-radius: 8px; - min-width: 128px; - max-width: 256px; - position: fixed; - z-index: 1002; -} - -.reaction-tray-item { - @include glass-text-primary-color; - - display: flex; - align-items: center; - outline: none; - border-radius: 8px; - user-select: none; - cursor: pointer; - padding: 8px; - - &:hover { - @include glass-state-hover-color; - } - - &:active { - background: rgba(163, 162, 163, 0.1); - } -} - -.reaction-menu__underlay { - z-index: 1000; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - display: block; - pointer-events: auto; - background: transparent; -} - .reaction-menu-trigger { z-index: 1003; outline: none; @@ -55,12 +8,13 @@ .emoji-picker { position: absolute; - right: 65px; bottom: 75px; + left: 390px; z-index: 1010; color: var(--color-greyscale-11); } -.emoji-picker-trigger-icon { - background: theme.$color-greyscale-transparency-3; +.emoji-picker--owner { + right: 65px; + left: auto; }