From 761865454dc299c6d739de811cf007101f12f55e Mon Sep 17 00:00:00 2001 From: Chloe Date: Fri, 19 Sep 2025 23:09:17 +0500 Subject: [PATCH 1/2] fix(composer): handle empty quotes with reposts --- src/view/com/composer/Composer.tsx | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 2a9635402fb..56484959098 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -78,6 +78,7 @@ import {cleanError} from '#/lib/strings/errors' import {colors} from '#/lib/styles' import {logger} from '#/logger' import {isAndroid, isIOS, isNative, isWeb} from '#/platform/detection' +import {updatePostShadow} from '#/state/cache/post-shadow' import {useDialogStateControlContext} from '#/state/dialogs' import {emitPostCreated} from '#/state/events' import { @@ -386,6 +387,33 @@ export const ComposePost = ({ return } + if ( + initQuote && + thread.posts.length === 1 && + thread.posts[0].richtext.text.trim().length === 0 && + !thread.posts[0].embed.media && + !thread.posts[0].embed.link + ) { + setError('') + setIsPublishing(true) + try { + const {uri: repostUri} = await agent.repost( + initQuote.uri, + initQuote.cid, + ) + logEvent('post:repost', {logContext: 'Post'}) + updatePostShadow(queryClient, initQuote.uri, { + repostUri, + }) + onClose() + onPost?.(undefined) + } catch (e: any) { + setError(cleanError(e.message)) + setIsPublishing(false) + } + return + } + if (!canPost) { return } From 64186517ddda6eb6a275c8d37844cefb817caaba Mon Sep 17 00:00:00 2001 From: Chloe Date: Sat, 20 Sep 2025 00:27:17 +0500 Subject: [PATCH 2/2] chore(composer): also account for empty quotes with post links --- src/view/com/composer/Composer.tsx | 47 +++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 56484959098..81a513f6a56 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -57,7 +57,7 @@ import {useNavigation} from '@react-navigation/native' import {useQueryClient} from '@tanstack/react-query' import * as apilib from '#/lib/api/index' -import {EmbeddingDisabledError} from '#/lib/api/resolve' +import {EmbeddingDisabledError, type ResolvedLink} from '#/lib/api/resolve' import {retry} from '#/lib/async/retry' import {until} from '#/lib/async/until' import { @@ -95,6 +95,7 @@ import { } from '#/state/preferences/languages' import {usePreferencesQuery} from '#/state/queries/preferences' import {useProfileQuery} from '#/state/queries/profile' +import {RQKEY_LINK as RQKEY_EXTERNAL_LINK} from '#/state/queries/resolve-link' import {type Gif} from '#/state/queries/tenor' import {useAgent, useSession} from '#/state/session' import {useComposerControls} from '#/state/shell/composer' @@ -386,23 +387,53 @@ export const ComposePost = ({ if (isPublishing) { return } + const firstPost = thread.posts[0] + logger.info(`composer: publish pressed`, firstPost) + let quoteForRepost: {uri: string; cid: string} | undefined if ( - initQuote && + !replyTo && thread.posts.length === 1 && - thread.posts[0].richtext.text.trim().length === 0 && - !thread.posts[0].embed.media && - !thread.posts[0].embed.link + !firstPost.embed.media && + !firstPost.embed.link && + firstPost.embed.quote ) { + const quoteUri = firstPost.embed.quote.uri + const text = firstPost.richtext.text.trim() + + if (text.length === 0 || text === quoteUri) { + // it's an empty quote so we need to get the cid + if (initQuote?.uri === quoteUri) { + // case 1, user started with "quote post" button. we have the cid in initQuote + quoteForRepost = { + uri: initQuote.uri, + cid: initQuote.cid, + } + } else { + // case 2, user pasted a link of a post. we need to get post details from cache + const metadata = queryClient.getQueryData( + RQKEY_EXTERNAL_LINK(quoteUri), + ) + if (metadata?.type === 'record' && metadata.kind === 'post') { + quoteForRepost = { + uri: metadata.view.uri, + cid: metadata.view.cid, + } + } + } + } + } + + if (quoteForRepost) { setError('') setIsPublishing(true) try { const {uri: repostUri} = await agent.repost( - initQuote.uri, - initQuote.cid, + quoteForRepost.uri, + quoteForRepost.cid, ) logEvent('post:repost', {logContext: 'Post'}) - updatePostShadow(queryClient, initQuote.uri, { + updatePostShadow(queryClient, quoteForRepost.uri, { repostUri, }) onClose()