[🐴] Rich text in messages (#3926)

* add facets to message

* richtext messages

* undo richtexttag changes

* whoops, don't redetect facets

* dont set color directly

* shorten links and filter invalid facets

* fix link shortening

* pass in underline style
This commit is contained in:
Samuel Newman 2024-05-09 21:08:56 +01:00 committed by GitHub
parent 03b2796976
commit becc708c61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 75 additions and 20 deletions

View file

@ -1,4 +1,5 @@
import React from 'react'
import {TextStyle} from 'react-native'
import {AppBskyRichtextFacet, RichText as RichTextAPI} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@ -26,6 +27,7 @@ export function RichText({
enableTags = false,
authorHandle,
onLinkPress,
interactiveStyle,
}: TextStyleProp &
Pick<TextProps, 'selectable'> & {
value: RichTextAPI | string
@ -35,13 +37,22 @@ export function RichText({
enableTags?: boolean
authorHandle?: string
onLinkPress?: LinkProps['onPress']
interactiveStyle?: TextStyle
}) {
const richText = React.useMemo(
() =>
value instanceof RichTextAPI ? value : new RichTextAPI({text: value}),
[value],
)
const styles = [a.leading_snug, flatten(style)]
const flattenedStyle = flatten(style)
const plainStyles = [a.leading_snug, flattenedStyle]
const interactiveStyles = [
a.leading_snug,
a.pointer_events_auto,
flatten(interactiveStyle),
flattenedStyle,
]
const {text, facets} = richText
@ -67,7 +78,7 @@ export function RichText({
<Text
selectable={selectable}
testID={testID}
style={styles}
style={plainStyles}
numberOfLines={numberOfLines}
// @ts-ignore web only -prf
dataSet={WORD_WRAP}>
@ -93,7 +104,7 @@ export function RichText({
<InlineLinkText
selectable={selectable}
to={`/profile/${mention.did}`}
style={[...styles, {pointerEvents: 'auto'}]}
style={interactiveStyles}
// @ts-ignore TODO
dataSet={WORD_WRAP}
onPress={onLinkPress}>
@ -110,7 +121,7 @@ export function RichText({
selectable={selectable}
key={key}
to={link.uri}
style={[...styles, {pointerEvents: 'auto'}]}
style={interactiveStyles}
// @ts-ignore TODO
dataSet={WORD_WRAP}
shareOnLongPress
@ -130,7 +141,7 @@ export function RichText({
key={key}
text={segment.text}
tag={tag.tag}
style={styles}
style={interactiveStyles}
selectable={selectable}
authorHandle={authorHandle}
/>,
@ -145,7 +156,7 @@ export function RichText({
<Text
selectable={selectable}
testID={testID}
style={styles}
style={plainStyles}
numberOfLines={numberOfLines}
// @ts-ignore web only -prf
dataSet={WORD_WRAP}>
@ -219,19 +230,16 @@ function RichTextTag({
onFocus={onFocus}
onBlur={onBlur}
style={[
style,
{
pointerEvents: 'auto',
color: t.palette.primary_500,
},
web({
cursor: 'pointer',
}),
{color: t.palette.primary_500},
(hovered || focused || pressed) && {
...web({outline: 0}),
textDecorationLine: 'underline',
textDecorationColor: t.palette.primary_500,
},
style,
]}>
{text}
</Text>