Add app.bsky.embed.gallery embed type support
Wires the new gallery embed (atproto PR #4827) through the display and compose pipelines while the lexicon is unpublished. Gallery posts render via the existing carousel for >4 items and grid for <=4. Compose now allows up to 10 images and auto-promotes images -> gallery above 4 (demotes back when count drops to <=4 so old clients still see legacy embeds when possible). Drafts persist as the new `embedGallery` field. Local shim types in `src/lib/api/gallery-embed-shim*.ts` mirror the lexicon shape; delete both files once @atproto/api ships the generated types.
This commit is contained in:
@@ -21,6 +21,7 @@ import {sha256} from 'js-sha256'
|
||||
import {CID} from 'multiformats/cid'
|
||||
import * as Hasher from 'multiformats/hashes/hasher'
|
||||
|
||||
import {type AppBskyEmbedGallery} from '#/lib/api/gallery-embed-shim'
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip'
|
||||
import {logger} from '#/logger'
|
||||
@@ -252,6 +253,7 @@ async function resolveEmbed(
|
||||
onStateChange: ((state: string) => void) | undefined,
|
||||
): Promise<
|
||||
| $Typed<AppBskyEmbedImages.Main>
|
||||
| $Typed<AppBskyEmbedGallery.Main>
|
||||
| $Typed<AppBskyEmbedVideo.Main>
|
||||
| $Typed<AppBskyEmbedExternal.Main>
|
||||
| $Typed<AppBskyEmbedRecord.Main>
|
||||
@@ -311,6 +313,7 @@ async function resolveMedia(
|
||||
): Promise<
|
||||
| $Typed<AppBskyEmbedExternal.Main>
|
||||
| $Typed<AppBskyEmbedImages.Main>
|
||||
| $Typed<AppBskyEmbedGallery.Main>
|
||||
| $Typed<AppBskyEmbedVideo.Main>
|
||||
| undefined
|
||||
> {
|
||||
@@ -338,6 +341,31 @@ async function resolveMedia(
|
||||
images,
|
||||
}
|
||||
}
|
||||
if (embedDraft.media?.type === 'gallery') {
|
||||
const imagesDraft = embedDraft.media.images
|
||||
logger.debug(`Uploading gallery items`, {
|
||||
count: imagesDraft.length,
|
||||
})
|
||||
onStateChange?.(t`Uploading images...`)
|
||||
const items: AppBskyEmbedGallery.Image[] = await Promise.all(
|
||||
imagesDraft.map(async (image, i) => {
|
||||
logger.debug(`Compressing gallery image #${i}`)
|
||||
const {path, width, height, mime} = await compressImage(image)
|
||||
logger.debug(`Uploading gallery image #${i}`)
|
||||
const res = await uploadBlob(agent, path, mime)
|
||||
return {
|
||||
$type: 'app.bsky.embed.gallery#image',
|
||||
image: res.data.blob,
|
||||
alt: image.alt,
|
||||
aspectRatio: {width, height},
|
||||
}
|
||||
}),
|
||||
)
|
||||
return {
|
||||
$type: 'app.bsky.embed.gallery',
|
||||
items,
|
||||
}
|
||||
}
|
||||
if (
|
||||
embedDraft.media?.type === 'video' &&
|
||||
embedDraft.media.video.status === 'done'
|
||||
|
||||
Reference in New Issue
Block a user