about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx2
-rw-r--r--src/view/com/post/Post.tsx2
-rw-r--r--src/view/com/posts/FeedItem.tsx2
-rw-r--r--src/view/com/util/post-ctrls/PostCtrls.tsx (renamed from src/view/com/util/PostCtrls.tsx)90
-rw-r--r--src/view/com/util/post-ctrls/RepostButton.tsx95
-rw-r--r--src/view/com/util/post-ctrls/RepostButton.web.tsx86
6 files changed, 210 insertions, 67 deletions
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index 563a3ead6..084e30a25 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -21,7 +21,7 @@ import {pluralize} from 'lib/strings/helpers'
 import {useStores} from 'state/index'
 import {PostMeta} from '../util/PostMeta'
 import {PostEmbeds} from '../util/post-embeds'
-import {PostCtrls} from '../util/PostCtrls'
+import {PostCtrls} from '../util/post-ctrls/PostCtrls'
 import {PostHider} from '../util/moderation/PostHider'
 import {ContentHider} from '../util/moderation/ContentHider'
 import {ImageHider} from '../util/moderation/ImageHider'
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index 0b49995fe..614c5ea77 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -20,7 +20,7 @@ import {Link} from '../util/Link'
 import {UserInfoText} from '../util/UserInfoText'
 import {PostMeta} from '../util/PostMeta'
 import {PostEmbeds} from '../util/post-embeds'
-import {PostCtrls} from '../util/PostCtrls'
+import {PostCtrls} from '../util/post-ctrls/PostCtrls'
 import {PostHider} from '../util/moderation/PostHider'
 import {ContentHider} from '../util/moderation/ContentHider'
 import {ImageHider} from '../util/moderation/ImageHider'
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index 1084fb6fc..fa6131d61 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -13,7 +13,7 @@ import {Link, DesktopWebTextLink} from '../util/Link'
 import {Text} from '../util/text/Text'
 import {UserInfoText} from '../util/UserInfoText'
 import {PostMeta} from '../util/PostMeta'
-import {PostCtrls} from '../util/PostCtrls'
+import {PostCtrls} from '../util/post-ctrls/PostCtrls'
 import {PostEmbeds} from '../util/post-embeds'
 import {PostHider} from '../util/moderation/PostHider'
 import {ContentHider} from '../util/moderation/ContentHider'
diff --git a/src/view/com/util/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx
index 11b73cea0..5c0296e28 100644
--- a/src/view/com/util/PostCtrls.tsx
+++ b/src/view/com/util/post-ctrls/PostCtrls.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, {useCallback} from 'react'
 import {
   StyleProp,
   StyleSheet,
@@ -18,18 +18,14 @@ import ReactNativeHapticFeedback, {
 //   TriggerableAnimated,
 //   TriggerableAnimatedRef,
 // } from './anim/TriggerableAnimated'
-import {Text} from './text/Text'
-import {PostDropdownBtn} from './forms/DropdownButton'
-import {
-  HeartIcon,
-  HeartIconSolid,
-  RepostIcon,
-  CommentBottomArrow,
-} from 'lib/icons'
+import {Text} from '../text/Text'
+import {PostDropdownBtn} from '../forms/DropdownButton'
+import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons'
 import {s, colors} from 'lib/styles'
 import {useTheme} from 'lib/ThemeContext'
 import {useStores} from 'state/index'
-import {isIOS} from 'platform/detection'
+import {isIOS, isNative} from 'platform/detection'
+import {RepostButton} from './RepostButton'
 
 interface PostCtrlsOpts {
   itemUri: string
@@ -112,10 +108,12 @@ export function PostCtrls(opts: PostCtrlsOpts) {
   // DISABLED see #135
   // const repostRef = React.useRef<TriggerableAnimatedRef | null>(null)
   // const likeRef = React.useRef<TriggerableAnimatedRef | null>(null)
-  const onRepost = () => {
+  const onRepost = useCallback(() => {
     store.shell.closeModal()
     if (!opts.isReposted) {
-      ReactNativeHapticFeedback.trigger(hapticImpact)
+      if (isNative) {
+        ReactNativeHapticFeedback.trigger(hapticImpact)
+      }
       opts.onPressToggleRepost().catch(_e => undefined)
       // DISABLED see #135
       // repostRef.current?.trigger(
@@ -128,9 +126,9 @@ export function PostCtrls(opts: PostCtrlsOpts) {
     } else {
       opts.onPressToggleRepost().catch(_e => undefined)
     }
-  }
+  }, [opts, store.shell])
 
-  const onQuote = () => {
+  const onQuote = useCallback(() => {
     store.shell.closeModal()
     store.shell.openComposer({
       quote: {
@@ -141,17 +139,18 @@ export function PostCtrls(opts: PostCtrlsOpts) {
         indexedAt: opts.indexedAt,
       },
     })
-    ReactNativeHapticFeedback.trigger(hapticImpact)
-  }
 
-  const onPressToggleRepostWrapper = () => {
-    store.shell.openModal({
-      name: 'repost',
-      onRepost: onRepost,
-      onQuote: onQuote,
-      isReposted: opts.isReposted,
-    })
-  }
+    if (isNative) {
+      ReactNativeHapticFeedback.trigger(hapticImpact)
+    }
+  }, [
+    opts.author,
+    opts.indexedAt,
+    opts.itemCid,
+    opts.itemUri,
+    opts.text,
+    store.shell,
+  ])
 
   const onPressToggleLikeWrapper = async () => {
     if (!opts.isLiked) {
@@ -181,7 +180,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
         onPress={opts.onPressReply}
         accessibilityRole="button"
         accessibilityLabel="Reply"
-        accessibilityHint="Opens reply composer">
+        accessibilityHint="reply composer">
         <CommentBottomArrow
           style={[defaultCtrlColor, opts.big ? s.mt2 : styles.mt1]}
           strokeWidth={3}
@@ -193,39 +192,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
           </Text>
         ) : undefined}
       </TouchableOpacity>
-      <TouchableOpacity
-        testID="repostBtn"
-        hitSlop={HITSLOP}
-        onPress={onPressToggleRepostWrapper}
-        style={styles.ctrl}
-        accessibilityRole="button"
-        accessibilityLabel={opts.isReposted ? 'Undo repost' : 'Repost'}
-        accessibilityHint={
-          opts.isReposted
-            ? `Remove your repost of ${opts.author}'s post`
-            : `Repost or quote post ${opts.author}'s post`
-        }>
-        <RepostIcon
-          style={
-            opts.isReposted
-              ? (styles.ctrlIconReposted as StyleProp<ViewStyle>)
-              : defaultCtrlColor
-          }
-          strokeWidth={2.4}
-          size={opts.big ? 24 : 20}
-        />
-        {typeof opts.repostCount !== 'undefined' ? (
-          <Text
-            testID="repostCount"
-            style={
-              opts.isReposted
-                ? [s.bold, s.green3, s.f15, s.ml5]
-                : [defaultCtrlColor, s.f15, s.ml5]
-            }>
-            {opts.repostCount}
-          </Text>
-        ) : undefined}
-      </TouchableOpacity>
+      <RepostButton {...opts} onRepost={onRepost} onQuote={onQuote} />
       <TouchableOpacity
         testID="likeBtn"
         style={styles.ctrl}
@@ -234,9 +201,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
         accessibilityRole="button"
         accessibilityLabel={opts.isLiked ? 'Unlike' : 'Like'}
         accessibilityHint={
-          opts.isReposted
-            ? `Removes like from ${opts.author}'s post`
-            : `Like ${opts.author}'s post`
+          opts.isReposted ? `Removes like from the post` : `Like the post`
         }>
         {opts.isLiked ? (
           <HeartIconSolid
@@ -309,9 +274,6 @@ const styles = StyleSheet.create({
     padding: 5,
     margin: -5,
   },
-  ctrlIconReposted: {
-    color: colors.green3,
-  },
   ctrlIconLiked: {
     color: colors.red3,
   },
diff --git a/src/view/com/util/post-ctrls/RepostButton.tsx b/src/view/com/util/post-ctrls/RepostButton.tsx
new file mode 100644
index 000000000..e6de4cb19
--- /dev/null
+++ b/src/view/com/util/post-ctrls/RepostButton.tsx
@@ -0,0 +1,95 @@
+import React, {useCallback} from 'react'
+import {StyleProp, StyleSheet, TouchableOpacity, ViewStyle} from 'react-native'
+import {RepostIcon} from 'lib/icons'
+import {s, colors} from 'lib/styles'
+import {useTheme} from 'lib/ThemeContext'
+import {Text} from '../text/Text'
+import {useStores} from 'state/index'
+
+const HITSLOP = {top: 5, left: 5, bottom: 5, right: 5}
+
+interface Props {
+  isReposted: boolean
+  repostCount?: number
+  big?: boolean
+  onRepost: () => void
+  onQuote: () => void
+}
+
+export const RepostButton = ({
+  isReposted,
+  repostCount,
+  big,
+  onRepost,
+  onQuote,
+}: Props) => {
+  const store = useStores()
+  const theme = useTheme()
+
+  const defaultControlColor = React.useMemo(
+    () => ({
+      color: theme.palette.default.postCtrl,
+    }),
+    [theme],
+  )
+
+  const onPressToggleRepostWrapper = useCallback(() => {
+    store.shell.openModal({
+      name: 'repost',
+      onRepost: onRepost,
+      onQuote: onQuote,
+      isReposted,
+    })
+  }, [onRepost, onQuote, isReposted, store.shell])
+
+  return (
+    <TouchableOpacity
+      testID="repostBtn"
+      hitSlop={HITSLOP}
+      onPress={onPressToggleRepostWrapper}
+      style={styles.control}
+      accessibilityRole="button"
+      accessibilityLabel={isReposted ? 'Undo repost' : 'Repost'}
+      accessibilityHint={
+        isReposted
+          ? `Remove your repost of the post`
+          : `Repost or quote post the post`
+      }>
+      <RepostIcon
+        style={
+          isReposted
+            ? (styles.reposted as StyleProp<ViewStyle>)
+            : defaultControlColor
+        }
+        strokeWidth={2.4}
+        size={big ? 24 : 20}
+      />
+      {typeof repostCount !== 'undefined' ? (
+        <Text
+          testID="repostCount"
+          style={
+            isReposted
+              ? [s.bold, s.green3, s.f15, s.ml5]
+              : [defaultControlColor, s.f15, s.ml5]
+          }>
+          {repostCount}
+        </Text>
+      ) : undefined}
+    </TouchableOpacity>
+  )
+}
+
+const styles = StyleSheet.create({
+  control: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    padding: 5,
+    margin: -5,
+  },
+  reposted: {
+    color: colors.green3,
+  },
+  repostCount: {
+    color: 'currentColor',
+  },
+})
diff --git a/src/view/com/util/post-ctrls/RepostButton.web.tsx b/src/view/com/util/post-ctrls/RepostButton.web.tsx
new file mode 100644
index 000000000..66cc0d123
--- /dev/null
+++ b/src/view/com/util/post-ctrls/RepostButton.web.tsx
@@ -0,0 +1,86 @@
+import React, {useMemo} from 'react'
+import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
+import {RepostIcon} from 'lib/icons'
+import {DropdownButton} from '../forms/DropdownButton'
+import {colors} from 'lib/styles'
+import {useTheme} from 'lib/ThemeContext'
+import {Text} from '../text/Text'
+
+interface Props {
+  isReposted: boolean
+  repostCount?: number
+  big?: boolean
+  onRepost: () => void
+  onQuote: () => void
+}
+
+export const RepostButton = ({
+  isReposted,
+  repostCount,
+  big,
+  onRepost,
+  onQuote,
+}: Props) => {
+  const theme = useTheme()
+
+  const defaultControlColor = React.useMemo(
+    () => ({
+      color: theme.palette.default.postCtrl,
+    }),
+    [theme],
+  )
+
+  const items = useMemo(
+    () => [
+      {
+        label: isReposted ? 'Undo repost' : 'Repost',
+        icon: 'retweet' as const,
+        onPress: onRepost,
+      },
+      {label: 'Quote post', icon: 'quote-left' as const, onPress: onQuote},
+    ],
+    [isReposted, onRepost, onQuote],
+  )
+
+  return (
+    <DropdownButton
+      type="bare"
+      items={items}
+      bottomOffset={4}
+      openToRight
+      rightOffset={-40}>
+      <View
+        style={[
+          styles.control,
+          (isReposted
+            ? styles.reposted
+            : defaultControlColor) as StyleProp<ViewStyle>,
+        ]}>
+        <RepostIcon strokeWidth={2.4} size={big ? 24 : 20} />
+        {typeof repostCount !== 'undefined' ? (
+          <Text
+            testID="repostCount"
+            type={isReposted ? 'md-bold' : 'md-medium'}
+            style={styles.repostCount}>
+            {repostCount ?? 0}
+          </Text>
+        ) : undefined}
+      </View>
+    </DropdownButton>
+  )
+}
+
+const styles = StyleSheet.create({
+  control: {
+    display: 'flex',
+    flexDirection: 'row',
+    alignItems: 'center',
+    gap: 4,
+  },
+  reposted: {
+    color: colors.green3,
+  },
+  repostCount: {
+    color: 'currentColor',
+  },
+})