/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ import React from 'react'; import FileSaver from 'file-saver'; import classNames from 'classnames'; import { Box, Chip, Header, IconButton, Text, as } from 'folds'; import { Icon, Icons } from '../icons'; import * as css from './ImageViewer.css'; import { useZoom } from '../../hooks/useZoom'; import { usePan } from '../../hooks/usePan'; import { downloadMedia } from '../../utils/matrix'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { getCurrentAccessToken } from '../../utils/auth'; export type ImageViewerProps = { alt: string; src: string; requestClose: () => void; }; export const ImageViewer = as<'div', ImageViewerProps>( ({ className, alt, src, requestClose, ...props }, ref) => { const mx = useMatrixClient(); const { zoom, zoomIn, zoomOut, setZoom } = useZoom(0.2); const { pan, cursor, onMouseDown } = usePan(zoom !== 1); const handleDownload = async () => { try { // Always use current session's token to avoid stale tokens during account switches const fileContent = await downloadMedia(src, getCurrentAccessToken()); FileSaver.saveAs(fileContent, alt); } catch (error) { console.warn('[ImageViewer] Failed to download media:', error); // Fallback: try to fetch via standard fetch as blob try { const response = await fetch(src); if (response.ok) { const blob = await response.blob(); FileSaver.saveAs(blob, alt); } } catch { // If all else fails, open in new tab to let browser handle it window.open(src, '_blank'); } } }; return (
{alt} setZoom(zoom === 1 ? 2 : 1)}> {Math.round(zoom * 100)}% 1 ? 'Success' : 'SurfaceVariant'} outlined={zoom > 1} size="300" radii="Pill" onClick={zoomIn} aria-label="Zoom In" > } > Download
{alt}
); } );