77 getIntersectionObserverEntry ,
88 useIntersectionObserver ,
99} from '$hooks/useIntersectionObserver' ;
10- import { mxcUrlToHttp } from '$utils/matrix' ;
10+ import { mxcUrlToHttp , downloadMedia } from '$utils/matrix' ;
1111import { useMediaAuthentication } from '$hooks/useMediaAuthentication' ;
1212import * as css from './UrlPreviewCard.css' ;
1313import { UrlPreview , UrlPreviewContent , UrlPreviewDescription } from './UrlPreview' ;
@@ -17,6 +17,16 @@ import { ImageViewer } from '../image-viewer';
1717
1818const linkStyles = { color : color . Success . Main } ;
1919
20+ const openMediaInNewTab = async ( url : string | undefined ) => {
21+ if ( ! url ) {
22+ console . warn ( 'Attempted to open an empty url' ) ;
23+ return ;
24+ }
25+ const blob = await downloadMedia ( url ) ;
26+ const blobUrl = URL . createObjectURL ( blob ) ;
27+ window . open ( blobUrl , '_blank' ) ;
28+ } ;
29+
2030export const UrlPreviewCard = as < 'div' , { url : string ; ts : number ; mediaType ?: string | null } > (
2131 ( { url, ts, mediaType, ...props } , ref ) => {
2232 const mx = useMatrixClient ( ) ;
@@ -50,6 +60,21 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number; mediaType?: s
5060 'scale' ,
5161 false
5262 ) ;
63+ const handleAuxClick = ( ev : React . MouseEvent ) => {
64+ if ( ! prev [ 'og:image' ] ) {
65+ console . warn ( 'No image' ) ;
66+ return ;
67+ }
68+ if ( ev . button === 1 ) {
69+ ev . preventDefault ( ) ;
70+ const mxcUrl = mxcUrlToHttp ( mx , prev [ 'og:image' ] , /* useAuthentication */ true ) ;
71+ if ( ! mxcUrl ) {
72+ console . error ( 'Error converting mxc:// url.' ) ;
73+ return ;
74+ }
75+ openMediaInNewTab ( mxcUrl ) ;
76+ }
77+ } ;
5378
5479 return (
5580 < Box
@@ -128,6 +153,7 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number; mediaType?: s
128153 < ImageContent
129154 style = { { width : '100%' , height : '100%' , position : 'absolute' , inset : 0 } }
130155 autoPlay
156+ onAuxClick = { handleAuxClick }
131157 body = { prev [ 'og:title' ] }
132158 url = { prev [ 'og:image' ] }
133159 renderViewer = { ( p ) => < ImageViewer { ...p } /> }
@@ -187,7 +213,6 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number; mediaType?: s
187213 </ Box >
188214 ) ;
189215 }
190-
191216 return (
192217 < UrlPreview
193218 { ...props }
0 commit comments