]> git.localhorst.tv Git - alttp.git/blobdiff - resources/js/components/common/RawHTML.js
clickable APNGs
[alttp.git] / resources / js / components / common / RawHTML.js
index fb0b51ef2b43ec3b5672768818bc2e8a78e056cb..dde6d530fed21f58dd5a736d64d7f6b1b22d01fd 100644 (file)
@@ -2,8 +2,23 @@ import PropTypes from 'prop-types';
 import React from 'react';
 import { useNavigate } from 'react-router-dom';
 
+import PngDialog from './PngDialog';
+
+const isApng = el => el.nodeName === 'IMG' && el.getAttribute('type') === 'image/apng';
+
+const isLink = el => el.nodeName === 'A';
+
+const canClick = el => {
+       if (isLink(el)) return true;
+       if (isApng(el)) return true;
+       return false;
+};
+
 const RawHTML = ({ html }) => {
        const navigate = useNavigate();
+       const [apng, setApng] = React.useState(null);
+       const [show, setShow] = React.useState(false);
+       const [title, setTitle] = React.useState(null);
 
        const onClick = e => {
                if (e.defaultPrevented) return;
@@ -11,34 +26,46 @@ const RawHTML = ({ html }) => {
                if (e.button !== 0) return;
 
                let el = e.target;
-               while (el && el.nodeName !== 'A') {
+               while (el && !canClick(el)) {
                        el = el.parentNode;
                }
                if (!el) return;
 
-               if (el.target && el.target !== '_self') return;
-               if (el.attributes.download) return;
-               if (el.rel && /(?:^|\s+)external(?:\s+|$)/.test(el.rel)) return;
+               if (isLink(el)) {
+                       if (el.target && el.target !== '_self') return;
+                       if (el.attributes.download) return;
+                       if (el.rel && /(?:^|\s+)external(?:\s+|$)/.test(el.rel)) return;
+
+                       const href = el.getAttribute('href');
 
-               const href = el.getAttribute('href');
+                       if (href.startsWith('#')) return;
+                       if (href.startsWith('http')) return;
+                       if (href.startsWith('mailto')) return;
+                       if (href.startsWith('tel')) return;
 
-               if (href.startsWith('#')) return;
-               if (href.startsWith('http')) return;
-               if (href.startsWith('mailto')) return;
-               if (href.startsWith('tel')) return;
+                       el.blur();
+                       e.preventDefault();
 
-               el.blur();
-               e.preventDefault();
+                       setTimeout(() => {
+                               // scroll to top on location change
+                               scrollTo({ top: 0, behavior: 'smooth' });
+                       }, 50);
 
-               setTimeout(() => {
-                       // scroll to top on location change
-                       scrollTo({ top: 0, behavior: 'smooth' });
-               }, 50);
+                       navigate(href);
+                       return;
+               }
 
-               navigate(href);
+               if (isApng(el)) {
+                       setApng(el.getAttribute('src'));
+                       setShow(true);
+                       setTitle(el.getAttribute('alt'));
+               }
        };
 
-       return <div onClick={onClick} dangerouslySetInnerHTML={{ __html: html }} />;
+       return <>
+               <div className="raw-html" onClick={onClick} dangerouslySetInnerHTML={{ __html: html }} />
+               <PngDialog onHide={() => setShow(false)} show={show} src={apng} title={title} />
+       </>;
 };
 
 RawHTML.propTypes = {