diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-01-18 18:14:46 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-18 18:14:46 -0600 |
commit | 6588961d2e075ed047857d71346e3a63282ee58f (patch) | |
tree | 54c75536bb623ccc14d26f9a12e0e42c9dd481b9 /src/state/lib/api.ts | |
parent | 27ee550d15321b17200f844038e8d6e0a8975139 (diff) | |
download | voidsky-6588961d2e075ed047857d71346e3a63282ee58f.tar.zst |
Update composer to preview external link cards (#52)
* Fetch external link metadata during compose so the user can preview and remove the embed * Add missing mocks * Update tests to match recent changes
Diffstat (limited to 'src/state/lib/api.ts')
-rw-r--r-- | src/state/lib/api.ts | 110 |
1 files changed, 50 insertions, 60 deletions
diff --git a/src/state/lib/api.ts b/src/state/lib/api.ts index fd020aeee..1dfbf5090 100644 --- a/src/state/lib/api.ts +++ b/src/state/lib/api.ts @@ -15,7 +15,13 @@ import {RootStoreModel} from '../models/root-store' import {extractEntities} from '../../lib/strings' import {isNetworkError} from '../../lib/errors' import {downloadAndResize} from '../../lib/images' -import {getLikelyType, LikelyType, getLinkMeta} from '../../lib/link-meta' +import { + getLikelyType, + LikelyType, + getLinkMeta, + LinkMeta, +} from '../../lib/link-meta' +import {Image} from '../../lib/images' const TIMEOUT = 10e3 // 10s @@ -23,10 +29,18 @@ export function doPolyfill() { AtpApi.xrpc.fetch = fetchHandler } +export interface ExternalEmbedDraft { + uri: string + isLoading: boolean + meta?: LinkMeta + localThumb?: Image +} + export async function post( store: RootStoreModel, text: string, replyTo?: string, + extLink?: ExternalEmbedDraft, images?: string[], knownHandles?: Set<string>, onStateChange?: (state: string) => void, @@ -67,68 +81,44 @@ export async function post( } } - if (!embed && entities) { - const link = entities.find( - ent => - ent.type === 'link' && - getLikelyType(ent.value || '') === LikelyType.HTML, - ) - if (link) { - try { - onStateChange?.(`Fetching link metadata...`) - let thumb - const linkMeta = await getLinkMeta(link.value) - if (linkMeta.image) { - onStateChange?.(`Downloading link thumbnail...`) - const thumbLocal = await downloadAndResize({ - uri: linkMeta.image, - width: 250, - height: 250, - mode: 'contain', - maxSize: 100000, - timeout: 15e3, - }).catch(() => undefined) - if (thumbLocal) { - onStateChange?.(`Uploading link thumbnail...`) - let encoding - if (thumbLocal.uri.endsWith('.png')) { - encoding = 'image/png' - } else if ( - thumbLocal.uri.endsWith('.jpeg') || - thumbLocal.uri.endsWith('.jpg') - ) { - encoding = 'image/jpeg' - } else { - store.log.warn( - 'Unexpected image format for thumbnail, skipping', - thumbLocal.uri, - ) - } - if (encoding) { - const thumbUploadRes = await store.api.com.atproto.blob.upload( - thumbLocal.uri, // this will be special-cased by the fetch monkeypatch in /src/state/lib/api.ts - {encoding}, - ) - thumb = { - cid: thumbUploadRes.data.cid, - mimeType: encoding, - } - } - } + if (!embed && extLink) { + let thumb + if (extLink.localThumb) { + onStateChange?.(`Uploading link thumbnail...`) + let encoding + if (extLink.localThumb.path.endsWith('.png')) { + encoding = 'image/png' + } else if ( + extLink.localThumb.path.endsWith('.jpeg') || + extLink.localThumb.path.endsWith('.jpg') + ) { + encoding = 'image/jpeg' + } else { + store.log.warn( + 'Unexpected image format for thumbnail, skipping', + extLink.localThumb.path, + ) + } + if (encoding) { + const thumbUploadRes = await store.api.com.atproto.blob.upload( + extLink.localThumb.path, // this will be special-cased by the fetch monkeypatch in /src/state/lib/api.ts + {encoding}, + ) + thumb = { + cid: thumbUploadRes.data.cid, + mimeType: encoding, } - embed = { - $type: 'app.bsky.embed.external', - external: { - uri: link.value, - title: linkMeta.title || linkMeta.url, - description: linkMeta.description || '', - thumb, - }, - } as AppBskyEmbedExternal.Main - } catch (e: any) { - store.log.warn(`Failed to fetch link meta for ${link.value}`, e) } } + embed = { + $type: 'app.bsky.embed.external', + external: { + uri: extLink.uri, + title: extLink.meta?.title || '', + description: extLink.meta?.description || '', + thumb, + }, + } as AppBskyEmbedExternal.Main } if (replyTo) { |