import style from "./style.module.scss"; import {useMemo} from "preact/hooks"; import {smileysMap} from "@/utils/smileys"; // const blocks = { // text: "text", // img: "img", // } // // type Segment = { // type: keyof typeof blocks, // content: string, // } export function Preview(props: { raw: string, }) { const html = useMemo(() => { const escaped = escapeHtml(props.raw); return injectHTML(escaped)/*.replace(/\n/g, '
')*/; }, [props.raw]); return (
) // // return ( //
// {segments.map(seg => { // if (seg.type === blocks.text) { // return seg.content // } // // if (seg.type === blocks.img) { // return noelshak // } // })} //
// ) } function quoteReplacer(reg: RegExp, raw: string): string { // return raw const match = reg.exec(raw); reg.lastIndex = 0; if (!match) return raw; const index = match.index; const length = match[0].length; return quoteReplacer( reg, raw.substring(0, index) + `
${quoteReplacer(reg, match[0].replace(/^> ?/gm, ""))}
` + raw.substring(index + length) ); } // WARNING: the order is important const jvcodeMap: [RegExp, string | ((reg: RegExp, raw: string) => string)][] = [ [ // Quotes /^>.*(?:\n>.*)*/m, quoteReplacer ], [ // Wrap text with paragraphs /(^|>)([^<]+)($|<)/g, "$1

$2

$3" ], [ // Replace line breaks between

tags with
/

\s*([\s\S]*?)\s*<\/p>/g, (reg, raw) => { // console.log(raw) return raw.replace(reg, (_, matched) => { // const randomId = (Math.random() + 1).toString(36).substring(2); console.log(matched) return `

${matched.replace(/\n/g, "
")}

`; }); } ], [ // Spoil /<spoil>(.*?)<\/spoil>/gm, (reg, raw) => { return raw.replace(reg, (_, matched) => { const randomId = (Math.random() + 1).toString(36).substring(2); return `${matched}`; }); } ], [ // Stickers // /(^|

| )https?:\/\/image\.noelshack\.com\/(?:fichiers|minis)([A-z0-9/\-_.]+)/gm, /(^|<[a-z]+\/?>| )https?:\/\/image\.noelshack\.com\/(?:fichiers|minis)([A-z0-9/\-_.]+)/gm, "$1\"sticker\"" ], [ // Vocaroo /(^|<[a-z]+\/?>| )https:\/\/vocaroo.com\/(.+)/gm, "$1

" ], [ // Regular links /(^|<[a-z]+\/?>| )(https?:\/\/[-a-zA-Z0-9@:%._/+~#=?&;]+)/gm, "$1$2" ], // TODO: embeded youtube, utiliser le titre du topic pour chercher une vidéo corespondante avec l'API search de youtube // Generate regexes for smileys // ...smileysMap.map((maping) => { // return [new RegExp( // Object.keys(smileysMap).map(s => ( // "(?:(?:^| )" + s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ")" // )).join("|"), "gm" // ), ``] // }) // (() => { // new RegExp( // smileysMap.map((mapping) => ( // "(?:(?:^| )" + s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ")" // )).join("|"), "gm" // ) // return [/(https?:\/\/image\.noelshack\.com\/\S+)/g, "\"noelshak\""] // })() ...[...smileysMap].sort((a, b) => b[0].length - a[0].length).map(mapping => { // Sort smileys by length to match :-))) before :-) return [ new RegExp("(

| )" + mapping[0].replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), "gm"), `$1${mapping[0]}` ]; }) ]; function injectHTML(input: string): string { // console.log("---------------------") let text = input.slice() for (const [regex, htmlOrFunc] of jvcodeMap) { // Reset the regex @see https://stackoverflow.com/a/11477448/5912637 regex.lastIndex = 0; // const regex = new RegExp(bbCode, 'gi'); // console.log(regex, html, input) if (htmlOrFunc instanceof Function) { text = htmlOrFunc(regex, text); } else { // console.log(regex) // console.log(text) text = text.replace(regex, htmlOrFunc as string); } } // console.log(input) return text; } function escapeHtml(unsafe: string): string { // unsafe.re return unsafe .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // function parseRaw(raw: string): Segment[] { // // Regex pour capturer les URLs (HTTP, HTTPS) // const urlRegex = /(https?:\/\/[^\s]+)/g; // // // Découper le texte en utilisant la regex, en gardant les URLs comme blocs séparés // return raw.split(urlRegex).filter(seg => seg !== "").map(seg => { // return { // type: seg.includes(".png") || seg.includes(".jpg") ? blocks.img : blocks.text, // content: seg, // } // }); // }