secure-scuttlebot classic
at main 4.5 kB view raw
1var pull = require('pull-stream') 2var Cat = require('pull-cat') 3var sort = require('ssb-sort') 4var ref = require('ssb-ref') 5var h = require('hyperscript') 6var u = require('../util') 7var Scroller = require('pull-scroll') 8var self_id = require('../keys').id 9 10function once (cont) { 11 var ended = false 12 return function (abort, cb) { 13 if(abort) return cb(abort) 14 else if (ended) return cb(ended) 15 else 16 cont(function (err, data) { 17 if(err) return cb(ended = err) 18 ended = true 19 cb(null, data) 20 }) 21 } 22} 23 24//var plugs = require('../plugs') 25// 26//var message_render = plugs.first(exports.message_render = []) 27//var message_name = plugs.first(exports.message_name = []) 28//var message_compose = plugs.first(exports.message_compose = []) 29//var message_unbox = plugs.first(exports.message_unbox = []) 30// 31//var sbot_get = plugs.first(exports.sbot_get = []) 32//var sbot_links = plugs.first(exports.sbot_links = []) 33 34exports.needs = { 35 message_render: 'first', 36 message_name: 'first', 37 message_compose: 'first', 38 message_unbox: 'first', 39 sbot_get: 'first', 40 sbot_links: 'first' 41} 42 43exports.gives = 'screen_view' 44 45 46exports.create = function (api) { 47 48 function getThread (root, cb) { 49 //in this case, it's inconvienent that panel only takes 50 //a stream. maybe it would be better to accept an array? 51 52 api.sbot_get(root, function (err, value) { 53 if (err) return cb(err) 54 var msg = {key: root, value: value} 55 // if(value.content.root) return getThread(value.content.root, cb) 56 57 pull( 58 api.sbot_links({rel: 'root', dest: root, values: true, keys: true}), 59 pull.collect(function (err, ary) { 60 if(err) return cb(err) 61 ary.unshift(msg) 62 cb(null, ary) 63 }) 64 ) 65 }) 66 67 } 68 69 return function (id) { 70 if(ref.isMsg(id)) { 71 function normalizeId (value) { 72 try { return decodeURIComponent(value) } catch (err) { return value } 73 } 74 var normalizedId = normalizeId(id) 75 var autoOpen = false 76 try { 77 autoOpen = window.sessionStorage.getItem('decent_reply_intent') === normalizedId 78 if (autoOpen) window.sessionStorage.removeItem('decent_reply_intent') 79 } catch (err) {} 80 81 var meta = { 82 type: 'post', 83 root: id, 84 branch: id //mutated when thread is loaded. 85 } 86 87 var content = h('div.column.scroller__content') 88 var div = h('div.column.scroller', 89 {style: {'overflow-y': 'auto'}}, 90 h('div.scroller__wrapper', 91 content, 92 api.message_compose( 93 meta, 94 { 95 shrink: false, 96 placeholder: 'Write a reply', 97 modal: true, 98 triggerLabel: 'Reply', 99 title: 'Reply', 100 autoOpen: autoOpen, 101 listenReplyEvents: true 102 } 103 ) 104 ) 105 ) 106 107 api.message_name(id, function (err, name) {}) 108 109 pull( 110 api.sbot_links({ 111 rel: 'root', dest: id, keys: true, old: false 112 }), 113 pull.drain(function (msg) { 114 loadThread() //redraw thread 115 }, function () {} ) 116 ) 117 118 119 function loadThread () { 120 getThread(id, function (err, thread) { 121 //would probably be better keep an id for each message element 122 //(i.e. message key) and then update it if necessary. 123 //also, it may have moved (say, if you received a missing message) 124 content.innerHTML = '' 125 if(err) return content.appendChild(h('pre', err.stack)) 126 127 //decrypt 128 thread = thread.map(function (msg) { 129 return 'string' === typeof msg.value.content ? api.message_unbox(msg) : msg 130 }) 131 132 if(err) return content.appendChild(h('pre', err.stack)) 133 sort(thread).map(api.message_render).filter(Boolean).forEach(function (el) { 134 content.appendChild(el) 135 }) 136 137 var branches = sort.heads(thread) 138 meta.branch = branches.length > 1 ? branches : branches[0] 139 meta.root = thread[0].value.content.root || thread[0].key 140 meta.channel = thread[0].value.content.channel 141 142 var recps = thread[0].value.content.recps 143 var private = thread[0].value.private 144 if(private) { 145 if(recps) 146 meta.recps = recps 147 else 148 meta.recps = [thread[0].value.author, self_id] 149 } 150 }) 151 } 152 153 loadThread() 154 return div 155 } 156 } 157}