translate/src/modules/entitydetails/components/Screenshots.tsx (59 lines of code) (raw):

import LinkifyIt from 'linkify-it'; import React, { useEffect, useState } from 'react'; import tlds from 'tlds'; import './Screenshots.css'; // Create and configure a URLs matcher. const linkify = new LinkifyIt(); linkify.tlds(tlds); function getImageURLs(source: string, locale: string) { const matches = linkify.match(source); if (!matches) { return []; } return matches .filter((match) => /(https?:\/\/.*\.(?:png|jpg))/im.test(match.url)) .map((match) => match.url.replace(/en-US\//gi, locale + '/')); } type Props = { locale: string; source: string; }; /** * Shows screenshot miniatures based on the content of a string. * * This component looks at all URLs to an image (either .png or .jpg) in a * source string and then shows a miniature of those images. * * On image click, shows the image in a fullscreen lightbox with a grey background. * Click or press a key to close. */ export function Screenshots({ locale, source }: Props) { const [openImage, setOpenImage] = useState<string | null>(null); useEffect(() => { if (!openImage) { return; } const handleKeyDown = ({ code }: KeyboardEvent) => { if ( code === 'Enter' || code === 'Escape' || code === 'Space' || code === 'Tab' ) { setOpenImage(null); } }; window.document.addEventListener('keydown', handleKeyDown); return () => { window.document.removeEventListener('keydown', handleKeyDown); }; }, [!openImage]); const images = getImageURLs(source, locale); return images.length > 0 ? ( <> <div className='screenshots'> {images.map((urlWithLocale) => ( <img src={urlWithLocale} alt='' key={urlWithLocale} onClick={() => setOpenImage(urlWithLocale)} /> ))} </div> {openImage ? ( <div className='lightbox' onClick={() => setOpenImage(null)}> <img src={openImage} alt='' /> </div> ) : null} </> ) : null; }