[🐴] Record message (#4230)
* send record via link in text * re-trim text after removing link * record message * only show copy text if message + add translate * reduce padding * adjust padding * Tweak spacing * Stop clickthrough for hidden content * Update bg to show labels --------- Co-authored-by: Eric Bailey <git@esb.lol>zio/stable
parent
8eb3cebb36
commit
22e1eb18c8
|
@ -6,7 +6,11 @@ import {
|
||||||
TextStyle,
|
TextStyle,
|
||||||
View,
|
View,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {ChatBskyConvoDefs, RichText as RichTextAPI} from '@atproto/api'
|
import {
|
||||||
|
AppBskyEmbedRecord,
|
||||||
|
ChatBskyConvoDefs,
|
||||||
|
RichText as RichTextAPI,
|
||||||
|
} from '@atproto/api'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
@ -18,6 +22,7 @@ import {ActionsWrapper} from '#/components/dms/ActionsWrapper'
|
||||||
import {InlineLinkText} from '#/components/Link'
|
import {InlineLinkText} from '#/components/Link'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {RichText} from '../RichText'
|
import {RichText} from '../RichText'
|
||||||
|
import {MessageItemEmbed} from './MessageItemEmbed'
|
||||||
|
|
||||||
let MessageItem = ({
|
let MessageItem = ({
|
||||||
item,
|
item,
|
||||||
|
@ -77,37 +82,44 @@ let MessageItem = ({
|
||||||
return (
|
return (
|
||||||
<View style={[isFromSelf ? a.mr_md : a.ml_md]}>
|
<View style={[isFromSelf ? a.mr_md : a.ml_md]}>
|
||||||
<ActionsWrapper isFromSelf={isFromSelf} message={message}>
|
<ActionsWrapper isFromSelf={isFromSelf} message={message}>
|
||||||
<View
|
{AppBskyEmbedRecord.isMain(message.embed) && (
|
||||||
style={[
|
<MessageItemEmbed embed={message.embed} />
|
||||||
a.py_sm,
|
)}
|
||||||
a.my_2xs,
|
{rt.text.length > 0 && (
|
||||||
a.rounded_md,
|
<View
|
||||||
{
|
|
||||||
paddingLeft: 14,
|
|
||||||
paddingRight: 14,
|
|
||||||
backgroundColor: isFromSelf
|
|
||||||
? isPending
|
|
||||||
? pendingColor
|
|
||||||
: t.palette.primary_500
|
|
||||||
: t.palette.contrast_50,
|
|
||||||
borderRadius: 17,
|
|
||||||
},
|
|
||||||
isFromSelf
|
|
||||||
? {borderBottomRightRadius: isLastInGroup ? 2 : 17}
|
|
||||||
: {borderBottomLeftRadius: isLastInGroup ? 2 : 17},
|
|
||||||
]}>
|
|
||||||
<RichText
|
|
||||||
value={rt}
|
|
||||||
style={[
|
style={[
|
||||||
a.text_md,
|
a.py_sm,
|
||||||
a.leading_snug,
|
a.my_2xs,
|
||||||
isFromSelf && {color: t.palette.white},
|
a.rounded_md,
|
||||||
isPending && t.name !== 'light' && {color: t.palette.primary_300},
|
{
|
||||||
]}
|
paddingLeft: 14,
|
||||||
interactiveStyle={a.underline}
|
paddingRight: 14,
|
||||||
enableTags
|
backgroundColor: isFromSelf
|
||||||
/>
|
? isPending
|
||||||
</View>
|
? pendingColor
|
||||||
|
: t.palette.primary_500
|
||||||
|
: t.palette.contrast_50,
|
||||||
|
borderRadius: 17,
|
||||||
|
},
|
||||||
|
isFromSelf ? a.self_end : a.self_start,
|
||||||
|
isFromSelf
|
||||||
|
? {borderBottomRightRadius: isLastInGroup ? 2 : 17}
|
||||||
|
: {borderBottomLeftRadius: isLastInGroup ? 2 : 17},
|
||||||
|
]}>
|
||||||
|
<RichText
|
||||||
|
value={rt}
|
||||||
|
style={[
|
||||||
|
a.text_md,
|
||||||
|
a.leading_snug,
|
||||||
|
isFromSelf && {color: t.palette.white},
|
||||||
|
isPending &&
|
||||||
|
t.name !== 'light' && {color: t.palette.primary_300},
|
||||||
|
]}
|
||||||
|
interactiveStyle={a.underline}
|
||||||
|
enableTags
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</ActionsWrapper>
|
</ActionsWrapper>
|
||||||
|
|
||||||
{isLastInGroup && (
|
{isLastInGroup && (
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
import React, {useMemo} from 'react'
|
||||||
|
import {View} from 'react-native'
|
||||||
|
import {
|
||||||
|
AppBskyEmbedRecord,
|
||||||
|
AppBskyFeedPost,
|
||||||
|
AtUri,
|
||||||
|
RichText as RichTextAPI,
|
||||||
|
} from '@atproto/api'
|
||||||
|
|
||||||
|
import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
|
||||||
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
|
import {usePostQuery} from '#/state/queries/post'
|
||||||
|
import {PostEmbeds} from '#/view/com/util/post-embeds'
|
||||||
|
import {PostMeta} from '#/view/com/util/PostMeta'
|
||||||
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
import {Link} from '#/components/Link'
|
||||||
|
import {ContentHider} from '#/components/moderation/ContentHider'
|
||||||
|
import {PostAlerts} from '#/components/moderation/PostAlerts'
|
||||||
|
import {RichText} from '#/components/RichText'
|
||||||
|
|
||||||
|
let MessageItemEmbed = ({
|
||||||
|
embed,
|
||||||
|
}: {
|
||||||
|
embed: AppBskyEmbedRecord.Main
|
||||||
|
}): React.ReactNode => {
|
||||||
|
const t = useTheme()
|
||||||
|
const {data: post} = usePostQuery(embed.record.uri)
|
||||||
|
|
||||||
|
const moderationOpts = useModerationOpts()
|
||||||
|
const moderation = useMemo(
|
||||||
|
() =>
|
||||||
|
moderationOpts && post ? moderatePost(post, moderationOpts) : undefined,
|
||||||
|
[moderationOpts, post],
|
||||||
|
)
|
||||||
|
|
||||||
|
const {rt, record} = useMemo(() => {
|
||||||
|
if (
|
||||||
|
post &&
|
||||||
|
AppBskyFeedPost.isRecord(post.record) &&
|
||||||
|
AppBskyFeedPost.validateRecord(post.record).success
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
rt: new RichTextAPI({
|
||||||
|
text: post.record.text,
|
||||||
|
facets: post.record.facets,
|
||||||
|
}),
|
||||||
|
record: post.record,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {rt: undefined, record: undefined}
|
||||||
|
}, [post])
|
||||||
|
|
||||||
|
if (!post || !moderation || !rt || !record) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemUrip = new AtUri(post.uri)
|
||||||
|
const itemHref = makeProfileLink(post.author, 'post', itemUrip.rkey)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link to={itemHref}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.w_full,
|
||||||
|
t.atoms.bg,
|
||||||
|
t.atoms.border_contrast_low,
|
||||||
|
a.rounded_md,
|
||||||
|
a.border,
|
||||||
|
a.p_md,
|
||||||
|
a.my_xs,
|
||||||
|
]}>
|
||||||
|
<PostMeta
|
||||||
|
showAvatar
|
||||||
|
author={post.author}
|
||||||
|
moderation={moderation}
|
||||||
|
authorHasWarning={!!post.author.labels?.length}
|
||||||
|
timestamp={post.indexedAt}
|
||||||
|
postHref={itemHref}
|
||||||
|
/>
|
||||||
|
<ContentHider modui={moderation.ui('contentView')}>
|
||||||
|
<PostAlerts modui={moderation.ui('contentView')} style={a.py_xs} />
|
||||||
|
{rt.text && (
|
||||||
|
<View style={a.mt_xs}>
|
||||||
|
<RichText
|
||||||
|
enableTags
|
||||||
|
testID="postText"
|
||||||
|
value={rt}
|
||||||
|
style={[a.text_sm, t.atoms.text_contrast_high]}
|
||||||
|
authorHandle={post.author.handle}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
{post.embed && (
|
||||||
|
<PostEmbeds
|
||||||
|
embed={post.embed}
|
||||||
|
moderation={moderation}
|
||||||
|
style={a.mt_xs}
|
||||||
|
quoteTextStyle={[a.text_sm, t.atoms.text_contrast_high]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</ContentHider>
|
||||||
|
</View>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
MessageItemEmbed = React.memo(MessageItemEmbed)
|
||||||
|
export {MessageItemEmbed}
|
|
@ -6,12 +6,16 @@ import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||||
|
import {getTranslatorLink} from '#/locale/helpers'
|
||||||
|
import {useLanguagePrefs} from '#/state/preferences'
|
||||||
|
import {useOpenLink} from '#/state/preferences/in-app-browser'
|
||||||
import {isWeb} from 'platform/detection'
|
import {isWeb} from 'platform/detection'
|
||||||
import {useConvoActive} from 'state/messages/convo'
|
import {useConvoActive} from 'state/messages/convo'
|
||||||
import {useSession} from 'state/session'
|
import {useSession} from 'state/session'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {ReportDialog} from '#/components/dms/ReportDialog'
|
import {ReportDialog} from '#/components/dms/ReportDialog'
|
||||||
|
import {BubbleQuestion_Stroke2_Corner0_Rounded as Translate} from '#/components/icons/Bubble'
|
||||||
import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
|
import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
|
||||||
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
|
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
|
||||||
import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
|
import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
|
||||||
|
@ -35,10 +39,12 @@ export let MessageMenu = ({
|
||||||
const convo = useConvoActive()
|
const convo = useConvoActive()
|
||||||
const deleteControl = usePromptControl()
|
const deleteControl = usePromptControl()
|
||||||
const reportControl = usePromptControl()
|
const reportControl = usePromptControl()
|
||||||
|
const langPrefs = useLanguagePrefs()
|
||||||
|
const openLink = useOpenLink()
|
||||||
|
|
||||||
const isFromSelf = message.sender?.did === currentAccount?.did
|
const isFromSelf = message.sender?.did === currentAccount?.did
|
||||||
|
|
||||||
const onCopyPostText = React.useCallback(() => {
|
const onCopyMessage = React.useCallback(() => {
|
||||||
const str = richTextToString(
|
const str = richTextToString(
|
||||||
new RichText({
|
new RichText({
|
||||||
text: message.text,
|
text: message.text,
|
||||||
|
@ -51,6 +57,14 @@ export let MessageMenu = ({
|
||||||
Toast.show(_(msg`Copied to clipboard`))
|
Toast.show(_(msg`Copied to clipboard`))
|
||||||
}, [_, message.text, message.facets])
|
}, [_, message.text, message.facets])
|
||||||
|
|
||||||
|
const onPressTranslateMessage = React.useCallback(() => {
|
||||||
|
const translatorUrl = getTranslatorLink(
|
||||||
|
message.text,
|
||||||
|
langPrefs.primaryLanguage,
|
||||||
|
)
|
||||||
|
openLink(translatorUrl)
|
||||||
|
}, [langPrefs.primaryLanguage, message.text, openLink])
|
||||||
|
|
||||||
const onDelete = React.useCallback(() => {
|
const onDelete = React.useCallback(() => {
|
||||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
|
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
|
||||||
convo
|
convo
|
||||||
|
@ -81,16 +95,27 @@ export let MessageMenu = ({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Menu.Outer>
|
<Menu.Outer>
|
||||||
<Menu.Group>
|
{message.text.length > 0 && (
|
||||||
<Menu.Item
|
<>
|
||||||
testID="messageDropdownCopyBtn"
|
<Menu.Group>
|
||||||
label={_(msg`Copy message text`)}
|
<Menu.Item
|
||||||
onPress={onCopyPostText}>
|
testID="messageDropdownTranslateBtn"
|
||||||
<Menu.ItemText>{_(msg`Copy message text`)}</Menu.ItemText>
|
label={_(msg`Translate`)}
|
||||||
<Menu.ItemIcon icon={ClipboardIcon} position="right" />
|
onPress={onPressTranslateMessage}>
|
||||||
</Menu.Item>
|
<Menu.ItemText>{_(msg`Translate`)}</Menu.ItemText>
|
||||||
</Menu.Group>
|
<Menu.ItemIcon icon={Translate} position="right" />
|
||||||
<Menu.Divider />
|
</Menu.Item>
|
||||||
|
<Menu.Item
|
||||||
|
testID="messageDropdownCopyBtn"
|
||||||
|
label={_(msg`Copy message text`)}
|
||||||
|
onPress={onCopyMessage}>
|
||||||
|
<Menu.ItemText>{_(msg`Copy message text`)}</Menu.ItemText>
|
||||||
|
<Menu.ItemIcon icon={ClipboardIcon} position="right" />
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.Group>
|
||||||
|
<Menu.Divider />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Menu.Group>
|
<Menu.Group>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
testID="messageDropdownDeleteBtn"
|
testID="messageDropdownDeleteBtn"
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
||||||
import {ModerationUI} from '@atproto/api'
|
import {ModerationUI} from '@atproto/api'
|
||||||
import {useLingui} from '@lingui/react'
|
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
|
||||||
import {isJustAMute} from '#/lib/moderation'
|
import {isJustAMute} from '#/lib/moderation'
|
||||||
|
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
|
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||||
import {atoms as a, useTheme, useBreakpoints, web} from '#/alf'
|
|
||||||
import {Button} from '#/components/Button'
|
import {Button} from '#/components/Button'
|
||||||
import {Text} from '#/components/Typography'
|
|
||||||
import {
|
import {
|
||||||
ModerationDetailsDialog,
|
ModerationDetailsDialog,
|
||||||
useModerationDetailsDialogControl,
|
useModerationDetailsDialogControl,
|
||||||
} from '#/components/moderation/ModerationDetailsDialog'
|
} from '#/components/moderation/ModerationDetailsDialog'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
export function ContentHider({
|
export function ContentHider({
|
||||||
testID,
|
testID,
|
||||||
|
@ -52,7 +51,9 @@ export function ContentHider({
|
||||||
<ModerationDetailsDialog control={control} modcause={blur} />
|
<ModerationDetailsDialog control={control} modcause={blur} />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onPress={() => {
|
onPress={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
if (!modui.noOverride) {
|
if (!modui.noOverride) {
|
||||||
setOverride(v => !v)
|
setOverride(v => !v)
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,7 +122,9 @@ export function ContentHider({
|
||||||
|
|
||||||
{desc.source && blur.type === 'label' && !override && (
|
{desc.source && blur.type === 'label' && !override && (
|
||||||
<Button
|
<Button
|
||||||
onPress={() => {
|
onPress={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
control.open()
|
control.open()
|
||||||
}}
|
}}
|
||||||
label={_(
|
label={_(
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
||||||
import {
|
import {
|
||||||
StyleProp,
|
StyleProp,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
|
TextStyle,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
|
@ -31,7 +32,7 @@ import {InfoCircleIcon} from 'lib/icons'
|
||||||
import {makeProfileLink} from 'lib/routes/links'
|
import {makeProfileLink} from 'lib/routes/links'
|
||||||
import {precacheProfile} from 'state/queries/profile'
|
import {precacheProfile} from 'state/queries/profile'
|
||||||
import {ComposerOptsQuote} from 'state/shell/composer'
|
import {ComposerOptsQuote} from 'state/shell/composer'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a, flatten} from '#/alf'
|
||||||
import {RichText} from '#/components/RichText'
|
import {RichText} from '#/components/RichText'
|
||||||
import {ContentHider} from '../../../../components/moderation/ContentHider'
|
import {ContentHider} from '../../../../components/moderation/ContentHider'
|
||||||
import {PostAlerts} from '../../../../components/moderation/PostAlerts'
|
import {PostAlerts} from '../../../../components/moderation/PostAlerts'
|
||||||
|
@ -45,10 +46,12 @@ export function MaybeQuoteEmbed({
|
||||||
embed,
|
embed,
|
||||||
onOpen,
|
onOpen,
|
||||||
style,
|
style,
|
||||||
|
textStyle,
|
||||||
}: {
|
}: {
|
||||||
embed: AppBskyEmbedRecord.View
|
embed: AppBskyEmbedRecord.View
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
|
textStyle?: StyleProp<TextStyle>
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
if (
|
if (
|
||||||
|
@ -62,6 +65,7 @@ export function MaybeQuoteEmbed({
|
||||||
postRecord={embed.record.value}
|
postRecord={embed.record.value}
|
||||||
onOpen={onOpen}
|
onOpen={onOpen}
|
||||||
style={style}
|
style={style}
|
||||||
|
textStyle={textStyle}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
} else if (AppBskyEmbedRecord.isViewBlocked(embed.record)) {
|
} else if (AppBskyEmbedRecord.isViewBlocked(embed.record)) {
|
||||||
|
@ -91,11 +95,13 @@ function QuoteEmbedModerated({
|
||||||
postRecord,
|
postRecord,
|
||||||
onOpen,
|
onOpen,
|
||||||
style,
|
style,
|
||||||
|
textStyle,
|
||||||
}: {
|
}: {
|
||||||
viewRecord: AppBskyEmbedRecord.ViewRecord
|
viewRecord: AppBskyEmbedRecord.ViewRecord
|
||||||
postRecord: AppBskyFeedPost.Record
|
postRecord: AppBskyFeedPost.Record
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
|
textStyle?: StyleProp<TextStyle>
|
||||||
}) {
|
}) {
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const moderation = React.useMemo(() => {
|
const moderation = React.useMemo(() => {
|
||||||
|
@ -120,6 +126,7 @@ function QuoteEmbedModerated({
|
||||||
moderation={moderation}
|
moderation={moderation}
|
||||||
onOpen={onOpen}
|
onOpen={onOpen}
|
||||||
style={style}
|
style={style}
|
||||||
|
textStyle={textStyle}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -129,11 +136,13 @@ export function QuoteEmbed({
|
||||||
moderation,
|
moderation,
|
||||||
onOpen,
|
onOpen,
|
||||||
style,
|
style,
|
||||||
|
textStyle,
|
||||||
}: {
|
}: {
|
||||||
quote: ComposerOptsQuote
|
quote: ComposerOptsQuote
|
||||||
moderation?: ModerationDecision
|
moderation?: ModerationDecision
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
|
textStyle?: StyleProp<TextStyle>
|
||||||
}) {
|
}) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
@ -192,7 +201,7 @@ export function QuoteEmbed({
|
||||||
{richText ? (
|
{richText ? (
|
||||||
<RichText
|
<RichText
|
||||||
value={richText}
|
value={richText}
|
||||||
style={[a.text_md]}
|
style={[a.text_md, flatten(textStyle)]}
|
||||||
numberOfLines={20}
|
numberOfLines={20}
|
||||||
disableLinks
|
disableLinks
|
||||||
/>
|
/>
|
||||||
|
@ -250,11 +259,6 @@ const styles = StyleSheet.create({
|
||||||
paddingHorizontal: 12,
|
paddingHorizontal: 12,
|
||||||
borderWidth: hairlineWidth,
|
borderWidth: hairlineWidth,
|
||||||
},
|
},
|
||||||
quotePost: {
|
|
||||||
flex: 1,
|
|
||||||
paddingLeft: 13,
|
|
||||||
paddingRight: 8,
|
|
||||||
},
|
|
||||||
errorContainer: {
|
errorContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
StyleProp,
|
StyleProp,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
|
TextStyle,
|
||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
@ -41,11 +42,13 @@ export function PostEmbeds({
|
||||||
moderation,
|
moderation,
|
||||||
onOpen,
|
onOpen,
|
||||||
style,
|
style,
|
||||||
|
quoteTextStyle,
|
||||||
}: {
|
}: {
|
||||||
embed?: Embed
|
embed?: Embed
|
||||||
moderation?: ModerationDecision
|
moderation?: ModerationDecision
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
|
quoteTextStyle?: StyleProp<TextStyle>
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const {openLightbox} = useLightboxControls()
|
const {openLightbox} = useLightboxControls()
|
||||||
|
@ -60,7 +63,11 @@ export function PostEmbeds({
|
||||||
moderation={moderation}
|
moderation={moderation}
|
||||||
onOpen={onOpen}
|
onOpen={onOpen}
|
||||||
/>
|
/>
|
||||||
<MaybeQuoteEmbed embed={embed.record} onOpen={onOpen} />
|
<MaybeQuoteEmbed
|
||||||
|
embed={embed.record}
|
||||||
|
onOpen={onOpen}
|
||||||
|
textStyle={quoteTextStyle}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -87,7 +94,14 @@ export function PostEmbeds({
|
||||||
|
|
||||||
// quote post
|
// quote post
|
||||||
// =
|
// =
|
||||||
return <MaybeQuoteEmbed embed={embed} style={style} onOpen={onOpen} />
|
return (
|
||||||
|
<MaybeQuoteEmbed
|
||||||
|
embed={embed}
|
||||||
|
style={style}
|
||||||
|
textStyle={quoteTextStyle}
|
||||||
|
onOpen={onOpen}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// image embed
|
// image embed
|
||||||
|
|
Loading…
Reference in New Issue