about summary refs log tree commit diff
path: root/src/components/PostControls/PostControlButton.tsx
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2025-05-24 02:02:38 +0300
committerGitHub <noreply@github.com>2025-05-23 18:02:38 -0500
commitc3f88e0a48bdf22831736ad3d44222e7c4418486 (patch)
treed72137786908d5c61ad52a7cb7aa8fd37472a615 /src/components/PostControls/PostControlButton.tsx
parent5aadb9e41b1305e673947b28ba0566bdc3a3325d (diff)
downloadvoidsky-c3f88e0a48bdf22831736ad3d44222e7c4418486.tar.zst
Share menu (#7840)
* move post ctrls to #/components

* restructure post controls, basic share menu

* add border radius to searchable people list for android

* Revert "add border radius to searchable people list for android"

This reverts commit 417449086e25b82f5683b12f6405d972f48ce50e.

* add copy link to native share menu

* reorg files again

* open native share menu on long press

* Translation comments

Thanks @surfdude29

* abs path

* update type imports, remove forwardRef

* rm react import

* equal spacing of buttons, extract disco debug

* add better icon

* add right offset to share button for visual alignment

* Add recent chats to share menu (#7853)

* add recent chats to share menu

* Update RecentChats.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update RecentChats.tsx

* add fading edge on andriod

* tweak scrollview

* Add metrics and A/B alt icon to share menu (#8401)

* add metrics

* add a/b tested alt icon

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* More descriptive share text/icon on web (#7854)

* more descriptive share text on web

* revert dev mode changes

* add missing import

* use modified share icon everywhere

* Add back conflicting changes

---------

Co-authored-by: Eric Bailey <git@esb.lol>

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/components/PostControls/PostControlButton.tsx')
-rw-r--r--src/components/PostControls/PostControlButton.tsx126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/components/PostControls/PostControlButton.tsx b/src/components/PostControls/PostControlButton.tsx
new file mode 100644
index 000000000..1585d429d
--- /dev/null
+++ b/src/components/PostControls/PostControlButton.tsx
@@ -0,0 +1,126 @@
+import {createContext, useContext, useMemo} from 'react'
+import {type GestureResponderEvent, type View} from 'react-native'
+
+import {POST_CTRL_HITSLOP} from '#/lib/constants'
+import {useHaptics} from '#/lib/haptics'
+import {atoms as a, useTheme} from '#/alf'
+import {Button, type ButtonProps} from '#/components/Button'
+import {type Props as SVGIconProps} from '#/components/icons/common'
+import {Text, type TextProps} from '#/components/Typography'
+
+const PostControlContext = createContext<{
+  big?: boolean
+  active?: boolean
+  color?: {color: string}
+}>({})
+
+// Base button style, which the the other ones extend
+export function PostControlButton({
+  ref,
+  onPress,
+  onLongPress,
+  children,
+  big,
+  active,
+  activeColor,
+  ...props
+}: ButtonProps & {
+  ref?: React.Ref<View>
+  active?: boolean
+  big?: boolean
+  color?: string
+  activeColor?: string
+}) {
+  const t = useTheme()
+  const playHaptic = useHaptics()
+
+  const ctx = useMemo(
+    () => ({
+      big,
+      active,
+      color: {
+        color: activeColor && active ? activeColor : t.palette.contrast_500,
+      },
+    }),
+    [big, active, activeColor, t.palette.contrast_500],
+  )
+
+  const style = useMemo(
+    () => [
+      a.flex_row,
+      a.align_center,
+      a.gap_xs,
+      a.bg_transparent,
+      {padding: 5},
+    ],
+    [],
+  )
+
+  const handlePress = useMemo(() => {
+    if (!onPress) return
+    return (evt: GestureResponderEvent) => {
+      playHaptic('Light')
+      onPress(evt)
+    }
+  }, [onPress, playHaptic])
+
+  const handleLongPress = useMemo(() => {
+    if (!onLongPress) return
+    return (evt: GestureResponderEvent) => {
+      playHaptic('Heavy')
+      onLongPress(evt)
+    }
+  }, [onLongPress, playHaptic])
+
+  return (
+    <Button
+      ref={ref}
+      onPress={handlePress}
+      onLongPress={handleLongPress}
+      style={style}
+      hoverStyle={t.atoms.bg_contrast_25}
+      shape="round"
+      variant="ghost"
+      color="secondary"
+      hitSlop={POST_CTRL_HITSLOP}
+      {...props}>
+      {typeof children === 'function' ? (
+        args => (
+          <PostControlContext.Provider value={ctx}>
+            {children(args)}
+          </PostControlContext.Provider>
+        )
+      ) : (
+        <PostControlContext.Provider value={ctx}>
+          {children}
+        </PostControlContext.Provider>
+      )}
+    </Button>
+  )
+}
+
+export function PostControlButtonIcon({
+  icon: Comp,
+}: {
+  icon: React.ComponentType<SVGIconProps>
+}) {
+  const {big, color} = useContext(PostControlContext)
+
+  return <Comp style={[color, a.pointer_events_none]} width={big ? 22 : 18} />
+}
+
+export function PostControlButtonText({style, ...props}: TextProps) {
+  const {big, active, color} = useContext(PostControlContext)
+
+  return (
+    <Text
+      style={[
+        color,
+        big ? a.text_md : {fontSize: 15},
+        active && a.font_bold,
+        style,
+      ]}
+      {...props}
+    />
+  )
+}