diff --git a/package.json b/package.json index 3a98f4d..f6422f8 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "emoji-named-characters": "^1.0.2", "emoji-server": "^1.0.0", "human-time": "^0.0.1", + "hyperscript": "2.0.2", "lrucache": "^1.0.2", "pull-cat": "^1.1.11", "pull-paramap": "^1.2.1", diff --git a/render.js b/render.js index fd9e95c..c3edca8 100644 --- a/render.js +++ b/render.js @@ -4,6 +4,7 @@ var marked = require("ssb-marked"); var htime = require("human-time"); var emojis = require("emoji-named-characters"); var cat = require("pull-cat"); +var h = require('hyperscript'); var emojiDir = path.join(require.resolve("emoji-named-characters"), "../pngs"); @@ -39,17 +40,11 @@ MdRenderer.prototype.urltransform = function(href) { }; MdRenderer.prototype.image = function(href, title, text) { - return ( - '' +
-    text +
-    '" : ">") - ); + return h('img', + { src: this.opts.img_base + href, + alt: text, + title: title + }).outerHTML; }; function renderEmoji(emoji) { @@ -59,16 +54,12 @@ function renderEmoji(emoji) { ? opts.blob_base + encodeURIComponent(mentions[emoji]) : emoji in emojis && opts.emoji_base + escape(emoji) + '.png'; return url - ? ':' +
-        escape(emoji) +
-        ':' + ? h('img.ssb-emoji', + { src: url, + alt: ':' + escape(emoji) + ':', + title: ':' + escape(emoji) + ':', + height: 16, width: 16 + }).outerHTML : ":" + emoji + ":"; } @@ -99,44 +90,46 @@ function wrap(before, after) { }; } +function callToAction() { + return h('a.call-to-action', + { href: 'https://www.scuttlebutt.nz' }, + 'Join Scuttlebutt now').outerHTML; +} + +function toolTipTop() { + return h('span.top-tip', + 'You are reading content from ', + h('a', { href: 'https://www.scuttlebutt.nz' }, + 'Scuttlebutt')).outerHTML; +} + function renderAbout(opts, about, showAllHTML = "") { + var figCaption = h('figcaption'); + figCaption.innerHTML = 'Feed of ' + about.name + '
' + + (about.description != undefined ? + marked(about.description, opts.marked) : ''); return pull( pull.map(renderMsg.bind(this, opts)), - wrap( - 'You are reading content from ' + - 'Scuttlebutt' + - '' + - '
' + - '
' + - '
' + - 'Feed of ' + about.name + '
' + - (about.description != undefined ? - marked(about.description, opts.marked) : '') + - '
', - - showAllHTML + '
' + - '' + - 'Join Scuttlebutt now' + - '' - ) + wrap(toolTipTop() + '
' + + h('article', + h('header', + h('figure', + h('img', + { src: opts.img_base + about.image, + height: 200, + width: 200 + }), + figCaption) + )).outerHTML, + showAllHTML + '
' + callToAction()) ); } function renderThread(opts, showAllHTML = "") { return pull( pull.map(renderMsg.bind(this, opts)), - wrap( - 'You are reading content from ' + - 'Scuttlebutt' + - '' + - '
', - - showAllHTML + '
' + - '' + - 'Join Scuttlebutt now' + - '' - ) + wrap(toolTipTop() + '
', + showAllHTML + '
' + callToAction()) ); } @@ -320,45 +313,32 @@ function docWrite(str) { function renderMsg(opts, msg) { var c = msg.value.content || {}; var name = encodeURIComponent(msg.key); - return ( - '
' + - '
' + - '
' + - '' + - '
' + - '" + msg.author.name + "" + - msgTimestamp(msg, opts.base + name) + - '
' + - '
' + - '
' + - render(opts, c) + - "
" - ); + return h('article#' + name, + h('header', + h('figure', + h('img', { alt: '', + src: opts.img_base + msg.author.image, + height: 50, width: 50 }), + h('figcaption', + h('a.ssb-avatar-name', + { href: opts.base + escape(msg.value.author) }, + msg.author.name), + msgTimestamp(msg, opts.base + name)))), + render(opts, c)).outerHTML; } function msgTimestamp(msg, link) { var date = new Date(msg.value.timestamp); var isoStr = date.toISOString(); - return ( - '' - ); + return h('time.ssb-timestamp', + { datetime: isoStr }, + h('a', + { href: link, + title: isoStr }, + formatDate(date))); } function formatDate(date) { - // return date.toISOString().replace('T', ' ') return htime(date); } @@ -366,106 +346,102 @@ function render(opts, c) { var base = opts.base; if (c.type === "post") { var channel = c.channel - ? '
#' + c.channel + "
" - : ""; - return channel + renderPost(opts, c); + ? h('div.top-right', + h('a', + { href: base + 'channel/' + c.channel }, + '#' + c.channel)) + : ""; + return [channel, renderPost(opts, c)]; } else if (c.type == "vote" && c.vote.expression == "Dig") { var channel = c.channel - ? ' in #' + c.channel + "" - : ""; + ? [' in ', + h('a', + { href: base + 'channel/' + c.channel }, + '#' + c.channel)] + : ""; var linkedText = "this"; if (typeof c.vote.linkedText != "undefined") - linkedText = c.vote.linkedText.substring(0, 75); - return ('' + - 'Liked ' + - '' + - linkedText + - "" + - channel + - '' - ); + linkedText = c.vote.linkedText.substring(0, 75); + return h('span.status', + ['Liked ', + h('a', { href: base + c.vote.link }, linkedText), + channel]); } else if (c.type == "vote") { var linkedText = "this"; if (typeof c.vote.linkedText != "undefined") linkedText = c.vote.linkedText.substring(0, 75); - return '' + - 'Voted ' + linkedText + "" + - ''; + return h('span.status', + ['Voted ', + h('a', { href: base + c.vote.link }, linkedText)]); } else if (c.type == "contact" && c.following) { var name = c.contact; - if (typeof c.contactAbout != "undefined") name = c.contactAbout.name; - return '' + - 'Followed ' + name + "" + - ''; + if (typeof c.contactAbout != "undefined") + name = c.contactAbout.name; + return h('span.status', + ['Followed ', + h('a', { href: base + c.contact }, name)]); } else if (c.type == "contact" && !c.following) { var name = c.contact; - if (typeof c.contactAbout != "undefined") name = c.contactAbout.name; - return '' + - 'Unfollowed ' + name + "" + - ''; + if (typeof c.contactAbout != "undefined") + name = c.contactAbout.name; + return h('span.status', + ['Unfollowed ', + h('a', { href: base + c.contact }, name)]); } else if (typeof c == "string") { - return '' + - "Wrote something private" + - ''; + return h('span.status', 'Wrote something private') } else if (c.type == "about") { - return '' + - "Changed something in about" + - '' + - renderDefault(c); + return [h('span.status', 'Changed something in about'), + renderDefault(c)]; } else if (c.type == "issue") { - return '' + - "Created a git issue" + (c.repoName != undefined ? " in repo " + c.repoName : "") + renderPost(opts, c) + - ''; + return [h('span.status', + "Created a git issue" + + (c.repoName != undefined ? " in repo " + c.repoName : ""), + renderPost(opts, c))]; } else if (c.type == "git-update") { - return '' + - "Did a git update " + (c.repoName != undefined ? " in repo " + c.repoName : "") + - "
" + - (c.commits != undefined ? c.commits.map(com => { return "-" +com.title; }).join("
") : "") + - '
' + return h('span.status', + "Did a git update " + + (c.repoName != undefined ? " in repo " + c.repoName : "") + + '
' + + (c.commits != undefined ? + c.commits.map(com => { return "-" +com.title; }).join('
') : "")); } else if (c.type == "ssb-dns") { - return '' + - "Updated DNS" + - '' + - renderDefault(c); + return [h('span.status', 'Updated DNS'), renderDefault(c)]; } else if (c.type == "pub") { - return '' + - "Connected to the pub " + c.address.host + - '' + return h('span.status', 'Connected to the pub ' + c.address.host); } else if (c.type == "channel" && c.subscribed) - return '' + - 'Subscribed to channel #' + - c.channel + - "" + - ''; + return h('span.status', + 'Subscribed to channel ', + h('a', + { href: base + 'channel/' + c.channel }, + '#' + c.channel)); else if (c.type == "channel" && !c.subscribed) - return '' + - 'Unsubscribed from channel #' + - c.channel + - "" + - ''; + return h('span.status', + 'Unsubscribed from channel ', + h('a', + { href: base + 'channel/' + c.channel }, + '#' + c.channel)) else return renderDefault(c); } function renderPost(opts, c) { opts.mentions = {}; - if (Array.isArray(c.mentions)) c.mentions.forEach(function (link) { - if (link && link.name && link.link) opts.mentions[link.name] = link.link; - }); - return '
' + marked(String(c.text), opts.marked) + "
"; + if (Array.isArray(c.mentions)) { + c.mentions.forEach(function (link) { + if (link && link.name && link.link) + opts.mentions[link.name] = link.link; + }); + } + var s = h('section'); + s.innerHTML = marked(String(c.text), opts.marked); + return s; } function renderDefault(c) { - return "
" + JSON.stringify(c, 0, 2) + "
"; + return h('pre', JSON.stringify(c, 0, 2)); }