Resolve chat invites
This commit is contained in:
@@ -69,7 +69,7 @@ function makeStore() {
|
|||||||
return createThreadStore({
|
return createThreadStore({
|
||||||
agent,
|
agent,
|
||||||
__createId: makeIdGenerator(),
|
__createId: makeIdGenerator(),
|
||||||
__resolveLink: mockResolveLink as unknown as typeof resolveLink,
|
__resolveLink: mockResolveLink,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +118,13 @@ const externalLink: ResolvedLink = {
|
|||||||
thumb: undefined,
|
thumb: undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const chatInviteLink: ResolvedLink = {
|
||||||
|
type: 'chat-invite',
|
||||||
|
uri: 'https://bsky.app/messages/join/abc123',
|
||||||
|
code: 'abc123',
|
||||||
|
view: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
describe('addUri pre-classifies bsky post URLs to the quote slot', () => {
|
describe('addUri pre-classifies bsky post URLs to the quote slot', () => {
|
||||||
test('post URL → quote.pending → quote.resolved (with view)', async () => {
|
test('post URL → quote.pending → quote.resolved (with view)', async () => {
|
||||||
const d = deferred<ResolvedLink>()
|
const d = deferred<ResolvedLink>()
|
||||||
@@ -258,6 +265,19 @@ describe('addUri pre-classifies non-post URLs to the embed slot', () => {
|
|||||||
expect(embed.title).toBe('Example')
|
expect(embed.title).toBe('Example')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('chat-invite → embed["chat-invite"]', async () => {
|
||||||
|
const d = deferred<ResolvedLink>()
|
||||||
|
mockResolveLink.mockReturnValueOnce(d.promise)
|
||||||
|
const store = makeStore()
|
||||||
|
const root = rootId(store)
|
||||||
|
store.actions.addUri(root, EXTERNAL_URL)
|
||||||
|
d.resolve(chatInviteLink)
|
||||||
|
await flushPromises()
|
||||||
|
const embed = store.getState().posts[root].embed
|
||||||
|
if (embed?.state !== 'chat-invite') throw new Error('expected chat-invite')
|
||||||
|
expect(embed.code).toBe('abc123')
|
||||||
|
})
|
||||||
|
|
||||||
test('addUri is a no-op when embed has settled (resolved)', async () => {
|
test('addUri is a no-op when embed has settled (resolved)', async () => {
|
||||||
const d = deferred<ResolvedLink>()
|
const d = deferred<ResolvedLink>()
|
||||||
mockResolveLink.mockReturnValueOnce(d.promise)
|
mockResolveLink.mockReturnValueOnce(d.promise)
|
||||||
|
|||||||
@@ -608,6 +608,14 @@ export function createThreadStore(options: {
|
|||||||
thumb: link.thumb,
|
thumb: link.thumb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (link.type === 'chat-invite') {
|
||||||
|
return {
|
||||||
|
state: 'chat-invite',
|
||||||
|
uri: link.uri,
|
||||||
|
code: link.code,
|
||||||
|
view: link.view,
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (link.kind) {
|
switch (link.kind) {
|
||||||
case 'feed':
|
case 'feed':
|
||||||
return {state: 'feed', record: link.record, view: link.view}
|
return {state: 'feed', record: link.record, view: link.view}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
type AppBskyFeedDefs,
|
type AppBskyFeedDefs,
|
||||||
type AppBskyGraphDefs,
|
type AppBskyGraphDefs,
|
||||||
type BlobRef,
|
type BlobRef,
|
||||||
|
type ChatBskyGroupDefs,
|
||||||
type ComAtprotoRepoStrongRef,
|
type ComAtprotoRepoStrongRef,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
|
|
||||||
@@ -97,7 +98,8 @@ export type LinkResolutionFailureCode = 'embedding-disabled' | 'unknown'
|
|||||||
* `embedding-disabled`) `retry` is omitted so UI can detect that case and
|
* `embedding-disabled`) `retry` is omitted so UI can detect that case and
|
||||||
* surface a non-retryable message. The pending variant is set synchronously
|
* surface a non-retryable message. The pending variant is set synchronously
|
||||||
* by addUri while resolution is in flight; the resolved variants
|
* by addUri while resolution is in flight; the resolved variants
|
||||||
* (external/feed/list/starter-pack) land when the worker reports back.
|
* (external/feed/list/starter-pack/chat-invite) land when the worker
|
||||||
|
* reports back.
|
||||||
*
|
*
|
||||||
* Note: `retry` is a function reference and won't survive JSON serialization.
|
* Note: `retry` is a function reference and won't survive JSON serialization.
|
||||||
* On restore (OS-resume / draft load), the store re-attaches it.
|
* On restore (OS-resume / draft load), the store re-attaches it.
|
||||||
@@ -135,6 +137,12 @@ export type PostEmbed =
|
|||||||
record: ComAtprotoRepoStrongRef.Main
|
record: ComAtprotoRepoStrongRef.Main
|
||||||
view: AppBskyGraphDefs.StarterPackView
|
view: AppBskyGraphDefs.StarterPackView
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
state: 'chat-invite'
|
||||||
|
uri: string
|
||||||
|
code: string
|
||||||
|
view: ChatBskyGroupDefs.JoinLinkPreviewView | undefined
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What's stored on a post's `quote` field. Mirrors `PostEmbed`'s shape: the
|
* What's stored on a post's `quote` field. Mirrors `PostEmbed`'s shape: the
|
||||||
|
|||||||
Reference in New Issue
Block a user