+7
-3
src/components/Post/Embed/ExternalEmbed/ExternalGif.tsx
+7
-3
src/components/Post/Embed/ExternalEmbed/ExternalGif.tsx
···
1
1
import React from 'react'
2
-
import {ActivityIndicator, GestureResponderEvent, Pressable} from 'react-native'
2
+
import {
3
+
ActivityIndicator,
4
+
type GestureResponderEvent,
5
+
Pressable,
6
+
} from 'react-native'
3
7
import {Image} from 'expo-image'
4
-
import {AppBskyEmbedExternal} from '@atproto/api'
8
+
import {type AppBskyEmbedExternal} from '@atproto/api'
5
9
import {msg} from '@lingui/macro'
6
10
import {useLingui} from '@lingui/react'
7
11
8
-
import {EmbedPlayerParams} from '#/lib/strings/embed-player'
12
+
import {type EmbedPlayerParams} from '#/lib/strings/embed-player'
9
13
import {isIOS, isNative, isWeb} from '#/platform/detection'
10
14
import {useExternalEmbedsPrefs} from '#/state/preferences'
11
15
import {atoms as a, useTheme} from '#/alf'
+7
-4
src/components/Post/Embed/ExternalEmbed/ExternalPlayer.tsx
+7
-4
src/components/Post/Embed/ExternalEmbed/ExternalPlayer.tsx
···
1
1
import React from 'react'
2
2
import {
3
3
ActivityIndicator,
4
-
GestureResponderEvent,
4
+
type GestureResponderEvent,
5
5
Pressable,
6
6
StyleSheet,
7
7
useWindowDimensions,
···
16
16
import {useSafeAreaInsets} from 'react-native-safe-area-context'
17
17
import {WebView} from 'react-native-webview'
18
18
import {Image} from 'expo-image'
19
-
import {AppBskyEmbedExternal} from '@atproto/api'
19
+
import {type AppBskyEmbedExternal} from '@atproto/api'
20
20
import {msg} from '@lingui/macro'
21
21
import {useLingui} from '@lingui/react'
22
22
import {useNavigation} from '@react-navigation/native'
23
23
24
-
import {NavigationProp} from '#/lib/routes/types'
25
-
import {EmbedPlayerParams, getPlayerAspect} from '#/lib/strings/embed-player'
24
+
import {type NavigationProp} from '#/lib/routes/types'
25
+
import {
26
+
type EmbedPlayerParams,
27
+
getPlayerAspect,
28
+
} from '#/lib/strings/embed-player'
26
29
import {isNative} from '#/platform/detection'
27
30
import {useExternalEmbedsPrefs} from '#/state/preferences'
28
31
import {EventStopper} from '#/view/com/util/EventStopper'
+4
-4
src/components/Post/Embed/ExternalEmbed/Gif.tsx
+4
-4
src/components/Post/Embed/ExternalEmbed/Gif.tsx
···
1
1
import React from 'react'
2
2
import {
3
3
Pressable,
4
-
StyleProp,
4
+
type StyleProp,
5
5
StyleSheet,
6
6
TouchableOpacity,
7
7
View,
8
-
ViewStyle,
8
+
type ViewStyle,
9
9
} from 'react-native'
10
10
import {msg, Trans} from '@lingui/macro'
11
11
import {useLingui} from '@lingui/react'
12
12
13
13
import {HITSLOP_20} from '#/lib/constants'
14
-
import {EmbedPlayerParams} from '#/lib/strings/embed-player'
14
+
import {type EmbedPlayerParams} from '#/lib/strings/embed-player'
15
15
import {isWeb} from '#/platform/detection'
16
16
import {useAutoplayDisabled} from '#/state/preferences'
17
17
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
···
22
22
import {Text} from '#/components/Typography'
23
23
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
24
24
import {GifView} from '../../../../../modules/expo-bluesky-gif-view'
25
-
import {GifViewStateChangeEvent} from '../../../../../modules/expo-bluesky-gif-view/src/GifView.types'
25
+
import {type GifViewStateChangeEvent} from '../../../../../modules/expo-bluesky-gif-view/src/GifView.types'
26
26
27
27
function PlaybackControls({
28
28
onPress,
+2
-2
src/components/Post/Embed/ListEmbed.tsx
+2
-2
src/components/Post/Embed/ListEmbed.tsx
···
6
6
import {atoms as a, useTheme} from '#/alf'
7
7
import * as ListCard from '#/components/ListCard'
8
8
import {ContentHider} from '#/components/moderation/ContentHider'
9
-
import {EmbedType} from '#/types/bsky/post'
10
-
import {CommonProps} from './types'
9
+
import {type EmbedType} from '#/types/bsky/post'
10
+
import {type CommonProps} from './types'
11
11
12
12
export function ListEmbed({
13
13
embed,
+1
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/TimeIndicator.tsx
+1
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/TimeIndicator.tsx
+2
-2
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx
+2
-2
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx
···
1
1
import React, {useRef} from 'react'
2
-
import {Pressable, StyleProp, View, ViewStyle} from 'react-native'
3
-
import {AppBskyEmbedVideo} from '@atproto/api'
2
+
import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
3
+
import {type AppBskyEmbedVideo} from '@atproto/api'
4
4
import {BlueskyVideoView} from '@haileyok/bluesky-video'
5
5
import {msg} from '@lingui/macro'
6
6
import {useLingui} from '@lingui/react'
+1
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx
+1
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx
···
1
-
import React from 'react'
2
1
import {View} from 'react-native'
3
2
import {msg, Trans} from '@lingui/macro'
4
3
import {useLingui} from '@lingui/react'
4
+
import type React from 'react'
5
5
6
6
import {atoms as a, useTheme} from '#/alf'
7
7
import {Button, ButtonText} from '#/components/Button'
+2
-2
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx
+2
-2
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx
+2
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx
+2
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx
···
1
-
import React, {useCallback, useEffect, useRef, useState} from 'react'
1
+
import {useCallback, useEffect, useRef, useState} from 'react'
2
2
import {View} from 'react-native'
3
3
import {msg} from '@lingui/macro'
4
4
import {useLingui} from '@lingui/react'
5
+
import type React from 'react'
5
6
6
7
import {isFirefox, isTouchDevice} from '#/lib/browser'
7
8
import {clamp} from '#/lib/numbers'
+2
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx
+2
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx
···
1
-
import React, {useCallback} from 'react'
1
+
import {useCallback} from 'react'
2
2
import {View} from 'react-native'
3
3
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
4
4
import {msg} from '@lingui/macro'
5
5
import {useLingui} from '@lingui/react'
6
+
import type React from 'react'
6
7
7
8
import {isSafari, isTouchDevice} from '#/lib/browser'
8
9
import {atoms as a} from '#/alf'
+1
-1
src/components/Post/Embed/VideoEmbed/index.tsx
+1
-1
src/components/Post/Embed/VideoEmbed/index.tsx
···
1
1
import React, {useCallback, useState} from 'react'
2
2
import {ActivityIndicator, View} from 'react-native'
3
3
import {ImageBackground} from 'expo-image'
4
-
import {AppBskyEmbedVideo} from '@atproto/api'
4
+
import {type AppBskyEmbedVideo} from '@atproto/api'
5
5
import {msg, Trans} from '@lingui/macro'
6
6
import {useLingui} from '@lingui/react'
7
7
+3
-2
src/components/Post/Embed/VideoEmbed/index.web.tsx
+3
-2
src/components/Post/Embed/VideoEmbed/index.web.tsx
···
1
-
import React, {useCallback, useEffect, useRef, useState} from 'react'
1
+
import {useCallback, useEffect, useRef, useState} from 'react'
2
2
import {View} from 'react-native'
3
-
import {AppBskyEmbedVideo} from '@atproto/api'
3
+
import {type AppBskyEmbedVideo} from '@atproto/api'
4
4
import {msg} from '@lingui/macro'
5
5
import {useLingui} from '@lingui/react'
6
+
import type React from 'react'
6
7
7
8
import {isFirefox} from '#/lib/browser'
8
9
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
+56
src/components/Post/ShowMoreTextButton.tsx
+56
src/components/Post/ShowMoreTextButton.tsx
···
1
+
import {useCallback, useMemo} from 'react'
2
+
import {LayoutAnimation, type TextStyle} from 'react-native'
3
+
import {msg, Trans} from '@lingui/macro'
4
+
import {useLingui} from '@lingui/react'
5
+
6
+
import {HITSLOP_10} from '#/lib/constants'
7
+
import {atoms as a, flatten, type TextStyleProp, useTheme} from '#/alf'
8
+
import {Button} from '#/components/Button'
9
+
import {Text} from '#/components/Typography'
10
+
11
+
export function ShowMoreTextButton({
12
+
onPress: onPressProp,
13
+
style,
14
+
}: TextStyleProp & {onPress: () => void}) {
15
+
const t = useTheme()
16
+
const {_} = useLingui()
17
+
18
+
const onPress = useCallback(() => {
19
+
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
20
+
onPressProp()
21
+
}, [onPressProp])
22
+
23
+
const textStyle = useMemo(() => {
24
+
return flatten([a.leading_snug, a.text_sm, style]) as TextStyle & {
25
+
fontSize: number
26
+
lineHeight: number
27
+
}
28
+
}, [style])
29
+
30
+
return (
31
+
<Button
32
+
label={_(msg`Expand post text`)}
33
+
onPress={onPress}
34
+
style={[
35
+
a.self_start,
36
+
{
37
+
paddingBottom: textStyle.fontSize / 3,
38
+
},
39
+
]}
40
+
hitSlop={HITSLOP_10}>
41
+
{({pressed, hovered}) => (
42
+
<Text
43
+
style={[
44
+
textStyle,
45
+
{
46
+
color: t.palette.primary_500,
47
+
opacity: pressed ? 0.6 : 1,
48
+
textDecorationLine: hovered ? 'underline' : undefined,
49
+
},
50
+
]}>
51
+
<Trans>Show More</Trans>
52
+
</Text>
53
+
)}
54
+
</Button>
55
+
)
56
+
}
+18
-22
src/screens/PostThread/components/ThreadItemPost.tsx
+18
-22
src/screens/PostThread/components/ThreadItemPost.tsx
···
6
6
AtUri,
7
7
RichText as RichTextAPI,
8
8
} from '@atproto/api'
9
-
import {msg, Trans} from '@lingui/macro'
10
-
import {useLingui} from '@lingui/react'
9
+
import {Trans} from '@lingui/macro'
11
10
12
11
import {useActorStatus} from '#/lib/actor-status'
13
12
import {MAX_POST_LINES} from '#/lib/constants'
14
13
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
15
-
import {usePalette} from '#/lib/hooks/usePalette'
16
14
import {makeProfileLink} from '#/lib/routes/links'
17
15
import {countLines} from '#/lib/strings/helpers'
18
16
import {
···
24
22
import {useSession} from '#/state/session'
25
23
import {type OnPostSuccessData} from '#/state/shell/composer'
26
24
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
27
-
import {TextLink} from '#/view/com/util/Link'
28
25
import {PostMeta} from '#/view/com/util/PostMeta'
29
26
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
30
27
import {
···
40
37
import {PostHider} from '#/components/moderation/PostHider'
41
38
import {type AppModerationCause} from '#/components/Pills'
42
39
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
40
+
import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton'
43
41
import {PostControls} from '#/components/PostControls'
44
42
import {RichText} from '#/components/RichText'
45
43
import * as Skele from '#/components/Skeleton'
···
187
185
postShadow: Shadow<AppBskyFeedDefs.PostView>
188
186
}) {
189
187
const t = useTheme()
190
-
const pal = usePalette('default')
191
-
const {_} = useLingui()
192
188
const {openComposer} = useOpenComposer()
193
189
const {currentAccount} = useSession()
194
190
···
304
300
additionalCauses={additionalPostAlerts}
305
301
/>
306
302
{richText?.text ? (
307
-
<RichText
308
-
enableTags
309
-
value={richText}
310
-
style={[a.flex_1, a.text_md]}
311
-
numberOfLines={limitLines ? MAX_POST_LINES : undefined}
312
-
authorHandle={post.author.handle}
313
-
shouldProxyLinks={true}
314
-
/>
315
-
) : undefined}
316
-
{limitLines ? (
317
-
<TextLink
318
-
text={_(msg`Show More`)}
319
-
style={pal.link}
320
-
onPress={onPressShowMore}
321
-
href="#"
322
-
/>
303
+
<>
304
+
<RichText
305
+
enableTags
306
+
value={richText}
307
+
style={[a.flex_1, a.text_md]}
308
+
numberOfLines={limitLines ? MAX_POST_LINES : undefined}
309
+
authorHandle={post.author.handle}
310
+
shouldProxyLinks={true}
311
+
/>
312
+
{limitLines && (
313
+
<ShowMoreTextButton
314
+
style={[a.text_md]}
315
+
onPress={onPressShowMore}
316
+
/>
317
+
)}
318
+
</>
323
319
) : undefined}
324
320
{post.embed && (
325
321
<View style={[a.pb_xs]}>
+16
-22
src/screens/PostThread/components/ThreadItemTreePost.tsx
+16
-22
src/screens/PostThread/components/ThreadItemTreePost.tsx
···
1
-
import React, {memo, useMemo} from 'react'
1
+
import {memo, useCallback, useMemo, useState} from 'react'
2
2
import {View} from 'react-native'
3
3
import {
4
4
type AppBskyFeedDefs,
···
6
6
AtUri,
7
7
RichText as RichTextAPI,
8
8
} from '@atproto/api'
9
-
import {msg, Trans} from '@lingui/macro'
10
-
import {useLingui} from '@lingui/react'
9
+
import {Trans} from '@lingui/macro'
11
10
12
11
import {MAX_POST_LINES} from '#/lib/constants'
13
12
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
14
-
import {usePalette} from '#/lib/hooks/usePalette'
15
13
import {makeProfileLink} from '#/lib/routes/links'
16
14
import {countLines} from '#/lib/strings/helpers'
17
15
import {
···
23
21
import {useSession} from '#/state/session'
24
22
import {type OnPostSuccessData} from '#/state/shell/composer'
25
23
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
26
-
import {TextLink} from '#/view/com/util/Link'
27
24
import {PostMeta} from '#/view/com/util/PostMeta'
28
25
import {
29
26
OUTER_SPACE,
···
39
36
import {PostHider} from '#/components/moderation/PostHider'
40
37
import {type AppModerationCause} from '#/components/Pills'
41
38
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
39
+
import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton'
42
40
import {PostControls} from '#/components/PostControls'
43
41
import {RichText} from '#/components/RichText'
44
42
import * as Skele from '#/components/Skeleton'
···
255
253
onPostSuccess?: (data: OnPostSuccessData) => void
256
254
threadgateRecord?: AppBskyFeedThreadgate.Record
257
255
}): React.ReactNode {
258
-
const pal = usePalette('default')
259
-
const {_} = useLingui()
260
256
const {openComposer} = useOpenComposer()
261
257
const {currentAccount} = useSession()
262
258
···
271
267
}),
272
268
[record],
273
269
)
274
-
const [limitLines, setLimitLines] = React.useState(
270
+
const [limitLines, setLimitLines] = useState(
275
271
() => countLines(richText?.text) >= MAX_POST_LINES,
276
272
)
277
273
const threadRootUri = record.reply?.root?.uri || post.uri
278
-
const postHref = React.useMemo(() => {
274
+
const postHref = useMemo(() => {
279
275
const urip = new AtUri(post.uri)
280
276
return makeProfileLink(post.author, 'post', urip.rkey)
281
277
}, [post.uri, post.author])
282
278
const threadgateHiddenReplies = useMergedThreadgateHiddenReplies({
283
279
threadgateRecord,
284
280
})
285
-
const additionalPostAlerts: AppModerationCause[] = React.useMemo(() => {
281
+
const additionalPostAlerts: AppModerationCause[] = useMemo(() => {
286
282
const isPostHiddenByThreadgate = threadgateHiddenReplies.has(post.uri)
287
283
const isControlledByViewer =
288
284
new AtUri(threadRootUri).host === currentAccount?.did
···
297
293
: []
298
294
}, [post, currentAccount?.did, threadgateHiddenReplies, threadRootUri])
299
295
300
-
const onPressReply = React.useCallback(() => {
296
+
const onPressReply = useCallback(() => {
301
297
openComposer({
302
298
replyTo: {
303
299
uri: post.uri,
···
311
307
})
312
308
}, [openComposer, post, record, onPostSuccess, moderation])
313
309
314
-
const onPressShowMore = React.useCallback(() => {
310
+
const onPressShowMore = useCallback(() => {
315
311
setLimitLines(false)
316
312
}, [setLimitLines])
317
313
···
348
344
additionalCauses={additionalPostAlerts}
349
345
/>
350
346
{richText?.text ? (
351
-
<View>
347
+
<>
352
348
<RichText
353
349
enableTags
354
350
value={richText}
···
357
353
authorHandle={post.author.handle}
358
354
shouldProxyLinks={true}
359
355
/>
360
-
</View>
361
-
) : undefined}
362
-
{limitLines ? (
363
-
<TextLink
364
-
text={_(msg`Show More`)}
365
-
style={pal.link}
366
-
onPress={onPressShowMore}
367
-
href="#"
368
-
/>
356
+
{limitLines && (
357
+
<ShowMoreTextButton
358
+
style={[a.text_md]}
359
+
onPress={onPressShowMore}
360
+
/>
361
+
)}
362
+
</>
369
363
) : undefined}
370
364
{post.embed && (
371
365
<View style={[a.pb_xs]}>
+3
-3
src/screens/VideoFeed/components/Scrubber.tsx
+3
-3
src/screens/VideoFeed/components/Scrubber.tsx
···
3
3
import {
4
4
Gesture,
5
5
GestureDetector,
6
-
NativeGesture,
6
+
type NativeGesture,
7
7
} from 'react-native-gesture-handler'
8
8
import Animated, {
9
9
interpolate,
10
10
runOnJS,
11
11
runOnUI,
12
-
SharedValue,
12
+
type SharedValue,
13
13
useAnimatedReaction,
14
14
useAnimatedStyle,
15
15
useSharedValue,
···
20
20
useSafeAreaInsets,
21
21
} from 'react-native-safe-area-context'
22
22
import {useEventListener} from 'expo'
23
-
import {VideoPlayer} from 'expo-video'
23
+
import {type VideoPlayer} from 'expo-video'
24
24
25
25
import {tokens} from '#/alf'
26
26
import {atoms as a} from '#/alf'
+3
-1
src/view/com/notifications/NotificationFeedItem.tsx
+3
-1
src/view/com/notifications/NotificationFeedItem.tsx
···
30
30
import {useNavigation} from '@react-navigation/native'
31
31
import {useQueryClient} from '@tanstack/react-query'
32
32
33
+
import {MAX_POST_LINES} from '#/lib/constants'
33
34
import {useAnimatedValue} from '#/lib/hooks/useAnimatedValue'
34
35
import {usePalette} from '#/lib/hooks/usePalette'
35
36
import {makeProfileLink} from '#/lib/routes/links'
···
918
919
{text?.length > 0 && (
919
920
<Text
920
921
emoji
921
-
style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}>
922
+
style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}
923
+
numberOfLines={MAX_POST_LINES}>
922
924
{text}
923
925
</Text>
924
926
)}
+8
-9
src/view/com/post-thread/PostThreadItem.tsx
+8
-9
src/view/com/post-thread/PostThreadItem.tsx
···
44
44
import {type PostSource} from '#/state/unstable-post-source'
45
45
import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn'
46
46
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
47
-
import {Link, TextLink} from '#/view/com/util/Link'
47
+
import {Link} from '#/view/com/util/Link'
48
48
import {formatCount} from '#/view/com/util/numeric/format'
49
49
import {PostMeta} from '#/view/com/util/PostMeta'
50
50
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
···
62
62
import {PostHider} from '#/components/moderation/PostHider'
63
63
import {type AppModerationCause} from '#/components/Pills'
64
64
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
65
+
import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton'
65
66
import {PostControls} from '#/components/PostControls'
66
67
import * as Prompt from '#/components/Prompt'
67
68
import {RichText} from '#/components/RichText'
···
685
686
authorHandle={post.author.handle}
686
687
shouldProxyLinks={true}
687
688
/>
689
+
{limitLines && (
690
+
<ShowMoreTextButton
691
+
style={[a.text_md]}
692
+
onPress={onPressShowMore}
693
+
/>
694
+
)}
688
695
</View>
689
-
) : undefined}
690
-
{limitLines ? (
691
-
<TextLink
692
-
text={_(msg`Show More`)}
693
-
style={pal.link}
694
-
onPress={onPressShowMore}
695
-
href="#"
696
-
/>
697
696
) : undefined}
698
697
{post.embed && (
699
698
<View style={[a.pb_xs]}>
+15
-24
src/view/com/post/Post.tsx
+15
-24
src/view/com/post/Post.tsx
···
1
-
import React, {useMemo, useState} from 'react'
1
+
import {useCallback, useMemo, useState} from 'react'
2
2
import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native'
3
3
import {
4
4
type AppBskyFeedDefs,
···
9
9
RichText as RichTextAPI,
10
10
} from '@atproto/api'
11
11
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
12
-
import {msg, Trans} from '@lingui/macro'
13
-
import {useLingui} from '@lingui/react'
12
+
import {Trans} from '@lingui/macro'
14
13
import {useQueryClient} from '@tanstack/react-query'
15
14
16
15
import {MAX_POST_LINES} from '#/lib/constants'
···
27
26
import {useModerationOpts} from '#/state/preferences/moderation-opts'
28
27
import {precacheProfile} from '#/state/queries/profile'
29
28
import {useSession} from '#/state/session'
30
-
import {Link, TextLink} from '#/view/com/util/Link'
29
+
import {Link} from '#/view/com/util/Link'
31
30
import {PostMeta} from '#/view/com/util/PostMeta'
32
31
import {Text} from '#/view/com/util/text/Text'
33
32
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
···
37
36
import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe'
38
37
import {PostAlerts} from '#/components/moderation/PostAlerts'
39
38
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
39
+
import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton'
40
40
import {PostControls} from '#/components/PostControls'
41
41
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
42
42
import {RichText} from '#/components/RichText'
···
115
115
}) {
116
116
const queryClient = useQueryClient()
117
117
const pal = usePalette('default')
118
-
const {_} = useLingui()
119
118
const {openComposer} = useOpenComposer()
120
119
const [limitLines, setLimitLines] = useState(
121
120
() => countLines(richText?.text) >= MAX_POST_LINES,
···
128
127
replyAuthorDid = urip.hostname
129
128
}
130
129
131
-
const onPressReply = React.useCallback(() => {
130
+
const onPressReply = useCallback(() => {
132
131
openComposer({
133
132
replyTo: {
134
133
uri: post.uri,
···
141
140
})
142
141
}, [openComposer, post, record, moderation])
143
142
144
-
const onPressShowMore = React.useCallback(() => {
143
+
const onPressShowMore = useCallback(() => {
145
144
setLimitLines(false)
146
145
}, [setLimitLines])
147
146
148
-
const onBeforePress = React.useCallback(() => {
147
+
const onBeforePress = useCallback(() => {
149
148
precacheProfile(queryClient, post.author)
150
149
}, [queryClient, post.author])
151
150
152
151
const {currentAccount} = useSession()
153
152
const isMe = replyAuthorDid === currentAccount?.did
154
153
155
-
const [hover, setHover] = React.useState(false)
154
+
const [hover, setHover] = useState(false)
156
155
return (
157
156
<Link
158
157
href={itemHref}
···
227
226
style={[a.py_xs]}
228
227
/>
229
228
{richText.text ? (
230
-
<View style={styles.postTextContainer}>
229
+
<View>
231
230
<RichText
232
231
enableTags
233
232
testID="postText"
···
237
236
authorHandle={post.author.handle}
238
237
shouldProxyLinks={true}
239
238
/>
239
+
{limitLines && (
240
+
<ShowMoreTextButton
241
+
style={[a.text_md]}
242
+
onPress={onPressShowMore}
243
+
/>
244
+
)}
240
245
</View>
241
-
) : undefined}
242
-
{limitLines ? (
243
-
<TextLink
244
-
text={_(msg`Show More`)}
245
-
style={pal.link}
246
-
onPress={onPressShowMore}
247
-
href="#"
248
-
/>
249
246
) : undefined}
250
247
{post.embed ? (
251
248
<Embed
···
289
286
},
290
287
alert: {
291
288
marginBottom: 6,
292
-
},
293
-
postTextContainer: {
294
-
flexDirection: 'row',
295
-
alignItems: 'center',
296
-
flexWrap: 'wrap',
297
-
overflow: 'hidden',
298
289
},
299
290
replyLine: {
300
291
position: 'absolute',
+7
-20
src/view/com/posts/PostFeedItem.tsx
+7
-20
src/view/com/posts/PostFeedItem.tsx
···
41
41
setUnstablePostSource,
42
42
} from '#/state/unstable-post-source'
43
43
import {FeedNameText} from '#/view/com/util/FeedInfoText'
44
-
import {Link, TextLink, TextLinkOnWebOnly} from '#/view/com/util/Link'
44
+
import {Link, TextLinkOnWebOnly} from '#/view/com/util/Link'
45
45
import {PostMeta} from '#/view/com/util/PostMeta'
46
46
import {Text} from '#/view/com/util/text/Text'
47
47
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
···
54
54
import {type AppModerationCause} from '#/components/Pills'
55
55
import {Embed} from '#/components/Post/Embed'
56
56
import {PostEmbedViewContext} from '#/components/Post/Embed/types'
57
+
import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton'
57
58
import {PostControls} from '#/components/PostControls'
58
59
import {DiscoverDebug} from '#/components/PostControls/DiscoverDebug'
59
60
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
···
501
502
post: AppBskyFeedDefs.PostView
502
503
threadgateRecord?: AppBskyFeedThreadgate.Record
503
504
}): React.ReactNode => {
504
-
const pal = usePalette('default')
505
-
const {_} = useLingui()
506
505
const {currentAccount} = useSession()
507
506
const [limitLines, setLimitLines] = useState(
508
507
() => countLines(richText.text) >= MAX_POST_LINES,
···
547
546
additionalCauses={additionalPostAlerts}
548
547
/>
549
548
{richText.text ? (
550
-
<View style={styles.postTextContainer}>
549
+
<>
551
550
<RichText
552
551
enableTags
553
552
testID="postText"
···
557
556
authorHandle={postAuthor.handle}
558
557
shouldProxyLinks={true}
559
558
/>
560
-
</View>
561
-
) : undefined}
562
-
{limitLines ? (
563
-
<TextLink
564
-
text={_(msg`Show More`)}
565
-
style={pal.link}
566
-
onPress={onPressShowMore}
567
-
href="#"
568
-
/>
559
+
{limitLines && (
560
+
<ShowMoreTextButton style={[a.text_md]} onPress={onPressShowMore} />
561
+
)}
562
+
</>
569
563
) : undefined}
570
564
{postEmbed ? (
571
565
<View style={[a.pb_xs]}>
···
688
682
alert: {
689
683
marginTop: 6,
690
684
marginBottom: 6,
691
-
},
692
-
postTextContainer: {
693
-
flexDirection: 'row',
694
-
alignItems: 'center',
695
-
flexWrap: 'wrap',
696
-
paddingBottom: 2,
697
-
overflow: 'hidden',
698
685
},
699
686
contentHiderChild: {
700
687
marginTop: 6,