about summary refs log tree commit diff
path: root/src/components/dms/EmojiReactionPicker.web.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/dms/EmojiReactionPicker.web.tsx')
-rw-r--r--src/components/dms/EmojiReactionPicker.web.tsx72
1 files changed, 50 insertions, 22 deletions
diff --git a/src/components/dms/EmojiReactionPicker.web.tsx b/src/components/dms/EmojiReactionPicker.web.tsx
index bd51b4fd2..0425a879a 100644
--- a/src/components/dms/EmojiReactionPicker.web.tsx
+++ b/src/components/dms/EmojiReactionPicker.web.tsx
@@ -1,24 +1,29 @@
 import {useState} from 'react'
 import {View} from 'react-native'
-import {ChatBskyConvoDefs} from '@atproto/api'
+import {type ChatBskyConvoDefs} from '@atproto/api'
 import EmojiPicker from '@emoji-mart/react'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
-import {Emoji} from '#/view/com/composer/text-input/web/EmojiPicker.web'
+import {useSession} from '#/state/session'
+import {type Emoji} from '#/view/com/composer/text-input/web/EmojiPicker.web'
 import {PressableWithHover} from '#/view/com/util/PressableWithHover'
 import {atoms as a} from '#/alf'
 import {useTheme} from '#/alf'
 import {DotGrid_Stroke2_Corner0_Rounded as DotGridIcon} from '#/components/icons/DotGrid'
 import * as Menu from '#/components/Menu'
-import {TriggerProps} from '#/components/Menu/types'
+import {type TriggerProps} from '#/components/Menu/types'
 import {Text} from '#/components/Typography'
+import {hasAlreadyReacted, hasReachedReactionLimit} from './util'
 
 export function EmojiReactionPicker({
+  message,
   children,
+  onEmojiSelect,
 }: {
   message: ChatBskyConvoDefs.MessageView
   children?: TriggerProps['children']
+  onEmojiSelect: (emoji: string) => void
 }) {
   if (!children)
     throw new Error('EmojiReactionPicker requires the children prop on web')
@@ -29,15 +34,22 @@ export function EmojiReactionPicker({
     <Menu.Root>
       <Menu.Trigger label={_(msg`Add emoji reaction`)}>{children}</Menu.Trigger>
       <Menu.Outer>
-        <MenuInner />
+        <MenuInner message={message} onEmojiSelect={onEmojiSelect} />
       </Menu.Outer>
     </Menu.Root>
   )
 }
 
-function MenuInner() {
+function MenuInner({
+  message,
+  onEmojiSelect,
+}: {
+  message: ChatBskyConvoDefs.MessageView
+  onEmojiSelect: (emoji: string) => void
+}) {
   const t = useTheme()
   const {control} = Menu.useMenuContext()
+  const {currentAccount} = useSession()
 
   const [expanded, setExpanded] = useState(false)
 
@@ -47,29 +59,45 @@ function MenuInner() {
 
   const handleEmojiSelect = (emoji: string) => {
     control.close()
-    window.alert(emoji)
+    onEmojiSelect(emoji)
   }
 
+  const limitReacted = hasReachedReactionLimit(message, currentAccount?.did)
+
   return expanded ? (
     <EmojiPicker onEmojiSelect={handleEmojiPickerResponse} autoFocus={true} />
   ) : (
     <View style={[a.flex_row, a.gap_xs]}>
-      {['👍', '😆', '❤️', '👀', '😢'].map(emoji => (
-        <PressableWithHover
-          key={emoji}
-          onPress={() => handleEmojiSelect(emoji)}
-          hoverStyle={{backgroundColor: t.palette.primary_100}}
-          style={[
-            a.rounded_xs,
-            {height: 40, width: 40},
-            a.justify_center,
-            a.align_center,
-          ]}>
-          <Text style={[a.text_center, {fontSize: 30}]} emoji>
-            {emoji}
-          </Text>
-        </PressableWithHover>
-      ))}
+      {['👍', '😆', '❤️', '👀', '😢'].map(emoji => {
+        const alreadyReacted = hasAlreadyReacted(
+          message,
+          currentAccount?.did,
+          emoji,
+        )
+        return (
+          <PressableWithHover
+            key={emoji}
+            onPress={() => handleEmojiSelect(emoji)}
+            hoverStyle={{
+              backgroundColor: alreadyReacted
+                ? t.palette.negative_200
+                : !limitReacted
+                ? t.palette.primary_300
+                : undefined,
+            }}
+            style={[
+              a.rounded_xs,
+              {height: 40, width: 40},
+              a.justify_center,
+              a.align_center,
+              alreadyReacted && {backgroundColor: t.palette.primary_100},
+            ]}>
+            <Text style={[a.text_center, {fontSize: 30}]} emoji>
+              {emoji}
+            </Text>
+          </PressableWithHover>
+        )
+      })}
       <PressableWithHover
         onPress={() => setExpanded(true)}
         hoverStyle={{backgroundColor: t.palette.primary_100}}