[Chat] Add chat invite as message embed type (#10728)
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyConvoGetLog,
|
||||
type ChatBskyConvoSendMessage,
|
||||
type ChatBskyEmbedJoinLink,
|
||||
type ChatBskyGroupDefs,
|
||||
} from '@atproto/api'
|
||||
import {XRPCError} from '@atproto/api'
|
||||
@@ -109,7 +110,9 @@ export class Convo {
|
||||
{
|
||||
id: string
|
||||
message: ChatBskyConvoSendMessage.InputSchema['message']
|
||||
optimisticEmbedView?: $Typed<AppBskyEmbedRecord.View>
|
||||
optimisticEmbedView?:
|
||||
| $Typed<AppBskyEmbedRecord.View>
|
||||
| $Typed<ChatBskyEmbedJoinLink.View>
|
||||
}
|
||||
> = new Map()
|
||||
private deletedMessages: Set<string> = new Set()
|
||||
@@ -942,7 +945,9 @@ export class Convo {
|
||||
|
||||
sendMessage(
|
||||
message: ChatBskyConvoSendMessage.InputSchema['message'],
|
||||
optimisticEmbedView?: $Typed<AppBskyEmbedRecord.View>,
|
||||
optimisticEmbedView?:
|
||||
| $Typed<AppBskyEmbedRecord.View>
|
||||
| $Typed<ChatBskyEmbedJoinLink.View>,
|
||||
) {
|
||||
// Ignore empty messages for now since they have no other purpose atm
|
||||
if (!message.text.trim() && !message.embed) return
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
type ChatBskyActorDefs,
|
||||
type ChatBskyConvoDefs,
|
||||
type ChatBskyConvoSendMessage,
|
||||
type ChatBskyEmbedJoinLink,
|
||||
} from '@atproto/api'
|
||||
|
||||
import {type MessagesEventBus} from '#/state/messages/events/agent'
|
||||
@@ -108,7 +109,10 @@ export type ConvoItem =
|
||||
type DeleteMessage = (messageId: string) => Promise<void>
|
||||
type SendMessage = (
|
||||
message: ChatBskyConvoSendMessage.InputSchema['message'],
|
||||
optimisticEmbedView: $Typed<AppBskyEmbedRecord.View> | undefined,
|
||||
optimisticEmbedView:
|
||||
| $Typed<AppBskyEmbedRecord.View>
|
||||
| $Typed<ChatBskyEmbedJoinLink.View>
|
||||
| undefined,
|
||||
) => void
|
||||
type FetchMessageHistory = () => Promise<void>
|
||||
type MarkConvoAccepted = () => void
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import {AtpAgent} from '@atproto/api'
|
||||
import {useCallback} from 'react'
|
||||
import {
|
||||
AtpAgent,
|
||||
type ChatBskyGroupDefs,
|
||||
type ChatBskyGroupGetJoinLinkPreviews,
|
||||
} from '@atproto/api'
|
||||
import {useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {CHAT_SERVICE, DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
@@ -17,14 +22,39 @@ export const createJoinLinkPreviewQueryKey = (args: {
|
||||
persistedVersion: 1,
|
||||
})
|
||||
|
||||
async function fetchJoinLinkPreviews({
|
||||
agent,
|
||||
codes,
|
||||
hasSession,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
codes: string[]
|
||||
hasSession: boolean
|
||||
}) {
|
||||
const previewAgent = new AtpAgent({service: CHAT_SERVICE})
|
||||
const res = hasSession
|
||||
? await agent.chat.bsky.group.getJoinLinkPreviews(
|
||||
{codes},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
: await previewAgent.chat.bsky.group.getJoinLinkPreviews({codes})
|
||||
return res.data
|
||||
}
|
||||
|
||||
export function useJoinLinkPreviewsQuery({
|
||||
codes,
|
||||
hasSession,
|
||||
staleTime = STALE.MINUTES.ONE,
|
||||
initialData,
|
||||
}: {
|
||||
codes?: string[]
|
||||
hasSession: boolean
|
||||
staleTime?: number
|
||||
/**
|
||||
* Seed the query with an already-known preview (e.g. a DM message embed
|
||||
* already carries the resolved view), avoiding a duplicate fetch.
|
||||
*/
|
||||
initialData?: ChatBskyGroupGetJoinLinkPreviews.OutputSchema
|
||||
}) {
|
||||
const agent = useAgent()
|
||||
|
||||
@@ -33,14 +63,7 @@ export function useJoinLinkPreviewsQuery({
|
||||
queryFn: async () => {
|
||||
if (!codes) throw new Error('No invite code')
|
||||
try {
|
||||
const previewAgent = new AtpAgent({service: CHAT_SERVICE})
|
||||
const res = hasSession
|
||||
? await agent.chat.bsky.group.getJoinLinkPreviews(
|
||||
{codes},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
: await previewAgent.chat.bsky.group.getJoinLinkPreviews({codes})
|
||||
return res.data
|
||||
return await fetchJoinLinkPreviews({agent, codes, hasSession})
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch join link preview', {safeMessage: error})
|
||||
throw error
|
||||
@@ -48,6 +71,7 @@ export function useJoinLinkPreviewsQuery({
|
||||
},
|
||||
enabled: codes != null && codes.length > 0,
|
||||
staleTime,
|
||||
initialData,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -58,17 +82,42 @@ export function usePrefetchJoinLinkPreviews() {
|
||||
return ({codes, hasSession}: {codes: string[]; hasSession: boolean}) => {
|
||||
return queryClient.prefetchQuery({
|
||||
queryKey: createJoinLinkPreviewQueryKey({codes, hasSession}),
|
||||
queryFn: async () => {
|
||||
const previewAgent = new AtpAgent({service: CHAT_SERVICE})
|
||||
const res = hasSession
|
||||
? await agent.chat.bsky.group.getJoinLinkPreviews(
|
||||
{codes},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
: await previewAgent.chat.bsky.group.getJoinLinkPreviews({codes})
|
||||
return res.data
|
||||
},
|
||||
queryFn: () => fetchJoinLinkPreviews({agent, codes, hasSession}),
|
||||
staleTime: STALE.MINUTES.ONE,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imperatively fetch (or read from cache) a single join link preview by code.
|
||||
* Used when sending a DM invite embed so we can build an optimistic view.
|
||||
* Returns undefined if the preview can't be resolved.
|
||||
*/
|
||||
export function useGetJoinLinkPreview() {
|
||||
const agent = useAgent()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useCallback(
|
||||
async ({
|
||||
code,
|
||||
hasSession,
|
||||
}: {
|
||||
code: string
|
||||
hasSession: boolean
|
||||
}): Promise<ChatBskyGroupDefs.JoinLinkPreviewView | undefined> => {
|
||||
try {
|
||||
const data = await queryClient.fetchQuery({
|
||||
queryKey: createJoinLinkPreviewQueryKey({codes: [code], hasSession}),
|
||||
queryFn: () =>
|
||||
fetchJoinLinkPreviews({agent, codes: [code], hasSession}),
|
||||
staleTime: STALE.MINUTES.ONE,
|
||||
})
|
||||
return data.joinLinkPreviews[0]
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch join link preview', {safeMessage: error})
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
[agent, queryClient],
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user