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>
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user