From c4785ef96e13d02b217dce4e777269c0e895507d Mon Sep 17 00:00:00 2001
From: Samuel Newman <mozzius@protonmail.com>
Date: Fri, 21 Mar 2025 18:29:14 +0200
Subject: New `ContextMenu` menu type for DM messages (#8014)

* get context menu somewhat working ish

* take screenshot rather than double rendering

* get animations somewhat working

* get transform animation working

* rm log

* upwards safe area

* get working on android

* get android working once and for all

* fix positioning on both platforms

* use dark blur on ios always, fix dark mode

* allow closing with hardware back press

* try and fix type error

* add note about ts-ignore

* round post

* add image capture error handling

* extract magic numbers

* set explicit embed width, rm top margin

* Message embed width tweaks

* Format

* fix position of embeds

* same as above for web

---------

Co-authored-by: Eric Bailey <git@esb.lol>
---
 src/components/dms/ActionsWrapper.tsx | 125 +++++++++++++---------------------
 1 file changed, 47 insertions(+), 78 deletions(-)

(limited to 'src/components/dms/ActionsWrapper.tsx')

diff --git a/src/components/dms/ActionsWrapper.tsx b/src/components/dms/ActionsWrapper.tsx
index a087fed3f..385086d7c 100644
--- a/src/components/dms/ActionsWrapper.tsx
+++ b/src/components/dms/ActionsWrapper.tsx
@@ -1,22 +1,10 @@
-import React from 'react'
-import {Keyboard} from 'react-native'
-import {Gesture, GestureDetector} from 'react-native-gesture-handler'
-import Animated, {
-  cancelAnimation,
-  runOnJS,
-  useAnimatedStyle,
-  useSharedValue,
-  withTiming,
-} from 'react-native-reanimated'
+import {View} from 'react-native'
 import {ChatBskyConvoDefs} from '@atproto/api'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
-import {HITSLOP_10} from '#/lib/constants'
-import {useHaptics} from '#/lib/haptics'
 import {atoms as a} from '#/alf'
-import {MessageMenu} from '#/components/dms/MessageMenu'
-import {useMenuControl} from '#/components/Menu'
+import {MessageContextMenu} from '#/components/dms/MessageContextMenu'
 
 export function ActionsWrapper({
   message,
@@ -28,71 +16,52 @@ export function ActionsWrapper({
   children: React.ReactNode
 }) {
   const {_} = useLingui()
-  const playHaptic = useHaptics()
-  const menuControl = useMenuControl()
-
-  const scale = useSharedValue(1)
-
-  const animatedStyle = useAnimatedStyle(() => ({
-    transform: [{scale: scale.get()}],
-  }))
-
-  const open = React.useCallback(() => {
-    playHaptic()
-    Keyboard.dismiss()
-    menuControl.open()
-  }, [menuControl, playHaptic])
-
-  const shrink = React.useCallback(() => {
-    'worklet'
-    cancelAnimation(scale)
-    scale.set(() => withTiming(1, {duration: 200}))
-  }, [scale])
-
-  const doubleTapGesture = Gesture.Tap()
-    .numberOfTaps(2)
-    .hitSlop(HITSLOP_10)
-    .onEnd(open)
-    .runOnJS(true)
-
-  const pressAndHoldGesture = Gesture.LongPress()
-    .onStart(() => {
-      'worklet'
-      scale.set(() =>
-        withTiming(1.05, {duration: 200}, finished => {
-          if (!finished) return
-          runOnJS(open)()
-          shrink()
-        }),
-      )
-    })
-    .onTouchesUp(shrink)
-    .onTouchesMove(shrink)
-    .cancelsTouchesInView(false)
-
-  const composedGestures = Gesture.Exclusive(
-    doubleTapGesture,
-    pressAndHoldGesture,
-  )
 
   return (
-    <GestureDetector gesture={composedGestures}>
-      <Animated.View
-        style={[
-          {
-            maxWidth: '80%',
-          },
-          isFromSelf ? a.self_end : a.self_start,
-          animatedStyle,
-        ]}
-        accessible={true}
-        accessibilityActions={[
-          {name: 'activate', label: _(msg`Open message options`)},
-        ]}
-        onAccessibilityAction={open}>
-        {children}
-        <MessageMenu message={message} control={menuControl} />
-      </Animated.View>
-    </GestureDetector>
+    <MessageContextMenu message={message}>
+      {trigger =>
+        // will always be true, since this file is platform split
+        trigger.isNative && (
+          <View style={[a.flex_1, a.relative]}>
+            {/* {isNative && (
+              <View
+                style={[
+                  a.rounded_full,
+                  a.absolute,
+                  {bottom: '100%'},
+                  isFromSelf ? a.right_0 : a.left_0,
+                  t.atoms.bg,
+                  a.flex_row,
+                  a.shadow_lg,
+                  a.py_xs,
+                  a.px_md,
+                  a.gap_md,
+                  a.mb_xs,
+                ]}>
+                {['👍', '😆', '❤️', '👀', '😢'].map(emoji => (
+                  <Text key={emoji} style={[a.text_center, {fontSize: 32}]}>
+                    {emoji}
+                  </Text>
+                ))}
+              </View>
+            )} */}
+            <View
+              style={[
+                {maxWidth: '80%'},
+                isFromSelf
+                  ? [a.self_end, a.align_end]
+                  : [a.self_start, a.align_start],
+              ]}
+              accessible={true}
+              accessibilityActions={[
+                {name: 'activate', label: _(msg`Open message options`)},
+              ]}
+              onAccessibilityAction={trigger.control.open}>
+              {children}
+            </View>
+          </View>
+        )
+      }
+    </MessageContextMenu>
   )
 }
-- 
cgit 1.4.1

