about summary refs log tree commit diff
path: root/src/components/dms/ActionsWrapper.web.tsx
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-05-02 13:54:17 -0700
committerGitHub <noreply@github.com>2024-05-02 13:54:17 -0700
commit8ba1b10ce0d278a88e37d6b6c277a41673392877 (patch)
tree1e44ec05c427aaa124077b6fb9ce01c831daa8b3 /src/components/dms/ActionsWrapper.web.tsx
parent6da18e3dcffaf72a03bde8a205a596b4b3366b86 (diff)
downloadvoidsky-8ba1b10ce0d278a88e37d6b6c277a41673392877.tar.zst
[Clipclops] Message actions for native and web (#3807)
* haptic on long press

* add animation to press and hold

* eslint disable for now

* adjust styles

* dont trigger if animation is cancelled

* organize

* add a delete menu

* reset scale automatically

* message actions dialog

cleanup

center the trigger

handle focus/unfocus better

make triggers accessible

weg dropdown menu

add a wep specific wrapper

decrease press delay

add report button

improve shrink logic

use `self_end` instead of `margin: auto`

rm extra `?`

move `MessageItem` to `components`

add delete button

* rm some padding

* update after merge

* fix merge

* web only types

* fix crash

* add an explanation

* fix web types

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Diffstat (limited to 'src/components/dms/ActionsWrapper.web.tsx')
-rw-r--r--src/components/dms/ActionsWrapper.web.tsx86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/components/dms/ActionsWrapper.web.tsx b/src/components/dms/ActionsWrapper.web.tsx
new file mode 100644
index 000000000..f4c85ab94
--- /dev/null
+++ b/src/components/dms/ActionsWrapper.web.tsx
@@ -0,0 +1,86 @@
+import React from 'react'
+import {StyleSheet, 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'
+
+export function ActionsWrapper({
+  message,
+  isFromSelf,
+  children,
+}: {
+  message: ChatBskyConvoDefs.MessageView
+  isFromSelf: boolean
+  children: React.ReactNode
+}) {
+  const menuControl = useMenuControl()
+  const viewRef = React.useRef(null)
+
+  const [showActions, setShowActions] = React.useState(false)
+
+  const onMouseEnter = React.useCallback(() => {
+    setShowActions(true)
+  }, [])
+
+  const onMouseLeave = React.useCallback(() => {
+    setShowActions(false)
+  }, [])
+
+  // We need to handle the `onFocus` separately because we want to know if there is a related target (the element
+  // that is losing focus). If there isn't that means the focus is coming from a dropdown that is now closed.
+  const onFocus = React.useCallback<React.FocusEventHandler>(e => {
+    if (e.nativeEvent.relatedTarget == null) return
+    setShowActions(true)
+  }, [])
+
+  return (
+    <View
+      // @ts-expect-error web only
+      onMouseEnter={onMouseEnter}
+      onMouseLeave={onMouseLeave}
+      onFocus={onFocus}
+      onBlur={onMouseLeave}
+      style={StyleSheet.flatten([a.flex_1, a.flex_row])}
+      ref={viewRef}>
+      {isFromSelf && (
+        <View
+          style={[
+            a.mr_xl,
+            a.justify_center,
+            {
+              marginLeft: 'auto',
+            },
+          ]}>
+          <MessageMenu
+            message={message}
+            control={menuControl}
+            triggerOpacity={showActions || menuControl.isOpen ? 1 : 0}
+            onTriggerPress={onMouseEnter}
+            // @ts-expect-error web only
+            onMouseLeave={onMouseLeave}
+          />
+        </View>
+      )}
+      <View
+        style={{
+          maxWidth: '65%',
+        }}>
+        {children}
+      </View>
+      {!isFromSelf && (
+        <View style={[a.flex_row, a.align_center, a.ml_xl]}>
+          <MessageMenu
+            message={message}
+            control={menuControl}
+            triggerOpacity={showActions || menuControl.isOpen ? 1 : 0}
+            onTriggerPress={onMouseEnter}
+            // @ts-expect-error web only
+            onMouseLeave={onMouseLeave}
+          />
+        </View>
+      )}
+    </View>
+  )
+}