migrate link resolution to the appview and chat clients
`resolveLink` took an agent and used it for four appview reads plus the chat invite preview, so it now takes both clients as a `LinkResolvers` pair - the caller cannot know which branch a URL will take until it is parsed. That was the last DM_SERVICE_HEADERS site, so the constant is deleted. `resolveGif` never touched the agent at all (it is pure URL metadata work on what the picker already returned), so its parameter is dropped rather than replaced, along with the one on `fetchResolveGifQuery`. With the resolvers on clients, `apilib.post` loses the agent parameter the previous slice kept solely for them, and `composerStateToDraft` takes the resolver pair instead of minting a throwaway public agent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -97,8 +97,8 @@ import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
import {resolveLinkQueryOptions} from '#/state/queries/resolve-link'
|
||||
import {
|
||||
useAgent,
|
||||
useAppviewClient,
|
||||
useChatClient,
|
||||
usePdsClient,
|
||||
useSession,
|
||||
} from '#/state/session'
|
||||
@@ -280,8 +280,8 @@ export const ComposePost = ({
|
||||
const videoMaxDurationMs = allow10MinuteVideos
|
||||
? VIDEO_10_MINUTE_MAX_DURATION_MS
|
||||
: VIDEO_MAX_DURATION_MS
|
||||
const agent = useAgent()
|
||||
const client = useAppviewClient()
|
||||
const chatClient = useChatClient()
|
||||
const pdsClient = usePdsClient()
|
||||
const queryClient = useQueryClient()
|
||||
const currentDid = currentAccount!.did
|
||||
@@ -1003,7 +1003,7 @@ export const ComposePost = ({
|
||||
.map(post => post.embed.link!.uri)
|
||||
const linkQueries = useQueries({
|
||||
queries: linkUris.map(uri => ({
|
||||
...resolveLinkQueryOptions(agent, uri),
|
||||
...resolveLinkQueryOptions({appviewClient: client, chatClient}, uri),
|
||||
enabled: false,
|
||||
})),
|
||||
})
|
||||
@@ -1094,12 +1094,13 @@ export const ComposePost = ({
|
||||
try {
|
||||
logger.info(`composer: posting...`)
|
||||
postUri = (
|
||||
await apilib.post(agent, queryClient, {
|
||||
await apilib.post(queryClient, {
|
||||
thread: filteredThread,
|
||||
replyTo: replyTo?.uri,
|
||||
onStateChange: setPublishingStage,
|
||||
langs: currentLanguages,
|
||||
appviewClient: client,
|
||||
chatClient,
|
||||
pdsClient,
|
||||
})
|
||||
).uris[0]
|
||||
@@ -1294,8 +1295,8 @@ export const ComposePost = ({
|
||||
}, [
|
||||
l,
|
||||
ax,
|
||||
agent,
|
||||
client,
|
||||
chatClient,
|
||||
pdsClient,
|
||||
canPost,
|
||||
isPublishing,
|
||||
|
||||
@@ -5,14 +5,13 @@ import {AppBskyDraftDefs, AtUri} from '@atproto/api'
|
||||
import {RichText} from '@bsky.app/sdk/richtext'
|
||||
import {nanoid} from 'nanoid/non-secure'
|
||||
|
||||
import {resolveLink} from '#/lib/api/resolve'
|
||||
import {type LinkResolvers, resolveLink} from '#/lib/api/resolve'
|
||||
import {getDeviceName} from '#/lib/deviceName'
|
||||
import {getImageDim} from '#/lib/media/manip'
|
||||
import {mimeToExt} from '#/lib/media/video/util'
|
||||
import {shortenLinks} from '#/lib/strings/rich-text-manip'
|
||||
import {type ComposerImage} from '#/state/gallery'
|
||||
import {threadgateAllowUISettingToAllowRecordValue} from '#/state/queries/threadgate/util'
|
||||
import {createPublicAgent} from '#/state/session/bridge-agent'
|
||||
import {
|
||||
type ComposerState,
|
||||
type EmbedDraft,
|
||||
@@ -60,7 +59,10 @@ function parseVideoMimeType(localRefPath: string): string {
|
||||
* Convert ComposerState to server Draft format for saving.
|
||||
* Returns both the draft and a map of localRef paths to their source paths.
|
||||
*/
|
||||
export async function composerStateToDraft(state: ComposerState): Promise<{
|
||||
export async function composerStateToDraft(
|
||||
clients: LinkResolvers,
|
||||
state: ComposerState,
|
||||
): Promise<{
|
||||
draft: AppBskyDraftDefs.Draft
|
||||
localRefPaths: Map<string, string>
|
||||
}> {
|
||||
@@ -68,7 +70,7 @@ export async function composerStateToDraft(state: ComposerState): Promise<{
|
||||
|
||||
const posts: AppBskyDraftDefs.DraftPost[] = await Promise.all(
|
||||
state.thread.posts.map(post => {
|
||||
return postDraftToServerPost(post, localRefPaths)
|
||||
return postDraftToServerPost(clients, post, localRefPaths)
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -94,6 +96,7 @@ export async function composerStateToDraft(state: ComposerState): Promise<{
|
||||
* Convert a single PostDraft to server DraftPost format.
|
||||
*/
|
||||
async function postDraftToServerPost(
|
||||
clients: LinkResolvers,
|
||||
post: PostDraft,
|
||||
localRefPaths: Map<string, string>,
|
||||
): Promise<AppBskyDraftDefs.DraftPost> {
|
||||
@@ -138,10 +141,7 @@ async function postDraftToServerPost(
|
||||
|
||||
// Add quote record embed
|
||||
if (post.embed.quote) {
|
||||
const resolved = await resolveLink(
|
||||
createPublicAgent(),
|
||||
post.embed.quote.uri,
|
||||
)
|
||||
const resolved = await resolveLink(clients, post.embed.quote.uri)
|
||||
if (resolved && resolved.type === 'record') {
|
||||
draftPost.embedRecords = [
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {matchXrpcError} from '#/lib/xrpc-error'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
import {useAppviewClient, useChatClient} from '#/state/session'
|
||||
import {type ComposerState} from '#/view/com/composer/state/composer'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {getDeviceId} from '#/analytics/identifiers'
|
||||
@@ -121,6 +121,7 @@ export async function loadDraftMedia(draft: AppBskyDraftDefs.Draft): Promise<{
|
||||
*/
|
||||
export function useSaveDraftMutation() {
|
||||
const client = useAppviewClient()
|
||||
const chatClient = useChatClient()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
@@ -136,8 +137,10 @@ export function useSaveDraftMutation() {
|
||||
originalLocalRefs: Set<string> | undefined
|
||||
}> => {
|
||||
// Convert composer state to server draft format
|
||||
const {draft: apiDraft, localRefPaths} =
|
||||
await composerStateToDraft(composerState)
|
||||
const {draft: apiDraft, localRefPaths} = await composerStateToDraft(
|
||||
{appviewClient: client, chatClient},
|
||||
composerState,
|
||||
)
|
||||
/*
|
||||
* `composerStateToDraft` builds the draft against the `@atproto/api`
|
||||
* types, whose string fields are unbranded, so it is asserted once here
|
||||
|
||||
Reference in New Issue
Block a user