diff options
20 files changed, 160 insertions, 125 deletions
diff --git a/src/components/Post/Embed/ExternalEmbed/ExternalGif.tsx b/src/components/Post/Embed/ExternalEmbed/ExternalGif.tsx index 8a12f0374..0c8f30d2b 100644 --- a/src/components/Post/Embed/ExternalEmbed/ExternalGif.tsx +++ b/src/components/Post/Embed/ExternalEmbed/ExternalGif.tsx @@ -1,11 +1,15 @@ import React from 'react' -import {ActivityIndicator, GestureResponderEvent, Pressable} from 'react-native' +import { + ActivityIndicator, + type GestureResponderEvent, + Pressable, +} from 'react-native' import {Image} from 'expo-image' -import {AppBskyEmbedExternal} from '@atproto/api' +import {type AppBskyEmbedExternal} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {EmbedPlayerParams} from '#/lib/strings/embed-player' +import {type EmbedPlayerParams} from '#/lib/strings/embed-player' import {isIOS, isNative, isWeb} from '#/platform/detection' import {useExternalEmbedsPrefs} from '#/state/preferences' import {atoms as a, useTheme} from '#/alf' diff --git a/src/components/Post/Embed/ExternalEmbed/ExternalPlayer.tsx b/src/components/Post/Embed/ExternalEmbed/ExternalPlayer.tsx index 7f6d53340..392cdd8a1 100644 --- a/src/components/Post/Embed/ExternalEmbed/ExternalPlayer.tsx +++ b/src/components/Post/Embed/ExternalEmbed/ExternalPlayer.tsx @@ -1,7 +1,7 @@ import React from 'react' import { ActivityIndicator, - GestureResponderEvent, + type GestureResponderEvent, Pressable, StyleSheet, useWindowDimensions, @@ -16,13 +16,16 @@ import Animated, { import {useSafeAreaInsets} from 'react-native-safe-area-context' import {WebView} from 'react-native-webview' import {Image} from 'expo-image' -import {AppBskyEmbedExternal} from '@atproto/api' +import {type AppBskyEmbedExternal} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {NavigationProp} from '#/lib/routes/types' -import {EmbedPlayerParams, getPlayerAspect} from '#/lib/strings/embed-player' +import {type NavigationProp} from '#/lib/routes/types' +import { + type EmbedPlayerParams, + getPlayerAspect, +} from '#/lib/strings/embed-player' import {isNative} from '#/platform/detection' import {useExternalEmbedsPrefs} from '#/state/preferences' import {EventStopper} from '#/view/com/util/EventStopper' diff --git a/src/components/Post/Embed/ExternalEmbed/Gif.tsx b/src/components/Post/Embed/ExternalEmbed/Gif.tsx index a839294f1..8e8499731 100644 --- a/src/components/Post/Embed/ExternalEmbed/Gif.tsx +++ b/src/components/Post/Embed/ExternalEmbed/Gif.tsx @@ -1,17 +1,17 @@ import React from 'react' import { Pressable, - StyleProp, + type StyleProp, StyleSheet, TouchableOpacity, View, - ViewStyle, + type ViewStyle, } from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {HITSLOP_20} from '#/lib/constants' -import {EmbedPlayerParams} from '#/lib/strings/embed-player' +import {type EmbedPlayerParams} from '#/lib/strings/embed-player' import {isWeb} from '#/platform/detection' import {useAutoplayDisabled} from '#/state/preferences' import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' @@ -22,7 +22,7 @@ import * as Prompt from '#/components/Prompt' import {Text} from '#/components/Typography' import {PlayButtonIcon} from '#/components/video/PlayButtonIcon' import {GifView} from '../../../../../modules/expo-bluesky-gif-view' -import {GifViewStateChangeEvent} from '../../../../../modules/expo-bluesky-gif-view/src/GifView.types' +import {type GifViewStateChangeEvent} from '../../../../../modules/expo-bluesky-gif-view/src/GifView.types' function PlaybackControls({ onPress, diff --git a/src/components/Post/Embed/ListEmbed.tsx b/src/components/Post/Embed/ListEmbed.tsx index dc79a7579..82685d271 100644 --- a/src/components/Post/Embed/ListEmbed.tsx +++ b/src/components/Post/Embed/ListEmbed.tsx @@ -6,8 +6,8 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts' import {atoms as a, useTheme} from '#/alf' import * as ListCard from '#/components/ListCard' import {ContentHider} from '#/components/moderation/ContentHider' -import {EmbedType} from '#/types/bsky/post' -import {CommonProps} from './types' +import {type EmbedType} from '#/types/bsky/post' +import {type CommonProps} from './types' export function ListEmbed({ embed, diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/TimeIndicator.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/TimeIndicator.tsx index 95401309f..67af7618c 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/TimeIndicator.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/TimeIndicator.tsx @@ -1,4 +1,4 @@ -import {StyleProp, ViewStyle} from 'react-native' +import {type StyleProp, type ViewStyle} from 'react-native' import {View} from 'react-native' import {msg, plural} from '@lingui/macro' import {useLingui} from '@lingui/react' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx index 88879d45a..351e9f305 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx @@ -1,6 +1,6 @@ import React, {useRef} from 'react' -import {Pressable, StyleProp, View, ViewStyle} from 'react-native' -import {AppBskyEmbedVideo} from '@atproto/api' +import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native' +import {type AppBskyEmbedVideo} from '@atproto/api' import {BlueskyVideoView} from '@haileyok/bluesky-video' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx index 1b46163cc..37b44751d 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx @@ -1,7 +1,7 @@ -import React from 'react' import {View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import type React from 'react' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx index 1b69a3e25..9b0c963ea 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx @@ -1,5 +1,5 @@ -import React from 'react' -import {SvgProps} from 'react-native-svg' +import {type SvgProps} from 'react-native-svg' +import type React from 'react' import {PressableWithHover} from '#/view/com/util/PressableWithHover' import {atoms as a, useTheme, web} from '#/alf' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx index 96960bad4..d84a90fa6 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx @@ -1,7 +1,8 @@ -import React, {useCallback, useEffect, useRef, useState} from 'react' +import {useCallback, useEffect, useRef, useState} from 'react' import {View} from 'react-native' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import type React from 'react' import {isFirefox, isTouchDevice} from '#/lib/browser' import {clamp} from '#/lib/numbers' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx index e0b688075..ec5f23fc0 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx @@ -1,8 +1,9 @@ -import React, {useCallback} from 'react' +import {useCallback} from 'react' import {View} from 'react-native' import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import type React from 'react' import {isSafari, isTouchDevice} from '#/lib/browser' import {atoms as a} from '#/alf' diff --git a/src/components/Post/Embed/VideoEmbed/index.tsx b/src/components/Post/Embed/VideoEmbed/index.tsx index fe29ecad6..8cb78ff70 100644 --- a/src/components/Post/Embed/VideoEmbed/index.tsx +++ b/src/components/Post/Embed/VideoEmbed/index.tsx @@ -1,7 +1,7 @@ import React, {useCallback, useState} from 'react' import {ActivityIndicator, View} from 'react-native' import {ImageBackground} from 'expo-image' -import {AppBskyEmbedVideo} from '@atproto/api' +import {type AppBskyEmbedVideo} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' diff --git a/src/components/Post/Embed/VideoEmbed/index.web.tsx b/src/components/Post/Embed/VideoEmbed/index.web.tsx index 53adc3b6a..7f601af47 100644 --- a/src/components/Post/Embed/VideoEmbed/index.web.tsx +++ b/src/components/Post/Embed/VideoEmbed/index.web.tsx @@ -1,8 +1,9 @@ -import React, {useCallback, useEffect, useRef, useState} from 'react' +import {useCallback, useEffect, useRef, useState} from 'react' import {View} from 'react-native' -import {AppBskyEmbedVideo} from '@atproto/api' +import {type AppBskyEmbedVideo} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import type React from 'react' import {isFirefox} from '#/lib/browser' import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' diff --git a/src/components/Post/ShowMoreTextButton.tsx b/src/components/Post/ShowMoreTextButton.tsx new file mode 100644 index 000000000..bc6db55b9 --- /dev/null +++ b/src/components/Post/ShowMoreTextButton.tsx @@ -0,0 +1,56 @@ +import {useCallback, useMemo} from 'react' +import {LayoutAnimation, type TextStyle} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {HITSLOP_10} from '#/lib/constants' +import {atoms as a, flatten, type TextStyleProp, useTheme} from '#/alf' +import {Button} from '#/components/Button' +import {Text} from '#/components/Typography' + +export function ShowMoreTextButton({ + onPress: onPressProp, + style, +}: TextStyleProp & {onPress: () => void}) { + const t = useTheme() + const {_} = useLingui() + + const onPress = useCallback(() => { + LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) + onPressProp() + }, [onPressProp]) + + const textStyle = useMemo(() => { + return flatten([a.leading_snug, a.text_sm, style]) as TextStyle & { + fontSize: number + lineHeight: number + } + }, [style]) + + return ( + <Button + label={_(msg`Expand post text`)} + onPress={onPress} + style={[ + a.self_start, + { + paddingBottom: textStyle.fontSize / 3, + }, + ]} + hitSlop={HITSLOP_10}> + {({pressed, hovered}) => ( + <Text + style={[ + textStyle, + { + color: t.palette.primary_500, + opacity: pressed ? 0.6 : 1, + textDecorationLine: hovered ? 'underline' : undefined, + }, + ]}> + <Trans>Show More</Trans> + </Text> + )} + </Button> + ) +} diff --git a/src/screens/PostThread/components/ThreadItemPost.tsx b/src/screens/PostThread/components/ThreadItemPost.tsx index 9393a6d1b..4337397f8 100644 --- a/src/screens/PostThread/components/ThreadItemPost.tsx +++ b/src/screens/PostThread/components/ThreadItemPost.tsx @@ -6,13 +6,11 @@ import { AtUri, RichText as RichTextAPI, } from '@atproto/api' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' +import {Trans} from '@lingui/macro' import {useActorStatus} from '#/lib/actor-status' import {MAX_POST_LINES} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' -import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' import {countLines} from '#/lib/strings/helpers' import { @@ -24,7 +22,6 @@ import {type ThreadItem} from '#/state/queries/usePostThread/types' import {useSession} from '#/state/session' import {type OnPostSuccessData} from '#/state/shell/composer' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' -import {TextLink} from '#/view/com/util/Link' import {PostMeta} from '#/view/com/util/PostMeta' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' import { @@ -40,6 +37,7 @@ import {PostAlerts} from '#/components/moderation/PostAlerts' import {PostHider} from '#/components/moderation/PostHider' import {type AppModerationCause} from '#/components/Pills' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' +import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton' import {PostControls} from '#/components/PostControls' import {RichText} from '#/components/RichText' import * as Skele from '#/components/Skeleton' @@ -187,8 +185,6 @@ const ThreadItemPostInner = memo(function ThreadItemPostInner({ postShadow: Shadow<AppBskyFeedDefs.PostView> }) { const t = useTheme() - const pal = usePalette('default') - const {_} = useLingui() const {openComposer} = useOpenComposer() const {currentAccount} = useSession() @@ -304,22 +300,22 @@ const ThreadItemPostInner = memo(function ThreadItemPostInner({ additionalCauses={additionalPostAlerts} /> {richText?.text ? ( - <RichText - enableTags - value={richText} - style={[a.flex_1, a.text_md]} - numberOfLines={limitLines ? MAX_POST_LINES : undefined} - authorHandle={post.author.handle} - shouldProxyLinks={true} - /> - ) : undefined} - {limitLines ? ( - <TextLink - text={_(msg`Show More`)} - style={pal.link} - onPress={onPressShowMore} - href="#" - /> + <> + <RichText + enableTags + value={richText} + style={[a.flex_1, a.text_md]} + numberOfLines={limitLines ? MAX_POST_LINES : undefined} + authorHandle={post.author.handle} + shouldProxyLinks={true} + /> + {limitLines && ( + <ShowMoreTextButton + style={[a.text_md]} + onPress={onPressShowMore} + /> + )} + </> ) : undefined} {post.embed && ( <View style={[a.pb_xs]}> diff --git a/src/screens/PostThread/components/ThreadItemTreePost.tsx b/src/screens/PostThread/components/ThreadItemTreePost.tsx index ac659a6e0..a8ffb76f4 100644 --- a/src/screens/PostThread/components/ThreadItemTreePost.tsx +++ b/src/screens/PostThread/components/ThreadItemTreePost.tsx @@ -1,4 +1,4 @@ -import React, {memo, useMemo} from 'react' +import {memo, useCallback, useMemo, useState} from 'react' import {View} from 'react-native' import { type AppBskyFeedDefs, @@ -6,12 +6,10 @@ import { AtUri, RichText as RichTextAPI, } from '@atproto/api' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' +import {Trans} from '@lingui/macro' import {MAX_POST_LINES} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' -import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' import {countLines} from '#/lib/strings/helpers' import { @@ -23,7 +21,6 @@ import {type ThreadItem} from '#/state/queries/usePostThread/types' import {useSession} from '#/state/session' import {type OnPostSuccessData} from '#/state/shell/composer' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' -import {TextLink} from '#/view/com/util/Link' import {PostMeta} from '#/view/com/util/PostMeta' import { OUTER_SPACE, @@ -39,6 +36,7 @@ import {PostAlerts} from '#/components/moderation/PostAlerts' import {PostHider} from '#/components/moderation/PostHider' import {type AppModerationCause} from '#/components/Pills' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' +import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton' import {PostControls} from '#/components/PostControls' import {RichText} from '#/components/RichText' import * as Skele from '#/components/Skeleton' @@ -255,8 +253,6 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({ onPostSuccess?: (data: OnPostSuccessData) => void threadgateRecord?: AppBskyFeedThreadgate.Record }): React.ReactNode { - const pal = usePalette('default') - const {_} = useLingui() const {openComposer} = useOpenComposer() const {currentAccount} = useSession() @@ -271,18 +267,18 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({ }), [record], ) - const [limitLines, setLimitLines] = React.useState( + const [limitLines, setLimitLines] = useState( () => countLines(richText?.text) >= MAX_POST_LINES, ) const threadRootUri = record.reply?.root?.uri || post.uri - const postHref = React.useMemo(() => { + const postHref = useMemo(() => { const urip = new AtUri(post.uri) return makeProfileLink(post.author, 'post', urip.rkey) }, [post.uri, post.author]) const threadgateHiddenReplies = useMergedThreadgateHiddenReplies({ threadgateRecord, }) - const additionalPostAlerts: AppModerationCause[] = React.useMemo(() => { + const additionalPostAlerts: AppModerationCause[] = useMemo(() => { const isPostHiddenByThreadgate = threadgateHiddenReplies.has(post.uri) const isControlledByViewer = new AtUri(threadRootUri).host === currentAccount?.did @@ -297,7 +293,7 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({ : [] }, [post, currentAccount?.did, threadgateHiddenReplies, threadRootUri]) - const onPressReply = React.useCallback(() => { + const onPressReply = useCallback(() => { openComposer({ replyTo: { uri: post.uri, @@ -311,7 +307,7 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({ }) }, [openComposer, post, record, onPostSuccess, moderation]) - const onPressShowMore = React.useCallback(() => { + const onPressShowMore = useCallback(() => { setLimitLines(false) }, [setLimitLines]) @@ -348,7 +344,7 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({ additionalCauses={additionalPostAlerts} /> {richText?.text ? ( - <View> + <> <RichText enableTags value={richText} @@ -357,15 +353,13 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({ authorHandle={post.author.handle} shouldProxyLinks={true} /> - </View> - ) : undefined} - {limitLines ? ( - <TextLink - text={_(msg`Show More`)} - style={pal.link} - onPress={onPressShowMore} - href="#" - /> + {limitLines && ( + <ShowMoreTextButton + style={[a.text_md]} + onPress={onPressShowMore} + /> + )} + </> ) : undefined} {post.embed && ( <View style={[a.pb_xs]}> diff --git a/src/screens/VideoFeed/components/Scrubber.tsx b/src/screens/VideoFeed/components/Scrubber.tsx index 29cc4b278..69e68ec9e 100644 --- a/src/screens/VideoFeed/components/Scrubber.tsx +++ b/src/screens/VideoFeed/components/Scrubber.tsx @@ -3,13 +3,13 @@ import {View} from 'react-native' import { Gesture, GestureDetector, - NativeGesture, + type NativeGesture, } from 'react-native-gesture-handler' import Animated, { interpolate, runOnJS, runOnUI, - SharedValue, + type SharedValue, useAnimatedReaction, useAnimatedStyle, useSharedValue, @@ -20,7 +20,7 @@ import { useSafeAreaInsets, } from 'react-native-safe-area-context' import {useEventListener} from 'expo' -import {VideoPlayer} from 'expo-video' +import {type VideoPlayer} from 'expo-video' import {tokens} from '#/alf' import {atoms as a} from '#/alf' diff --git a/src/view/com/notifications/NotificationFeedItem.tsx b/src/view/com/notifications/NotificationFeedItem.tsx index 0a460e77b..85f67919a 100644 --- a/src/view/com/notifications/NotificationFeedItem.tsx +++ b/src/view/com/notifications/NotificationFeedItem.tsx @@ -30,6 +30,7 @@ import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' import {useQueryClient} from '@tanstack/react-query' +import {MAX_POST_LINES} from '#/lib/constants' import {useAnimatedValue} from '#/lib/hooks/useAnimatedValue' import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' @@ -918,7 +919,8 @@ function AdditionalPostText({post}: {post?: AppBskyFeedDefs.PostView}) { {text?.length > 0 && ( <Text emoji - style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}> + style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]} + numberOfLines={MAX_POST_LINES}> {text} </Text> )} diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 15f5539c9..592224ff5 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -44,7 +44,7 @@ import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replie import {type PostSource} from '#/state/unstable-post-source' import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' -import {Link, TextLink} from '#/view/com/util/Link' +import {Link} from '#/view/com/util/Link' import {formatCount} from '#/view/com/util/numeric/format' import {PostMeta} from '#/view/com/util/PostMeta' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' @@ -62,6 +62,7 @@ import {PostAlerts} from '#/components/moderation/PostAlerts' import {PostHider} from '#/components/moderation/PostHider' import {type AppModerationCause} from '#/components/Pills' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' +import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton' import {PostControls} from '#/components/PostControls' import * as Prompt from '#/components/Prompt' import {RichText} from '#/components/RichText' @@ -685,16 +686,14 @@ let PostThreadItemLoaded = ({ authorHandle={post.author.handle} shouldProxyLinks={true} /> + {limitLines && ( + <ShowMoreTextButton + style={[a.text_md]} + onPress={onPressShowMore} + /> + )} </View> ) : undefined} - {limitLines ? ( - <TextLink - text={_(msg`Show More`)} - style={pal.link} - onPress={onPressShowMore} - href="#" - /> - ) : undefined} {post.embed && ( <View style={[a.pb_xs]}> <Embed diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 19017f30f..6079f5c10 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -1,4 +1,4 @@ -import React, {useMemo, useState} from 'react' +import {useCallback, useMemo, useState} from 'react' import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native' import { type AppBskyFeedDefs, @@ -9,8 +9,7 @@ import { RichText as RichTextAPI, } from '@atproto/api' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' +import {Trans} from '@lingui/macro' import {useQueryClient} from '@tanstack/react-query' import {MAX_POST_LINES} from '#/lib/constants' @@ -27,7 +26,7 @@ import { import {useModerationOpts} from '#/state/preferences/moderation-opts' import {precacheProfile} from '#/state/queries/profile' import {useSession} from '#/state/session' -import {Link, TextLink} from '#/view/com/util/Link' +import {Link} from '#/view/com/util/Link' import {PostMeta} from '#/view/com/util/PostMeta' import {Text} from '#/view/com/util/text/Text' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' @@ -37,6 +36,7 @@ import {ContentHider} from '#/components/moderation/ContentHider' import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe' import {PostAlerts} from '#/components/moderation/PostAlerts' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' +import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton' import {PostControls} from '#/components/PostControls' import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {RichText} from '#/components/RichText' @@ -115,7 +115,6 @@ function PostInner({ }) { const queryClient = useQueryClient() const pal = usePalette('default') - const {_} = useLingui() const {openComposer} = useOpenComposer() const [limitLines, setLimitLines] = useState( () => countLines(richText?.text) >= MAX_POST_LINES, @@ -128,7 +127,7 @@ function PostInner({ replyAuthorDid = urip.hostname } - const onPressReply = React.useCallback(() => { + const onPressReply = useCallback(() => { openComposer({ replyTo: { uri: post.uri, @@ -141,18 +140,18 @@ function PostInner({ }) }, [openComposer, post, record, moderation]) - const onPressShowMore = React.useCallback(() => { + const onPressShowMore = useCallback(() => { setLimitLines(false) }, [setLimitLines]) - const onBeforePress = React.useCallback(() => { + const onBeforePress = useCallback(() => { precacheProfile(queryClient, post.author) }, [queryClient, post.author]) const {currentAccount} = useSession() const isMe = replyAuthorDid === currentAccount?.did - const [hover, setHover] = React.useState(false) + const [hover, setHover] = useState(false) return ( <Link href={itemHref} @@ -227,7 +226,7 @@ function PostInner({ style={[a.py_xs]} /> {richText.text ? ( - <View style={styles.postTextContainer}> + <View> <RichText enableTags testID="postText" @@ -237,16 +236,14 @@ function PostInner({ authorHandle={post.author.handle} shouldProxyLinks={true} /> + {limitLines && ( + <ShowMoreTextButton + style={[a.text_md]} + onPress={onPressShowMore} + /> + )} </View> ) : undefined} - {limitLines ? ( - <TextLink - text={_(msg`Show More`)} - style={pal.link} - onPress={onPressShowMore} - href="#" - /> - ) : undefined} {post.embed ? ( <Embed embed={post.embed} @@ -290,12 +287,6 @@ const styles = StyleSheet.create({ alert: { marginBottom: 6, }, - postTextContainer: { - flexDirection: 'row', - alignItems: 'center', - flexWrap: 'wrap', - overflow: 'hidden', - }, replyLine: { position: 'absolute', left: 36, diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx index 6755f013d..96d5df5e9 100644 --- a/src/view/com/posts/PostFeedItem.tsx +++ b/src/view/com/posts/PostFeedItem.tsx @@ -41,7 +41,7 @@ import { setUnstablePostSource, } from '#/state/unstable-post-source' import {FeedNameText} from '#/view/com/util/FeedInfoText' -import {Link, TextLink, TextLinkOnWebOnly} from '#/view/com/util/Link' +import {Link, TextLinkOnWebOnly} from '#/view/com/util/Link' import {PostMeta} from '#/view/com/util/PostMeta' import {Text} from '#/view/com/util/text/Text' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' @@ -54,6 +54,7 @@ import {PostAlerts} from '#/components/moderation/PostAlerts' import {type AppModerationCause} from '#/components/Pills' import {Embed} from '#/components/Post/Embed' import {PostEmbedViewContext} from '#/components/Post/Embed/types' +import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton' import {PostControls} from '#/components/PostControls' import {DiscoverDebug} from '#/components/PostControls/DiscoverDebug' import {ProfileHoverCard} from '#/components/ProfileHoverCard' @@ -501,8 +502,6 @@ let PostContent = ({ post: AppBskyFeedDefs.PostView threadgateRecord?: AppBskyFeedThreadgate.Record }): React.ReactNode => { - const pal = usePalette('default') - const {_} = useLingui() const {currentAccount} = useSession() const [limitLines, setLimitLines] = useState( () => countLines(richText.text) >= MAX_POST_LINES, @@ -547,7 +546,7 @@ let PostContent = ({ additionalCauses={additionalPostAlerts} /> {richText.text ? ( - <View style={styles.postTextContainer}> + <> <RichText enableTags testID="postText" @@ -557,15 +556,10 @@ let PostContent = ({ authorHandle={postAuthor.handle} shouldProxyLinks={true} /> - </View> - ) : undefined} - {limitLines ? ( - <TextLink - text={_(msg`Show More`)} - style={pal.link} - onPress={onPressShowMore} - href="#" - /> + {limitLines && ( + <ShowMoreTextButton style={[a.text_md]} onPress={onPressShowMore} /> + )} + </> ) : undefined} {postEmbed ? ( <View style={[a.pb_xs]}> @@ -689,13 +683,6 @@ const styles = StyleSheet.create({ marginTop: 6, marginBottom: 6, }, - postTextContainer: { - flexDirection: 'row', - alignItems: 'center', - flexWrap: 'wrap', - paddingBottom: 2, - overflow: 'hidden', - }, contentHiderChild: { marginTop: 6, }, |