diff --git a/src/components/dms/ActionsWrapper.tsx b/src/components/dms/ActionsWrapper.tsx
index 7c957578c4..eb57da4f78 100644
--- a/src/components/dms/ActionsWrapper.tsx
+++ b/src/components/dms/ActionsWrapper.tsx
@@ -7,22 +7,26 @@ import Animated, {
useSharedValue,
withTiming,
} from 'react-native-reanimated'
+import {ChatBskyConvoDefs} from '@atproto-labs/api'
import {useHaptics} from 'lib/haptics'
import {atoms as a} from '#/alf'
+import {MessageMenu} from '#/components/dms/MessageMenu'
+import {useMenuControl} from '#/components/Menu'
const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
export const ActionsWrapper = function GrowWrapper({
+ message,
isFromSelf,
- onOpenMenu,
children,
}: {
+ message: ChatBskyConvoDefs.MessageView
isFromSelf: boolean
- onOpenMenu: () => unknown
children: React.ReactNode
}) {
const playHaptic = useHaptics()
+ const menuControl = useMenuControl()
const scale = useSharedValue(1)
const animationDidComplete = useSharedValue(false)
@@ -45,11 +49,11 @@ export const ActionsWrapper = function GrowWrapper({
if (!finished) return
animationDidComplete.value = true
runOnJS(playHaptic)()
- runOnJS(onOpenMenu)()
+ runOnJS(menuControl.open)()
shrink()
})
- }, [scale, animationDidComplete, playHaptic, onOpenMenu, shrink])
+ }, [scale, animationDidComplete, playHaptic, shrink, menuControl])
return (
{children}
+
)
}
diff --git a/src/components/dms/ActionsWrapper.web.tsx b/src/components/dms/ActionsWrapper.web.tsx
index a6c09548c9..90e4643659 100644
--- a/src/components/dms/ActionsWrapper.web.tsx
+++ b/src/components/dms/ActionsWrapper.web.tsx
@@ -1,14 +1,75 @@
import React from 'react'
import {View} from 'react-native'
+import {ChatBskyConvoDefs} from '@atproto-labs/api'
+
+import {atoms as a} from '#/alf'
+import {MessageMenu} from '#/components/dms/MessageMenu'
+import {useMenuControl} from '#/components/Menu'
+import {Text} from '#/components/Typography'
export function ActionsWrapper({
+ message,
isFromSelf,
- onOpenMenu,
children,
}: {
+ message: ChatBskyConvoDefs.MessageView
isFromSelf: boolean
- onOpenMenu: () => unknown
children: React.ReactNode
}) {
- return {children}
+ const [showActions, setShowActions] = React.useState(false)
+
+ const menuControl = useMenuControl()
+
+ const onMouseEnter = React.useCallback(() => {
+ setShowActions(true)
+ }, [])
+
+ const onMouseLeave = React.useCallback(() => {
+ setShowActions(false)
+ }, [])
+
+ return (
+
+ {isFromSelf && (
+
+
+
+ )}
+
+ {children}
+
+ {!isFromSelf && (
+ {showActions && Hello}
+ )}
+
+ )
+}
+
+function ActionBar({
+ control,
+ message,
+}: {
+ control: Menu.MenuControlProps
+ message: ChatBskyConvoDefs.MessageView
+}) {
+ return (
+
+
+
+ )
}
diff --git a/src/components/dms/MessageItem.tsx b/src/components/dms/MessageItem.tsx
index 24e6e7c834..46357ab596 100644
--- a/src/components/dms/MessageItem.tsx
+++ b/src/components/dms/MessageItem.tsx
@@ -6,8 +6,6 @@ import {useSession} from 'state/session'
import {atoms as a, useTheme} from '#/alf'
import {ActionsWrapper} from '#/components/dms/ActionsWrapper'
import {MessageItemMetadata} from '#/components/dms/MesageItemMetadata'
-import {MessageMenu} from '#/components/dms/MessageMenu'
-import {useMenuControl} from '#/components/Menu'
import {Text} from '#/components/Typography'
export function MessageItem({
@@ -23,8 +21,6 @@ export function MessageItem({
const t = useTheme()
const {currentAccount} = useSession()
- const menuControl = useMenuControl()
-
const isFromSelf = item.sender?.did === currentAccount?.did
const isNextFromSelf =
@@ -51,12 +47,8 @@ export function MessageItem({
return true
}, [item, next, isFromSelf, isNextFromSelf])
- const onOpenMenu = React.useCallback(() => {
- menuControl.open()
- }, [menuControl])
-
return (
-
+
-
)
}
diff --git a/src/components/dms/MessageMenu.tsx b/src/components/dms/MessageMenu.tsx
index 8f1644695b..7b158a536f 100644
--- a/src/components/dms/MessageMenu.tsx
+++ b/src/components/dms/MessageMenu.tsx
@@ -1,9 +1,12 @@
import React from 'react'
+import {Pressable} from 'react-native'
import {ChatBskyConvoDefs} from '@atproto-labs/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useSession} from 'state/session'
+import {atoms as a, useTheme} from '#/alf'
+import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
import * as Menu from '#/components/Menu'
@@ -13,11 +16,14 @@ import {usePromptControl} from '#/components/Prompt'
export let MessageMenu = ({
message,
control,
+ hideTrigger,
}: {
+ hideTrigger?: boolean
message: ChatBskyConvoDefs.MessageView
control: Menu.MenuControlProps
}): React.ReactNode => {
const {_} = useLingui()
+ const t = useTheme()
const {currentAccount} = useSession()
const deleteControl = usePromptControl()
@@ -34,6 +40,24 @@ export let MessageMenu = ({
return (
<>
+ {!hideTrigger && (
+
+ {({props, state}) => (
+
+
+
+ )}
+
+ )}
+