From 85988697d488c55e20ace8194788ba74185d93a5 Mon Sep 17 00:00:00 2001 From: JubaAzul <118773284+JubaAzul@users.noreply.github.com> Date: Wed, 26 Mar 2025 16:52:51 -0400 Subject: [PATCH] [FEATURE] Zoomer sur les images en cliquant dessus Fixes #306 --- .../templates/TextTypeTemplate.ts | 3 +- client/src/markedConfig.ts | 103 +++++++++++++++++- 2 files changed, 100 insertions(+), 6 deletions(-) diff --git a/client/src/components/GiftTemplate/templates/TextTypeTemplate.ts b/client/src/components/GiftTemplate/templates/TextTypeTemplate.ts index dc5a77b..548e32c 100644 --- a/client/src/components/GiftTemplate/templates/TextTypeTemplate.ts +++ b/client/src/components/GiftTemplate/templates/TextTypeTemplate.ts @@ -1,4 +1,4 @@ -import marked from 'src/markedConfig'; +import marked, {attachImageModalListeners} from 'src/markedConfig'; import katex from 'katex'; import { TextFormat } from 'gift-pegjs'; @@ -53,6 +53,7 @@ export function FormattedTextTemplate(formattedText: TextFormat): string { break; case 'markdown': parsedText = marked.parse(formatText, { breaks: true, gfm: true }) as string; //
for newlines + attachImageModalListeners(); result = parsedText.replace(/(^

)(.*?)(<\/p>)$/gm, '$2'); break; default: diff --git a/client/src/markedConfig.ts b/client/src/markedConfig.ts index 29a9d9a..fac63ac 100644 --- a/client/src/markedConfig.ts +++ b/client/src/markedConfig.ts @@ -2,15 +2,108 @@ import { marked, Renderer } from 'marked'; // Customized renderer to support image width and height // see https://github.com/markedjs/marked/issues/339#issuecomment-1146363560 -const renderer = new Renderer(); - -renderer.image = ({href, title, text}) => { - const [width, height] = title?.startsWith('=') ? title.slice(1).split('x').map(v => v.trim()).filter(Boolean) : []; - return `${text}`; +declare global { + interface Window { + showImageInModal: (src: string, alt: string) => void; + } } +const renderer = new Renderer(); + +renderer.image = ({ href, title, text }) => { + const [width, height] = title?.startsWith('=') ? title.slice(1).split('x').map(v => v.trim()).filter(Boolean) : []; + const maxHeight = '15rem'; // Limite maximale de hauteur + + return ` +

+ ${text} +
+ `; +}; marked.use({ renderer: renderer }); + +if (typeof window !== 'undefined') { + window.showImageInModal = (src, alt) => { + console.log('showImageInModal called with:', src, alt); + + // Check if a modal already exists + const existingModal = document.querySelector('.image-modal'); + if (existingModal) { + // If the modal exists, remove it (close the modal) + document.body.removeChild(existingModal); + return; + } + + // Create the modal container + const modal = document.createElement('div'); + modal.className = 'image-modal'; // Add a class to identify the modal + modal.style.position = 'fixed'; + modal.style.top = '0'; + modal.style.left = '0'; + modal.style.width = '100vw'; + modal.style.height = '100vh'; + modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; + modal.style.display = 'flex'; + modal.style.justifyContent = 'center'; + modal.style.alignItems = 'center'; + modal.style.zIndex = '1000'; + + // Close the modal when the modal itself is clicked + modal.onclick = () => { + document.body.removeChild(modal); + }; + + // Create the image element + const img = document.createElement('img'); + img.src = src; + img.alt = alt; + + img.style.minWidth = '40%'; + img.style.minHeight = '40%'; + + img.style.cursor = 'zoom-out'; + + // Allow the modal to close when clicking on the image + img.onclick = () => { + document.body.removeChild(modal); + }; + + // Append the image to the modal and the modal to the body + modal.appendChild(img); + document.body.appendChild(modal); + }; +} + +export const attachImageModalListeners = () => { + const images = document.querySelectorAll('.modal-image'); + + images.forEach((image) => { + // Remove any existing event listeners by cloning the element + const newImage = image.cloneNode(true) as HTMLElement; + image.parentNode?.replaceChild(newImage, image); + + // Attach a new event listener + newImage.addEventListener('click', (event) => { + const target = event.target as HTMLImageElement; + const src = target.getAttribute('src'); + const alt = target.getAttribute('alt'); + if (src) { + window.showImageInModal(src, alt || ''); + } + }); + }); +}; + +marked.use({ + renderer: renderer, +}); + export default marked;