about summary refs log tree commit diff
path: root/src/view/com/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util')
-rw-r--r--src/view/com/util/Link.tsx26
-rw-r--r--src/view/com/util/PostMeta.tsx119
-rw-r--r--src/view/com/util/UserAvatar.tsx54
3 files changed, 78 insertions, 121 deletions
diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx
index 1dec97e78..454fd7c21 100644
--- a/src/view/com/util/Link.tsx
+++ b/src/view/com/util/Link.tsx
@@ -6,6 +6,7 @@ import {
   Platform,
   StyleProp,
   TextStyle,
+  TextProps,
   View,
   ViewStyle,
   TouchableOpacity,
@@ -144,7 +145,7 @@ export const TextLink = observer(function TextLink({
   numberOfLines?: number
   lineHeight?: number
   dataSet?: any
-}) {
+} & TextProps) {
   const {...props} = useLinkProps({to: sanitizeUrl(href)})
   const store = useStores()
   const navigation = useNavigation<NavigationProp>()
@@ -186,16 +187,7 @@ export const TextLink = observer(function TextLink({
 /**
  * Only acts as a link on desktop web
  */
-export const DesktopWebTextLink = observer(function DesktopWebTextLink({
-  testID,
-  type = 'md',
-  style,
-  href,
-  text,
-  numberOfLines,
-  lineHeight,
-  ...props
-}: {
+interface DesktopWebTextLinkProps extends TextProps {
   testID?: string
   type?: TypographyVariant
   style?: StyleProp<TextStyle>
@@ -206,7 +198,17 @@ export const DesktopWebTextLink = observer(function DesktopWebTextLink({
   accessible?: boolean
   accessibilityLabel?: string
   accessibilityHint?: string
-}) {
+}
+export const DesktopWebTextLink = observer(function DesktopWebTextLink({
+  testID,
+  type = 'md',
+  style,
+  href,
+  text,
+  numberOfLines,
+  lineHeight,
+  ...props
+}: DesktopWebTextLinkProps) {
   if (isDesktopWeb) {
     return (
       <TextLink
diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx
index 628c88722..396b0278d 100644
--- a/src/view/com/util/PostMeta.tsx
+++ b/src/view/com/util/PostMeta.tsx
@@ -4,12 +4,10 @@ import {Text} from './text/Text'
 import {DesktopWebTextLink} from './Link'
 import {ago, niceDate} from 'lib/strings/time'
 import {usePalette} from 'lib/hooks/usePalette'
-import {useStores} from 'state/index'
 import {UserAvatar} from './UserAvatar'
 import {observer} from 'mobx-react-lite'
-import {FollowButton} from '../profile/FollowButton'
-import {FollowState} from 'state/models/cache/my-follows'
 import {sanitizeDisplayName} from 'lib/strings/display-names'
+import {isAndroid, isIOS} from 'platform/detection'
 
 interface PostMetaOpts {
   authorAvatar?: string
@@ -18,88 +16,17 @@ interface PostMetaOpts {
   authorHasWarning: boolean
   postHref: string
   timestamp: string
-  did?: string
-  showFollowBtn?: boolean
 }
 
 export const PostMeta = observer(function (opts: PostMetaOpts) {
   const pal = usePalette('default')
   const displayName = opts.authorDisplayName || opts.authorHandle
   const handle = opts.authorHandle
-  const store = useStores()
-  const isMe = opts.did === store.me.did
-  const followState =
-    typeof opts.did === 'string'
-      ? store.me.follows.getFollowState(opts.did)
-      : FollowState.Unknown
 
-  const [didFollow, setDidFollow] = React.useState(false)
-  const onToggleFollow = React.useCallback(() => {
-    setDidFollow(true)
-  }, [setDidFollow])
-
-  if (
-    opts.showFollowBtn &&
-    !isMe &&
-    (followState === FollowState.NotFollowing || didFollow) &&
-    opts.did
-  ) {
-    // two-liner with follow button
-    return (
-      <View style={styles.metaTwoLine}>
-        <View style={styles.metaTwoLineLeft}>
-          <View style={styles.metaTwoLineTop}>
-            <DesktopWebTextLink
-              type="lg-bold"
-              style={pal.text}
-              numberOfLines={1}
-              lineHeight={1.2}
-              text={sanitizeDisplayName(displayName)}
-              href={`/profile/${opts.authorHandle}`}
-            />
-            <Text
-              type="md"
-              style={pal.textLight}
-              lineHeight={1.2}
-              accessible={false}>
-              &nbsp;&middot;&nbsp;
-            </Text>
-            <DesktopWebTextLink
-              type="md"
-              style={[styles.metaItem, pal.textLight]}
-              lineHeight={1.2}
-              text={ago(opts.timestamp)}
-              accessibilityLabel={niceDate(opts.timestamp)}
-              accessibilityHint=""
-              href={opts.postHref}
-            />
-          </View>
-          <DesktopWebTextLink
-            type="md"
-            style={[styles.metaItem, pal.textLight]}
-            lineHeight={1.2}
-            numberOfLines={1}
-            text={`@${handle}`}
-            href={`/profile/${opts.authorHandle}`}
-          />
-        </View>
-
-        <View>
-          <FollowButton
-            unfollowedType="default"
-            did={opts.did}
-            onToggleFollow={onToggleFollow}
-          />
-        </View>
-      </View>
-    )
-  }
-
-  // one-liner
   return (
-    <View style={styles.meta}>
+    <View style={styles.metaOneLine}>
       {typeof opts.authorAvatar !== 'undefined' && (
-        <View style={[styles.metaItem, styles.avatar]}>
+        <View style={styles.avatar}>
           <UserAvatar
             avatar={opts.authorAvatar}
             size={16}
@@ -107,7 +34,7 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
           />
         </View>
       )}
-      <View style={[styles.metaItem, styles.maxWidth]}>
+      <View style={styles.maxWidth}>
         <DesktopWebTextLink
           type="lg-bold"
           style={pal.text}
@@ -128,12 +55,18 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
           href={`/profile/${opts.authorHandle}`}
         />
       </View>
-      <Text type="md" style={pal.textLight} lineHeight={1.2} accessible={false}>
-        &middot;&nbsp;
-      </Text>
+      {!isAndroid && (
+        <Text
+          type="md"
+          style={pal.textLight}
+          lineHeight={1.2}
+          accessible={false}>
+          &middot;
+        </Text>
+      )}
       <DesktopWebTextLink
         type="md"
-        style={[styles.metaItem, pal.textLight]}
+        style={pal.textLight}
         lineHeight={1.2}
         text={ago(opts.timestamp)}
         accessibilityLabel={niceDate(opts.timestamp)}
@@ -145,32 +78,16 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
 })
 
 const styles = StyleSheet.create({
-  meta: {
+  metaOneLine: {
     flexDirection: 'row',
     paddingBottom: 2,
-  },
-  metaTwoLine: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    justifyContent: 'space-between',
-    width: '100%',
-    paddingBottom: 4,
-  },
-  metaTwoLineLeft: {
-    flex: 1,
-    paddingRight: 40,
-  },
-  metaTwoLineTop: {
-    flexDirection: 'row',
-    alignItems: 'baseline',
-  },
-  metaItem: {
-    paddingRight: 5,
+    gap: 4,
   },
   avatar: {
     alignSelf: 'center',
   },
   maxWidth: {
-    maxWidth: '80%',
+    flex: isAndroid ? 1 : undefined,
+    maxWidth: isIOS ? '80%' : undefined,
   },
 })
diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx
index b94cf54e9..135615a3b 100644
--- a/src/view/com/util/UserAvatar.tsx
+++ b/src/view/com/util/UserAvatar.tsx
@@ -1,5 +1,5 @@
 import React, {useMemo} from 'react'
-import {StyleSheet, View} from 'react-native'
+import {Pressable, StyleSheet, View} from 'react-native'
 import Svg, {Circle, Rect, Path} from 'react-native-svg'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {IconProp} from '@fortawesome/fontawesome-svg-core'
@@ -12,13 +12,31 @@ import {
 import {useStores} from 'state/index'
 import {colors} from 'lib/styles'
 import {DropdownButton} from './forms/DropdownButton'
+import {Link} from './Link'
 import {usePalette} from 'lib/hooks/usePalette'
 import {isWeb, isAndroid} from 'platform/detection'
 import {Image as RNImage} from 'react-native-image-crop-picker'
 import {AvatarModeration} from 'lib/labeling/types'
+import {isDesktopWeb} from 'platform/detection'
 
 type Type = 'user' | 'algo' | 'list'
 
+interface BaseUserAvatarProps {
+  type?: Type
+  size: number
+  avatar?: string | null
+  moderation?: AvatarModeration
+}
+
+interface UserAvatarProps extends BaseUserAvatarProps {
+  onSelectNewAvatar?: (img: RNImage | null) => void
+}
+
+interface PreviewableUserAvatarProps extends BaseUserAvatarProps {
+  did: string
+  handle: string
+}
+
 const BLUR_AMOUNT = isWeb ? 5 : 100
 
 function DefaultAvatar({type, size}: {type: Type; size: number}) {
@@ -91,13 +109,7 @@ export function UserAvatar({
   avatar,
   moderation,
   onSelectNewAvatar,
-}: {
-  type?: Type
-  size: number
-  avatar?: string | null
-  moderation?: AvatarModeration
-  onSelectNewAvatar?: (img: RNImage | null) => void
-}) {
+}: UserAvatarProps) {
   const store = useStores()
   const pal = usePalette('default')
   const {requestCameraAccessIfNeeded} = useCameraPermission()
@@ -244,6 +256,32 @@ export function UserAvatar({
   )
 }
 
+export function PreviewableUserAvatar(props: PreviewableUserAvatarProps) {
+  const store = useStores()
+
+  if (isDesktopWeb) {
+    return (
+      <Link href={`/profile/${props.handle}`} title={props.handle} asAnchor>
+        <UserAvatar {...props} />
+      </Link>
+    )
+  }
+  return (
+    <Pressable
+      onPress={() =>
+        store.shell.openModal({
+          name: 'profile-preview',
+          did: props.did,
+        })
+      }
+      accessibilityRole="button"
+      accessibilityLabel={props.handle}
+      accessibilityHint="">
+      <UserAvatar {...props} />
+    </Pressable>
+  )
+}
+
 const styles = StyleSheet.create({
   editButtonContainer: {
     position: 'absolute',