File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -219,12 +219,23 @@ async function previewTweet(id: string): Promise<Preview | null> {
219219 return { tags, images, cover : mosaic ?? undefined } ;
220220}
221221
222+ function imageType ( page : Response ) : string | null {
223+ const type = / ^ \s * ( i m a g e \/ [ \w . + - ] + ) / i. exec ( page . headers . get ( 'Content-Type' ) ?? '' ) ?. [ 1 ] . toLowerCase ( ) ;
224+ return type && type !== 'image/svg+xml' ? type : null ;
225+ }
226+
222227async function previewPage ( url : URL ) : Promise < Preview | null > {
223228 const endpoint = OEMBED_ENDPOINTS . find ( ( [ host ] ) => host . test ( url . hostname ) ) ?. [ 1 ] ;
224229 const known = endpoint ? fetchJson < OEmbed > ( new URL ( `${ endpoint } ?format=json&url=${ encodeURIComponent ( url . href ) } ` ) ) : null ;
225230
226231 const page = await fetchPublic ( url , 'text/html' ) ;
227232 const base = page ?. url || url ;
233+ const type = page && imageType ( page ) ;
234+ if ( page && type ) {
235+ await page . body ?. cancel ( ) ;
236+ const image = toImage ( base . toString ( ) ) ;
237+ return image ? { tags : { 'og:image:type' : type } , images : [ image ] } : null ;
238+ }
228239 const html = page ?. headers . get ( 'Content-Type' ) ?. includes ( 'text/html' ) ? await readPage ( page , base ) : null ;
229240 const knownOEmbed = await known ;
230241 if ( ! html && ! knownOEmbed ) return null ;
Original file line number Diff line number Diff line change @@ -89,6 +89,18 @@ describe('preview_url', () => {
8989 expect ( ( await preview ( 'https://api.example/' ) ) . status ) . toBe ( 404 ) ;
9090 } ) ;
9191
92+ it ( 'previews a direct image link as the image itself' , async ( ) => {
93+ servePage ( '' , 'image/gif' ) ;
94+
95+ const response = await preview ( 'https://cdn.example/clip.gif' ) ;
96+ const body = ( await response . json ( ) ) as Record < string , unknown > ;
97+
98+ expect ( response . status ) . toBe ( 200 ) ;
99+ expect ( body [ 'og:image' ] ) . toBe ( `mxc://gifs.example/${ toMatrixID ( 'https://cdn.example/clip.gif' , 'og_' ) } ` ) ;
100+ expect ( body [ 'og:image:type' ] ) . toBe ( 'image/gif' ) ;
101+ expect ( body [ 'og:title' ] ) . toBeUndefined ( ) ;
102+ } ) ;
103+
92104 it ( 'answers not found when the page cannot be fetched' , async ( ) => {
93105 vi . spyOn ( globalThis , 'fetch' ) . mockRejectedValue ( new Error ( 'down' ) ) ;
94106
You can’t perform that action at this time.
0 commit comments