var h = require('hyperscript') var pull = require('pull-stream') var human = require('human-time') var sbot = require('./scuttlebot') var composer = require('./compose') var tools = require('./tools') var ref = require('ssb-ref') var config = require('./config')() var id = require('./keys').id var avatar = require('./avatar') var ssbAvatar = require('ssb-avatar') var ssbKeys = require('ssb-keys') var keys = require('./keys') var diff = require('diff') function hash () { return window.location.hash.substring(1) } module.exports.render = function (msg) { var messageExists = (document.getElementById(msg.key.substring(0, 44)) !== null); if (!messageExists) { var message = h('div.message#' + msg.key.substring(0, 44)) //console.log(msg) var messageContent = h('div.messageContent') message.appendChild(messageContent) pull( sbot.backlinks({ query: [{$filter: {dest: msg.key}}], live: true, reverse: false, index: 'DTA' }), pull.drain(function (data) { if (data.sync) { } else { if (data.value.content.type == 'vote') { var subMessageExists = (document.getElementById(data.key.substring(0, 44)) !== null) if (msg.key == data.value.content.vote.link) { if (data.value.content.vote.value == 1) { var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'star.png'}), ' ', h('a', {href: '#' + data.value.content.vote.link}, tools.messageLink(data.value.content.vote.link))) if (!subMessageExists) { message.appendChild(h('div.submessage', h('div.messageContent', tools.mini(data, link)))) } if (data.value.author == id) { var gotIt = document.getElementById('votebutton:' + msg.key.substring(0,44)) if (gotIt != null) { gotIt.parentNode.appendChild(tools.unstar(msg)) gotIt.parentNode.removeChild(gotIt) } } } else if (data.value.content.vote.value == -1) { var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'stars.png'}), ' ', h('a', {href: '#' + data.value.content.vote.link}, tools.messageLink(data.value.content.vote.link))) if (!subMessageExists) { message.appendChild(h('div.submessage', h('div.messageContent', tools.mini(data, link)))) } if (data.value.author == id) { var gotIt = document.getElementById('votebutton:' + msg.key.substring(0,44)) if (gotIt != null) { gotIt.parentNode.appendChild(tools.star(msg)) gotIt.parentNode.removeChild(gotIt) } } } } } else if (!subMessageExists) { if (data.value.content.type == 'post') { if ( (msg.key == data.value.content.root) || (msg.value.content.root == data.value.content.root) ) { message.appendChild(h('div.submessage', (exports.render(data)))) } } else if (data.value.content.type == 'git-update') { message.appendChild(h('div.submessage', (exports.render(data)))) } else { var link = h('span', ' backlinked from ', tools.messageLink(data.key)) message.appendChild(h('div.submessage', h('div.messageContent', tools.mini(data, link)))) } } else { //console.log('message already rendered') } } }) ) if (msg.value.content.type == 'post') { var opts = { type: 'post', branch: msg.key } var fallback = {} if (msg.value.content.root) opts.root = msg.value.content.root else opts.root = msg.key messageContent.appendChild(tools.header(msg)) if (msg.value.content.root) { messageContent.appendChild(h('span', 're: ', tools.messageLink(msg.value.content.root))) } messageContent.appendChild(h('div.message__body', tools.markdown(msg.value.content.text))) var name = avatar.name(msg.value.author) var buttons = h('div.buttons') buttons.appendChild(h('button.btn', 'Reply', { onclick: function () { opts.type = 'post' opts.mentions = '[' + name.textContent + '](' + msg.value.author + ')' if (msg.value.content.recps) { opts.recps = msg.value.content.recps } var r = messageContent.childNodes.length - 1 delete opts.updated delete opts.original delete fallback.messageText fallback.buttons = messageContent.childNodes[r] var compose = h('div.submessage#re:' + msg.key.substring(0, 44), h('div.messageContent', composer(opts, fallback))) messageContent.removeChild(messageContent.childNodes[r]) message.parentNode.insertBefore(compose, message.nextSibling) } })) buttons.appendChild(h('button.btn', 'Edit', { onclick: function () { opts.type = 'edit' if (!fallback.messageText) fallback.messageText = msg.value.content.text if (!opts.updated) opts.updated = msg.key opts.original = msg.key var r = messageContent.childNodes.length - 1 fallback.buttons = messageContent.childNodes[r] messageContent.removeChild(messageContent.childNodes[r]) var compose = h('div#edit:' + msg.key.substring(0, 44), composer(opts, fallback)) messageContent.replaceChild(compose, messageContent.lastElementChild) } })) buttons.appendChild(h('button.btn', 'Boost', { onclick: function () { opts.type = 'post' opts.mentions = '[' + name.textContent + '](' + msg.value.author + ')' if (msg.value.content.recps) { opts.recps = msg.value.content.recps } var r = messageContent.childNodes.length - 1 delete opts.updated delete opts.original delete fallback.messageText opts.boostContent = msg.value.content.text opts.boostKey = msg.key opts.boostAuthor = msg.value.author fallback.buttons = messageContent.childNodes[r] var compose = h('div.submessage#re:' + msg.key.substring(0, 44), h('div.messageContent', composer(opts, fallback))) messageContent.removeChild(messageContent.childNodes[r]) message.parentNode.insertBefore(compose, message.nextSibling) } })) buttons.appendChild(tools.star(msg)) messageContent.appendChild(buttons) return message } if (msg.value.content.type == 'vote') { if (msg.value.content.vote.value == 1) var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'star.png'}), ' ', h('a', {href: '#' + msg.value.content.vote.link}, tools.messageLink(msg.value.content.vote.link))) else if (msg.value.content.vote.value == -1) var link = h('span', ' ', h('img.emoji', {src: config.emojiUrl + 'stars.png'}), ' ', h('a', {href: '#' + msg.value.content.vote.link}, tools.messageLink(msg.value.content.vote.link))) messageContent.appendChild(tools.mini(msg, link)) return message } if (msg.value.content.type == 'about') { if (msg.value.content.image) { if (ref.isBlob(msg.value.content.image.link)) { var image = h('img', {src: config.blobsUrl + msg.value.content.image.link}) } else if (ref.isBlob(msg.value.content.image)) { var image = h('img', {src: config.blobsUrl + msg.value.content.image}) } else { console.log('Not a valid image')} var content = h('span.avatar--small', ' identified ', h('a', {href: '#' + msg.value.content.about}, avatar.cachedName(msg.value.content.about)), ' as ', image ) messageContent.appendChild(tools.mini(msg, content)) return message } if (msg.value.content.name) { var name = h('span', ' identified ', h('a', {href: '#' + msg.value.content.about}, avatar.cachedName(msg.value.content.about)), ' as ', msg.value.content.name ) messageContent.appendChild(tools.mini(msg, name)) return message } } if (msg.value.content.type == 'label'){ var content = h('span', ' labeled ', tools.messageLink(msg.value.content.link), ' as ', h('mark', h('a', {href: '#label/' + msg.value.content.label}, msg.value.content.label))) messageContent.appendChild(tools.mini(msg, content)) return message } if (msg.value.content.type == 'queue') { if (msg.value.content.queue == true) { var content = h('span', ' added ', tools.messageLink(msg.value.content.message), ' to their ', h('a', {href: '#queue'}, 'queue')) messageContent.appendChild(tools.mini(msg, content)) } if (msg.value.content.queue == false) { var content = h('span', ' removed ', tools.messageLink(msg.value.content.message), ' from their ', h('a', {href: '#queue'}, 'queue')) messageContent.appendChild(tools.mini(msg, content)) } return message } if (msg.value.content.type == 'scat_message') { var src = hash() if (src != 'backchannel') { messageContent.appendChild(h('button.btn.right', h('a', {href: '#backchannel'}, 'Chat'))) } messageContent.appendChild(tools.mini(msg, ' ' + msg.value.content.text)) return message } else if (msg.value.content.type == 'contact') { if (msg.value.content.contact) { var contact = h('a', {href: '#' + msg.value.content.contact}, avatar.name(msg.value.content.contact)) } else { var contact = h('p', 'no contact named')} if (msg.value.content.following == true) { var following = h('span', ' follows ', contact) messageContent.appendChild(tools.mini(msg, following)) } if (msg.value.content.following == false) { var unfollowing = h('span', ' unfollows ', contact) messageContent.appendChild(tools.mini(msg, unfollowing)) } if (msg.value.content.blocking == true) { var blocking = h('span', ' blocks ', contact) messageContent.appendChild(tools.mini(msg, blocking)) } if (msg.value.content.blocking == false) { var unblocking = h('span', ' unblocks ', contact) messageContent.appendChild(tools.mini(msg, unblocking)) } return message } if (msg.value.content.type == 'git-update') { messageContent.appendChild(tools.header(msg)) var reponame = h('p', 'pushed to ', h('a', {href: '#' + msg.value.content.repo}, msg.value.content.repo)) var cloneurl = h('pre', 'git clone ssb://' + msg.value.content.repo) messageContent.appendChild(reponame) ssbAvatar(sbot, id, msg.value.content.repo, function (err, data) { if (data) { var actualname = h('p', 'pushed to ', h('a', {href: '#' + msg.value.content.repo}, '%' + data.name)) reponame.parentNode.replaceChild(actualname, reponame) } }) messageContent.appendChild(cloneurl) var commits = h('ul') if (msg.value.content.commits) { msg.value.content.commits.map(function (commit) { commits.appendChild(h('li', h('code', commit.sha1), ' - ', commit.title)) }) } messageContent.appendChild(commits) return message } if (msg.value.content.type == 'git-repo') { messageContent.appendChild(tools.header(msg)) var reponame = h('p', 'git-ssb repo ', h('a', {href: '#' + msg.key}, msg.key)) messageContent.appendChild(reponame) ssbAvatar(sbot, id, msg.key, function (err, data) { if (data) var actualname = h('p', 'git-ssb repo ', h('a', {href: '#' + msg.key}, '%' + data.name)) reponame.parentNode.replaceChild(actualname, reponame) }) var cloneurl = h('pre', 'git clone ssb://' + msg.key) messageContent.appendChild(cloneurl) return message } if (typeof msg.value.content === 'string') { var unboxed = ssbKeys.unbox(msg.value.content, keys) if (unboxed) { msg.value.content = unboxed msg.value.private = true return exports.render(msg) } else { var privateMsg = h('span', ' sent a private message.') messageContent.appendChild(tools.mini(msg, privateMsg)) return message } } else { //FULL FALLBACK //message.appendChild(tools.header(msg)) messageContent.appendChild(tools.header(msg)) messageContent.appendChild(h('pre', tools.rawJSON(msg.value))) //MINI FALLBACK //var fallback = h('span', ' ' + msg.value.content.type) //message.appendChild(tools.mini(msg, fallback)) return message } } }