+29
-13
src/components/Post/Embed/index.tsx
+29
-13
src/components/Post/Embed/index.tsx
···
1
-
import React from 'react'
1
+
import {useCallback, useMemo} from 'react'
2
2
import {View} from 'react-native'
3
3
import {
4
4
type $Typed,
···
11
11
import {Trans} from '@lingui/macro'
12
12
import {useQueryClient} from '@tanstack/react-query'
13
13
14
-
import {usePalette} from '#/lib/hooks/usePalette'
15
14
import {makeProfileLink} from '#/lib/routes/links'
16
15
import {useModerationOpts} from '#/state/preferences/moderation-opts'
17
16
import {unstableCacheProfileView} from '#/state/queries/profile'
···
19
18
import {Link} from '#/view/com/util/Link'
20
19
import {PostMeta} from '#/view/com/util/PostMeta'
21
20
import {atoms as a, useTheme} from '#/alf'
21
+
import {useInteractionState} from '#/components/hooks/useInteractionState'
22
22
import {ContentHider} from '#/components/moderation/ContentHider'
23
23
import {PostAlerts} from '#/components/moderation/PostAlerts'
24
24
import {RichText} from '#/components/RichText'
···
232
232
viewContext?: QuoteEmbedViewContext
233
233
}) {
234
234
const moderationOpts = useModerationOpts()
235
-
const quote = React.useMemo<$Typed<AppBskyFeedDefs.PostView>>(
235
+
const quote = useMemo<$Typed<AppBskyFeedDefs.PostView>>(
236
236
() => ({
237
237
...embed.view,
238
238
$type: 'app.bsky.feed.defs#postView',
···
241
241
}),
242
242
[embed],
243
243
)
244
-
const moderation = React.useMemo(() => {
244
+
const moderation = useMemo(() => {
245
245
return moderationOpts ? moderatePost(quote, moderationOpts) : undefined
246
246
}, [quote, moderationOpts])
247
247
248
248
const t = useTheme()
249
249
const queryClient = useQueryClient()
250
-
const pal = usePalette('default')
251
250
const itemUrip = new AtUri(quote.uri)
252
251
const itemHref = makeProfileLink(quote.author, 'post', itemUrip.rkey)
253
252
const itemTitle = `Post by ${quote.author.handle}`
254
253
255
-
const richText = React.useMemo(() => {
254
+
const richText = useMemo(() => {
256
255
if (
257
256
!bsky.dangerousIsType<AppBskyFeedPost.Record>(
258
257
quote.record,
···
266
265
: undefined
267
266
}, [quote.record])
268
267
269
-
const onBeforePress = React.useCallback(() => {
268
+
const onBeforePress = useCallback(() => {
270
269
unstableCacheProfileView(queryClient, quote.author)
271
270
onOpen?.()
272
271
}, [queryClient, quote.author, onOpen])
273
272
274
-
const [hover, setHover] = React.useState(false)
273
+
const {
274
+
state: hover,
275
+
onIn: onPointerEnter,
276
+
onOut: onPointerLeave,
277
+
} = useInteractionState()
278
+
const {
279
+
state: pressed,
280
+
onIn: onPressIn,
281
+
onOut: onPressOut,
282
+
} = useInteractionState()
275
283
return (
276
284
<View
277
285
style={[a.mt_sm]}
278
-
onPointerEnter={() => setHover(true)}
279
-
onPointerLeave={() => setHover(false)}>
286
+
onPointerEnter={onPointerEnter}
287
+
onPointerLeave={onPointerLeave}>
280
288
<ContentHider
281
289
modui={moderation?.ui('contentList')}
282
290
style={[a.rounded_md, a.border, t.atoms.border_contrast_low, style]}
···
284
292
childContainerStyle={[a.pt_sm]}>
285
293
{({active}) => (
286
294
<>
287
-
{!active && <SubtleHover hover={hover} style={[a.rounded_md]} />}
295
+
{!active && (
296
+
<SubtleHover
297
+
native
298
+
hover={hover || pressed}
299
+
style={[a.rounded_md]}
300
+
/>
301
+
)}
288
302
<Link
289
303
style={[!active && a.p_md]}
290
-
hoverStyle={{borderColor: pal.colors.borderLinkHover}}
304
+
hoverStyle={t.atoms.border_contrast_high}
291
305
href={itemHref}
292
306
title={itemTitle}
293
-
onBeforePress={onBeforePress}>
307
+
onBeforePress={onBeforePress}
308
+
onPressIn={onPressIn}
309
+
onPressOut={onPressOut}>
294
310
<View pointerEvents="none">
295
311
<PostMeta
296
312
author={quote.author}