diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/download.ts | 61 | ||||
-rw-r--r-- | src/lib/link-meta.ts | 16 |
2 files changed, 74 insertions, 3 deletions
diff --git a/src/lib/download.ts b/src/lib/download.ts new file mode 100644 index 000000000..96d93fc27 --- /dev/null +++ b/src/lib/download.ts @@ -0,0 +1,61 @@ +import RNFetchBlob from 'rn-fetch-blob' +import ImageResizer from '@bam.tech/react-native-image-resizer' + +interface DownloadAndResizeOpts { + uri: string + width: number + height: number + mode: 'contain' | 'cover' | 'stretch' + timeout: number +} + +export async function downloadAndResize(opts: DownloadAndResizeOpts) { + let appendExt + try { + const urip = new URL(opts.uri) + const ext = urip.pathname.split('.').pop() + if (ext === 'jpg' || ext === 'jpeg') { + appendExt = 'jpeg' + } else if (ext === 'png') { + appendExt = 'png' + } else { + return + } + } catch (e: any) { + console.error('Invalid URI', opts.uri, e) + return + } + + let downloadRes + try { + const downloadResPromise = RNFetchBlob.config({ + fileCache: true, + appendExt, + }).fetch('GET', opts.uri) + const to1 = setTimeout(() => downloadResPromise.cancel(), opts.timeout) + downloadRes = await downloadResPromise + clearTimeout(to1) + + let localUri = downloadRes.path() + if (!localUri.startsWith('file://')) { + localUri = `file://${localUri}` + } + + const resizeRes = await ImageResizer.createResizedImage( + localUri, + opts.width, + opts.height, + 'JPEG', + 0.7, + undefined, + undefined, + undefined, + {mode: opts.mode}, + ) + return resizeRes + } finally { + if (downloadRes) { + downloadRes.flush() + } + } +} diff --git a/src/lib/link-meta.ts b/src/lib/link-meta.ts index c1739ae3b..53d5eed7c 100644 --- a/src/lib/link-meta.ts +++ b/src/lib/link-meta.ts @@ -22,9 +22,13 @@ export interface LinkMeta { url: string title?: string description?: string + image?: string } -export async function getLinkMeta(url: string): Promise<LinkMeta> { +export async function getLinkMeta( + url: string, + timeout = 5e3, +): Promise<LinkMeta> { if (isBskyAppUrl(url)) { // TODO this could be better url = convertBskyAppUrlIfNeeded(url) @@ -57,14 +61,20 @@ export async function getLinkMeta(url: string): Promise<LinkMeta> { } try { - const httpRes = await fetch(url) + const controller = new AbortController() + const to = setTimeout(() => controller.abort(), timeout || 5e3) + const httpRes = await fetch(url, { + headers: {accept: 'text/html'}, + signal: controller.signal, + }) const httpResBody = await httpRes.text() + clearTimeout(to) const httpResMeta = extractHtmlMeta(httpResBody) meta.title = httpResMeta.title ? he.decode(httpResMeta.title) : undefined meta.description = httpResMeta.description ? he.decode(httpResMeta.description) : undefined - // TODO meta.image = httpResMeta.image + meta.image = httpResMeta.image } catch (e) { // failed console.log(e) |