Handle manual quote embeds and disabled errors

This commit is contained in:
Eric Bailey
2024-08-13 16:52:23 -05:00
parent 61519a0beb
commit 728d7097ea
4 changed files with 61 additions and 14 deletions
+1
View File
@@ -0,0 +1 @@
export {TimesLarge_Stroke2_Corner0_Rounded as X_Stroke2_Corner0_Rounded} from './Times'
+8
View File
@@ -107,6 +107,11 @@ export async function extractBskyMeta(
return meta return meta
} }
export class EmbeddingDisabledError extends Error {
constructor() {
super('Embedding is disabled for this record')
}
}
export async function getPostAsQuote( export async function getPostAsQuote(
getPost: ReturnType<typeof useGetPost>, getPost: ReturnType<typeof useGetPost>,
url: string, url: string,
@@ -115,6 +120,9 @@ export async function getPostAsQuote(
const [_0, user, _1, rkey] = url.split('/').filter(Boolean) const [_0, user, _1, rkey] = url.split('/').filter(Boolean)
const uri = makeRecordUri(user, 'app.bsky.feed.post', rkey) const uri = makeRecordUri(user, 'app.bsky.feed.post', rkey)
const post = await getPost({uri: uri}) const post = await getPost({uri: uri})
if (post.viewer?.embeddingDisabled) {
throw new EmbeddingDisabledError()
}
return { return {
uri: post.uri, uri: post.uri,
cid: post.cid, cid: post.cid,
+38 -10
View File
@@ -83,9 +83,12 @@ import {State as VideoUploadState} from 'state/queries/video/video'
import {ComposerOpts} from 'state/shell/composer' import {ComposerOpts} from 'state/shell/composer'
import {ComposerReplyTo} from 'view/com/composer/ComposerReplyTo' import {ComposerReplyTo} from 'view/com/composer/ComposerReplyTo'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button' import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji' import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji'
import {X_Stroke2_Corner0_Rounded as X} from '#/components/icons/X'
import * as Prompt from '#/components/Prompt' import * as Prompt from '#/components/Prompt'
import {Text as NewText} from '#/components/Typography'
import {QuoteEmbed, QuoteX} from '../util/post-embeds/QuoteEmbed' import {QuoteEmbed, QuoteX} from '../util/post-embeds/QuoteEmbed'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
@@ -183,7 +186,7 @@ export const ComposePost = observer(function ComposePost({
}) })
const [publishOnUpload, setPublishOnUpload] = useState(false) const [publishOnUpload, setPublishOnUpload] = useState(false)
const {extLink, setExtLink} = useExternalLinkFetch({setQuote}) const {extLink, setExtLink} = useExternalLinkFetch({setQuote, setError})
const [extGif, setExtGif] = useState<Gif>() const [extGif, setExtGif] = useState<Gif>()
const [labels, setLabels] = useState<string[]>([]) const [labels, setLabels] = useState<string[]>([])
const [threadgateAllowUISettings, onChangeThreadgateAllowUISettings] = const [threadgateAllowUISettings, onChangeThreadgateAllowUISettings] =
@@ -572,15 +575,40 @@ export const ComposePost = observer(function ComposePost({
</View> </View>
)} )}
{error !== '' && ( {error !== '' && (
<View style={styles.errorLine}> <View style={[a.px_lg, a.pb_sm]}>
<View style={styles.errorIcon}> <View
<FontAwesomeIcon style={[
icon="exclamation" a.px_md,
style={{color: colors.red4}} a.py_sm,
size={10} a.rounded_sm,
/> a.flex_row,
a.gap_sm,
t.atoms.bg_contrast_25,
{
paddingRight: 48,
},
]}>
<CircleInfo fill={t.palette.negative_400} />
<NewText style={[a.leading_snug, {paddingTop: 1}]}>
{error}
</NewText>
<Button
label={_(msg`Dismiss error`)}
size="tiny"
color="secondary"
variant="ghost"
shape="round"
style={[
a.absolute,
{
top: a.py_sm.paddingTop,
right: a.px_md.paddingRight,
},
]}
onPress={() => setError('')}>
<ButtonIcon icon={X} />
</Button>
</View> </View>
<Text style={[s.red4, a.flex_1]}>{error}</Text>
</View> </View>
)} )}
</Animated.View> </Animated.View>
+11 -1
View File
@@ -1,4 +1,6 @@
import {useEffect, useState} from 'react' import {useEffect, useState} from 'react'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {logger} from '#/logger' import {logger} from '#/logger'
import {useFetchDid} from '#/state/queries/handle' import {useFetchDid} from '#/state/queries/handle'
@@ -7,6 +9,7 @@ import {useAgent} from '#/state/session'
import * as apilib from 'lib/api/index' import * as apilib from 'lib/api/index'
import {POST_IMG_MAX} from 'lib/constants' import {POST_IMG_MAX} from 'lib/constants'
import { import {
EmbeddingDisabledError,
getFeedAsEmbed, getFeedAsEmbed,
getListAsEmbed, getListAsEmbed,
getPostAsQuote, getPostAsQuote,
@@ -28,9 +31,12 @@ import {ComposerOpts} from 'state/shell/composer'
export function useExternalLinkFetch({ export function useExternalLinkFetch({
setQuote, setQuote,
setError,
}: { }: {
setQuote: (opts: ComposerOpts['quote']) => void setQuote: (opts: ComposerOpts['quote']) => void
setError: (err: string) => void
}) { }) {
const {_} = useLingui()
const [extLink, setExtLink] = useState<apilib.ExternalEmbedDraft | undefined>( const [extLink, setExtLink] = useState<apilib.ExternalEmbedDraft | undefined>(
undefined, undefined,
) )
@@ -57,9 +63,13 @@ export function useExternalLinkFetch({
setExtLink(undefined) setExtLink(undefined)
}, },
err => { err => {
if (err instanceof EmbeddingDisabledError) {
setError(_(msg`This post's author has disabled quote posts.`))
} else {
logger.error('Failed to fetch post for quote embedding', { logger.error('Failed to fetch post for quote embedding', {
message: err.toString(), message: err.toString(),
}) })
}
setExtLink(undefined) setExtLink(undefined)
}, },
) )
@@ -170,7 +180,7 @@ export function useExternalLinkFetch({
}) })
} }
return cleanup return cleanup
}, [extLink, setQuote, getPost, fetchDid, agent]) }, [_, extLink, setQuote, getPost, fetchDid, agent, setError])
return {extLink, setExtLink} return {extLink, setExtLink}
} }