diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b7147b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +testing/ \ No newline at end of file diff --git a/README.md b/README.md index c418209..fa27b1d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # An embed visualizer -Visualizes embed or message content from JSON input. This can be used for visualizing bot embed commands. +Displays embed or message content from JSON input. This can be used for visualizing bot embed commands. This can be used for bot embed commands commands, although I understand that not every one understands JSON thus will add a GUI later. -You can look into the [project boards](https://github.com/Glitchii/embedbuilder/projects/3) if you want to see what I'm currently working on or want to contribute +You can look into the [project boards](https://github.com/Glitchii/embedbuilder/projects/3) if you want to see what is being worked on or want to contribute.

-![Layout image](https://raw.githubusercontent.com/Glitchii/embedbuilder/master/assets/media/layout.png) \ No newline at end of file +![Layout image](https://raw.githubusercontent.com/Glitchii/embedbuilder/master/assets/media/layout.png) + +[To Do](https://github.com/Glitchii/embedbuilder/projects/3) | [Discussions](https://github.com/Glitchii/embedbuilder/discussions/1) \ No newline at end of file diff --git a/assets/css/index.css b/assets/css/index.css index b239f68..a2cedf1 100644 --- a/assets/css/index.css +++ b/assets/css/index.css @@ -340,10 +340,14 @@ img[alt] { .emoji { object-fit: contain; - width: 22px; - height: 22px; - margin: 0 .05em 0 .1em !important; - vertical-align: -.4em; + width: 1.375em; + height: 1.375em; + vertical-align: bottom; +} + +.embed .emoji { + width: 18px; + height: 18px; } .embedGrid { @@ -471,6 +475,7 @@ img[alt] { margin-top: 8px; gap: 8px; min-width: 0px; + grid-gap: 8px; } .embedField { @@ -583,6 +588,26 @@ u { text-size-adjust: none; } +.embed blockquote { + max-width: 100%; +} +.blockquote { + display: flex; +} +.blockquote blockquote { + padding: 0 8px 0 12px; + box-sizing: border-box; + text-indent: 0; +} + +.blockquote .blockquoteDivider { + width: 4px; + border-radius: 4px; +} +.blockquoteDivider { + background-color: var(--interactive-muted); +} + .container { display: grid; grid-auto-flow: row; @@ -620,6 +645,10 @@ u { white-space: pre-wrap; } +.markup .markup :is(pre, blockquote) { + max-width: 90%; +} + .markup pre { max-width: 90%; border-radius: 4px; @@ -632,11 +661,7 @@ u { background-clip: border-box; } -.markup pre.embeded { - max-width: 100%; -} - -.markup pre.embeded>code { +.embed code { border: none; background: var(--background-tertiary); } @@ -781,4 +806,17 @@ u { display: block; margin-top: 5px; } +} + +@media screen and (max-width: 530px) { + .msgEmbed { + margin: 20px 0px; + padding: 0.125rem 0 20px 65px; + } + .avatar { + left: 10px; + } + .main .side1 { + padding: 10px; + } } \ No newline at end of file diff --git a/assets/js/components.js b/assets/js/components.js index 97b0652..847d819 100644 --- a/assets/js/components.js +++ b/assets/js/components.js @@ -1,56 +1,58 @@ var emoticons = { - ">=-(": "angry", - "=\")": "blush", - "=-\")": "blush", - "<\\3": "broken_heart", - "=-/": "confused", - ":'(": "cry", - ":'-(": "cry", - ":,(": "cry", - ":,-(": "cry", - "='(": "cry", - "='-(": "cry", - "=,(": "cry", - "=,-(": "cry", - "=-(": "frowning", - "โ™ก": "heart", - "]=-(": "imp", - "0=-)": "innocent", - ":')": "joy", - ":'-)": "joy", - ":,)": "joy", - ":,-)": "joy", - ":'D": "joy", - ":'-D": "joy", - ":,D": "joy", - ":,-D": "joy", - "=')": "joy", - "='-)": "joy", - "=,)": "joy", - "=,-)": "joy", - "='D": "joy", - "='-D": "joy", - "=-*": "kissing", - "X-)": "laughing", - "=-|": "neutral_face", - "=-O": "open_mouth", - "=-@": "rage", - "=-D": "smile", - "=-)": "slight_smile", - "]=-)": "smiling_imp", - ":,'(": "sob", - ":,'-(": "sob", - ";(": "sob", - ";-(": "sob", - "=,'(": "sob", - "=,'-(": "sob", - "=-P": "stuck_out_tongue", - "B-)": "sunglasses", - ",=-(": "sweat", - ",=-)": "sweat_smile", - "=-$": "unamused", - ";)": "wink", - ";-)": "wink" + ">=-(": "๐Ÿ˜ ", + "=\")": "๐Ÿ˜Š", + "=-\")": "๐Ÿ˜Š", + "<\\3": "๐Ÿ’”", + "=-/": "๐Ÿ˜•", + ":'(": "๐Ÿ˜ข", + ":'-(": "๐Ÿ˜ข", + ":,(": "๐Ÿ˜ข", + ":,-(": "cr๐Ÿ˜ขy", + "='(": "๐Ÿ˜ข", + "='-(": "๐Ÿ˜ข", + "=,(": "๐Ÿ˜ข", + "=,-(": "๐Ÿ˜ข", + "=-(": "๐Ÿ˜ฆ", + "โ™ก": "heartโค๏ธ", + "]=-(": "๐Ÿ‘ฟ", + "0=-)": "๐Ÿ˜‡", + ":')": "๐Ÿ˜‚", + ":'-)": "๐Ÿ˜‚", + ":,)": "๐Ÿ˜‚", + ":,-)": "๐Ÿ˜‚", + ":'D": "๐Ÿ˜‚", + ":'-D": "๐Ÿ˜‚", + ":,D": "๐Ÿ˜‚", + ":,-D": "๐Ÿ˜‚", + "=')": "๐Ÿ˜‚", + "='-)": "๐Ÿ˜‚", + "=,)": "๐Ÿ˜‚", + "=,-)": "๐Ÿ˜‚", + "='D": "๐Ÿ˜‚", + "='-D": "๐Ÿ˜‚", + "=-*": "๐Ÿ˜—", + "X-)": "๐Ÿ˜†", + "=-|": "๐Ÿ˜", + "=-O": "๐Ÿ˜ฎ", + "=-@": "๐Ÿ˜ก", + "=-D": "๐Ÿ˜„", + ":)": "๐Ÿ™‚", + ":-)": "๐Ÿ™‚", + "=-)": "๐Ÿ™‚", + "]=-)": "๐Ÿ˜ˆ", + ":,'(": "๐Ÿ˜ญ", + ":,'-(": "๐Ÿ˜ญ", + ";(": "๐Ÿ˜ญ", + ";-(": "๐Ÿ˜ญ", + "=,'(": "๐Ÿ˜ญ", + "=,'-(": "๐Ÿ˜ญ", + "=-P": "๐Ÿ˜›", + "B-)": "๐Ÿ˜Ž", + ",=-(": "๐Ÿ˜“", + ",=-)": "๐Ÿ˜…", + "=-$": "๐Ÿ˜’", + ";)": "๐Ÿ˜‰", + ";-)": "๐Ÿ˜‰" }, emojis = { "open_hands": "๐Ÿ‘", "open_hands_tone1": "๐Ÿ‘๐Ÿป", @@ -2968,6 +2970,7 @@ var emoticons = { "confused": "๐Ÿ˜•", "cry": "๐Ÿ˜ข", "frowning": "๐Ÿ˜ฆ", + "frowning2": "โ˜น๏ธ", "imp": "๐Ÿ‘ฟ", "innocent": "๐Ÿ˜‡", "joy": "๐Ÿ˜‚", diff --git a/assets/js/index.js b/assets/js/index.js index 634763e..484fe86 100644 --- a/assets/js/index.js +++ b/assets/js/index.js @@ -12,7 +12,6 @@ window.onload = () => { theme: 'material-darker', scrollbarStyle: "overlay", mode: "application/json", - // lineNumbers: true, foldGutter: true, gutters: ["CodeMirror-foldgutter", "CodeMirror-lint-markers"], matchBrackets: true, @@ -30,27 +29,26 @@ window.onload = () => { if (html) notif.innerHTML = msg; else notif.innerText = msg; notif.style.display = 'block'; - // err && console.log(err); - }, markup = (txt, isEmbed) => { + }, markup = (txt, opts) => { txt = txt - // Custom Emojis - .replace(//g, '') // .replace(//g, '') // This will keep logging failed GET request errors in console - // MD + .replace(/<:[^:]+:(\d+)>/g, '') + .replace(//g, '') .replace(/~~(.+?)~~/g, '$1') - .replace(/\`(?!\`)([^\`]+?)\`(?!\`)/g, '$1') - .replace(/\`\`(?!\`)([^\`]+?)\`\`(?!\`)/g, '$1') .replace(/\*\*\*(.+?)\*\*\*/g, '$1') .replace(/\*\*(.+?)\*\*/g, '$1') .replace(/__(.+?)__/g, '$1') .replace(/\*(.+?)\*/g, '$1') .replace(/_(.+?)_/g, '$1') - // Block - .replace(/\n/g, '
') - .replace(/\`\`\`(\w{1,15})
((\n|.)+?)\`\`\`/g, isEmbed ? '
$2
' : '
$2
') - .replace(/\`\`\`(\w{1,15})
((\n|.)+?)\`\`\`/g, isEmbed ? '
$2
' : '
$2
') - .replace(/\`\`\`(
)?((\n|.)+?)\`\`\`/g, isEmbed ? '
$2
' : '
$2
') - if (isEmbed) txt = txt - .replace(/\[(.+)\]\((.+)\)/g, `$1`); + if (opts.inlineBlock) txt = txt.replace(/\`([^\`]+?)\`|\`\`([^\`]+?)\`\`|\`\`\`((?:\n|.)+?)\`\`\`/g, (m, x, y, z) => x ? `${x}` : y ? `${y}` : z ? `${z}` : m); + else txt = txt.replace(/\`\`\`(\w{1,15})?\n((?:\n|.)+?)\`\`\`|\`\`(.+?)\`\`(?!\`)|\`([^\`]+?)\`/g, (m, w, x, y, z) => w && x ? `
${x}
` : x ? `
${x}
` : y || z ? `${y || z}` : m); + if (opts.inEmbed) txt = txt.replace(/\[([^\[\]]+)\]\((.+?)\)/g, `$1`); + if (opts.replaceEmojis) { + txt = txt.replace(/(?[^>]+)(? x && emojis[x] ? emojis[x] : match); + !opts.noEmoticons && Object.keys(emoticons).forEach(e => txt = txt.replace(new RegExp(`(?<=^|\\s)${regEscape(e)}(?=$|\\s)`, 'g'), emoticons[e])); + } + txt = txt + .replace(/(?<=\n|^)\s*>\s+([^\n]+)/g, '
$1
') + .replace(/\n/g, '
'); return txt; }, content = document.querySelector('.messageContent'), @@ -77,15 +75,16 @@ window.onload = () => { el.style.display = displayType || "unset"; }, hide = el => el.style.removeProperty('display'), + regEscape = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), toObj = jsonString => JSON.parse(jsonString.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (x, y) => y ? "" : x)), update = data => { try { - content.innerHTML = data.content ? markup(data.content) : ''; + content.innerHTML = data.content ? markup(data.content, { replaceEmojis: true }) : ''; if (data.embed) { let e = data.embed; - if (e.title) display(embedTitle, markup(`${e.url ? '' + e.title + '' : e.title}`)); + if (e.title) display(embedTitle, markup(`${e.url ? '' + e.title + '' : e.title}`, { replaceEmojis: true, noEmoticons: true, inlineBlock: true })); else hide(embedTitle); - if (e.description) display(embedDescription, markup(e.description, true)); + if (e.description) display(embedDescription, markup(e.description, { inEmbed: true, replaceEmojis: true })); else hide(embedDescription); if (e.color) embed.closest('.embed').style.borderColor = (typeof e.color === 'number' ? '#' + e.color.toString(16) : e.color); else embed.closest('.embed').style.removeProperty('border-color'); @@ -110,15 +109,15 @@ window.onload = () => { let el = fields.insertBefore(document.createElement('div'), null); el.outerHTML = `
-
${markup(f.name)}
-
${markup(f.value)}
+
${markup(f.name, { inEmbed: true, replaceEmojis: true, inlineBlock: true })}
+
${markup(f.value, { inEmbed: true, replaceEmojis: true })}
`; } else { el = fields.insertBefore(document.createElement('div'), null); el.outerHTML = `
-
${markup(f.name)}
-
${markup(f.value)}
+
${markup(f.name, { inEmbed: true, replaceEmojis: true, inlineBlock: true })}
+
${markup(f.value, { inEmbed: true, replaceEmojis: true })}
`; colNum = (colNum === 9 ? 1 : colNum + 4); num++; @@ -127,16 +126,16 @@ window.onload = () => { colNum = 1; let len = e.fields.filter(f => f.inline).length; if (len === 2 || (len > 3 && len % 2 !== 0)) { - let children = Array.from(fields.children), - arr = children.filter(x => x === children[len] || x === children[len - 1]); + let children = Array.from(fields.children), arr = children.filter(x => x === children[len] || x === children[len - 1]); arr[0].style.gridColumn = '1 / 7', arr[1].style.gridColumn = '7 / 13'; } display(fields, undefined, 'grid'); } else hide(fields); embed.classList.remove('empty'); - let re = /"((icon_)?url")(: *)("(?!\w+?:\/\/).+?")/g.exec(editor.getValue()) - if (re) error(`URLs should have a valid protocol (eg. https://) on this line ${makeShort(re[0], 30, 600)}`, true); + let re = /"((icon_)?url")(: *)("(?!https?:\/\/).+?")/g.exec(editor.getValue()) + if (re) error(`URLs should start with https:// or http:// on this line ${makeShort(re[0], 30, 600)}`, true); else notif.animate({ opacity: '0', bottom: '-50px', offset: 1 }, { easing: 'ease', duration: 500 }).onfinish = () => notif.style.removeProperty('display'); + twemoji.parse(msgEmbed); } } catch (e) { error(e); @@ -146,16 +145,14 @@ window.onload = () => { editor.on('change', editor => { try { update(toObj(editor.getValue())); } catch (e) { - if (editor.getValue()) return; // error("Couldn't parse JSON; Invalid JSON syntax", e) + if (editor.getValue()) return; embed.classList.add('empty'); content.innerHTML = ''; } document.querySelectorAll('.markup pre > code').forEach((block) => hljs.highlightBlock(block)); - twemoji.parse(msgEmbed); }); update(toObj(editor.getValue())); - twemoji.parse(msgEmbed); document.querySelector('.timeText').innerText = tstamp() document.querySelectorAll('.markup pre > code').forEach((block) => hljs.highlightBlock(block)) !window.navigator.userAgent.match(/Firefox\/[\d\.]+$/g) && // Firefox pushes the text up a little diff --git a/index.html b/index.html index a322c92..9c09a0d 100644 --- a/index.html +++ b/index.html @@ -23,6 +23,8 @@ + + @@ -31,10 +33,10 @@