a demonstration replicated social networking web app built with anproto wiredove.net/
social ed25519 protocols
at master 79 lines 2.4 kB view raw
1import { h } from 'h' 2import { apds } from 'apds' 3import { marked } from 'https://esm.sh/gh/evbogue/bog5@de70376265/lib/marked.esm.js' 4import { send } from './send.js' 5 6const renderer = new marked.Renderer() 7 8const linkHashtags = (words) => { 9 for (let i = 0; i < words.length; i++) { 10 let word = words[i] 11 if (!word.startsWith('#')) { continue } 12 let end 13 if (['.', ',', '?', ':', '!'].some(char => word.endsWith(char))) { 14 end = word[word.length - 1] 15 word = word.substring(0, word.length - 1) 16 } 17 let hashtag = "<a href='#?" + word + "'>" + word + "</a>" 18 if (end) { hashtag += end } 19 words[i] = hashtag 20 } 21 return words 22} 23 24renderer.paragraph = function (paragraph) { 25 const images = paragraph.match(/<img\b[^>]*>/gi) || [] 26 if (images.length) { 27 const textOnly = paragraph 28 .replace(/<img\b[^>]*>/gi, ' ') 29 .replace(/<br\s*\/?>/gi, ' ') 30 .replace(/\s+/g, ' ') 31 .trim() 32 33 if (!textOnly) { 34 return `<div class="post-image-row">${images.join('')}</div>` 35 } 36 37 const linked = linkHashtags(textOnly.split(' ')).join(' ') 38 return '<p>' + linked + '</p><div class="post-image-row">' + images.join('') + '</div>' 39 } 40 41 return '<p>' + linkHashtags(paragraph.split(' ')).join(' ') + '</p>' 42} 43 44renderer.link = function (href, title, text) { 45 if (href.length == 44 && !href.startsWith('http')) { 46 href = '#' + href 47 return marked.Renderer.prototype.link.call(this, href, title, text); 48 } else { 49 const m = marked.Renderer.prototype.link.call(this, href, title, text) 50 return m 51 } 52} 53 54renderer.image = function (src, title, text) { 55 if (src && src.length === 44) { 56 apds.get(src).then(async (img) => { 57 if (img) { 58 const image = document.getElementById('inlineimage' + src) 59 if (image) { 60 image.src = img 61 } 62 } else { 63 await send(src) 64 } 65 }) 66 const altText = text ? text.replace(/"/g, '&quot;') : 'Post image' 67 return `<img class="post-image" data-hash="${src}" id="inlineimage${src}" alt="${altText}" loading="lazy" tabindex="0" />` 68 } 69} 70 71marked.setOptions({ 72 renderer: renderer 73}) 74 75export const markdown = async (txt) => { 76 const rendered = marked(txt || '') 77 // If markdown splits image-only paragraphs (e.g. due blank lines), merge adjacent rows. 78 return rendered.replace(/<\/div>\s*<div class="post-image-row">/g, '') 79}