git ssb

16+

Dominic / patchbay



Commit b85e0e914249723b9baa871cf50ede60a7ba2a55

update modules_extra/ to use new depject

Dominic Tarr committed on 12/4/2016, 4:04:29 PM
Parent: 8cf292c13507a00dd6f025dfa662409737ba7dea

Files changed

index.jschanged
modules_basic/compose.jschanged
modules_basic/search-box.jschanged
modules_basic/suggest-mentions.jschanged
modules_basic/thread.jschanged
modules_extra/audio-mp3.jschanged
modules_extra/channel.jschanged
modules_extra/dns.jschanged
modules_extra/emoji.jschanged
modules_extra/git-ssb.jschanged
modules_extra/git.jschanged
modules_extra/meta-image.jschanged
modules_extra/music-release-cc.jschanged
modules_extra/music-release.jschanged
modules_extra/network.jschanged
modules_extra/notifications.jschanged
modules_extra/query.jschanged
modules_extra/raw.jschanged
modules_extra/search.jschanged
modules_extra/split.jschanged
modules_extra/suggest-emoji.jschanged
modules_extra/versions.jschanged
index.jsView
@@ -2,6 +2,6 @@
22 // from more specialized to more general
33 require('./modules_extra'),
44 require('./modules_basic'),
55 require('./modules_core')
6-).plugs.app[0]()
6 +).app[0]()
77
modules_basic/compose.jsView
@@ -102,9 +102,9 @@
102102 publishBtn.disabled = false
103103 if (cb) cb(err)
104104 else alert(err.message)
105105 }
106- return message_confirm(meta, done)
106 + return api.message_confirm(meta, done)
107107 }
108108
109109 api.message_confirm(content, done)
110110
@@ -136,13 +136,14 @@
136136 )
137137 )
138138
139139 suggest(ta, function (name, cb) {
140- cont.para(suggest_mentions.map(function (e) { return e(name) }))
140 + cont.para(api.suggest_mentions(name))
141141 (function (err, ary) {
142142 cb(null, ary.reduce(function (a, b) {
143 + if(!b) return a
143144 return a.concat(b)
144- }))
145 + }, []))
145146 })
146147 }, {})
147148
148149 return composer
@@ -150,4 +151,5 @@
150151 }
151152
152153 }
153154
155 +
modules_basic/search-box.jsView
@@ -59,16 +59,20 @@
5959
6060 // delay until the element has a parent
6161 setTimeout(function () {
6262 suggestBox = suggest(search, function (word, cb) {
63- cont.para(api.suggest_search.map(function (e) {
64- return function (cb) { e(word, cb) }
65- }))(cb)
63 + cont.para(api.suggest_search(word))
64 + (function (err, ary) {
65 + if(err) return cb(err)
66 +
67 + cb(null, ary.filter(Boolean).reduce(function (a, b) {
68 + return a.concat(b)
69 + }, []))
70 + })
6671 }, {})
6772 }, 10)
6873
6974 return search
7075 }
7176
7277 }
7378
74-
modules_basic/suggest-mentions.jsView
@@ -11,9 +11,9 @@
1111 exports.needs = {
1212 sbot_links2: 'first',
1313 blob_url: 'first',
1414 signified: 'first',
15- bultin_tabs: 'map'
15 + builtin_tabs: 'map'
1616 }
1717
1818 exports.gives = {
1919 suggest_mentions: true,
@@ -40,31 +40,33 @@
4040 })
4141 }
4242 },
4343
44- suggest_search: function (query, cb) {
45- if(/^[@%]\w/.test(query)) {
46- api.signified(query, function (_, names) {
47- cb(null, names.map(function (e) {
44 + suggest_search: function (query) {
45 + return function (cb) {
46 + if(/^[@%]\w/.test(query)) {
47 + api.signified(query, function (_, names) {
48 + cb(null, names.map(function (e) {
49 + return {
50 + title: e.name + ':'+e.id.substring(0, 10),
51 + value: e.id,
52 + subtitle: e.rank,
53 + rank: e.rank
54 + }
55 + }))
56 + })
57 +
58 + } else if(/^\//.test(query)) {
59 + var tabs = [].concat.apply([], api.builtin_tabs())
60 + cb(null, tabs.filter(function (name) {
61 + return name.substr(0, query.length) === query
62 + }).map(function (name) {
4863 return {
49- title: e.name + ':'+e.id.substring(0, 10),
50- value: e.id,
51- subtitle: e.rank,
52- rank: e.rank
64 + title: name,
65 + value: name,
5366 }
5467 }))
55- })
56-
57- } else if(/^\//.test(query)) {
58- var tabs = [].concat.apply([], builtin_tabs())
59- cb(null, tabs.filter(function (name) {
60- return name.substr(0, query.length) === query
61- }).map(function (name) {
62- return {
63- title: name,
64- value: name,
65- }
66- }))
67- } else cb()
68 + } else cb()
69 + }
6870 }
6971 }
7072 }
modules_basic/thread.jsView
@@ -106,9 +106,9 @@
106106 if(err) return content.appendChild(h('pre', err.stack))
107107
108108 //decrypt
109109 thread = thread.map(function (msg) {
110- return 'string' === typeof msg.value.content ? message_unbox(msg) : msg
110 + return 'string' === typeof msg.value.content ? api.message_unbox(msg) : msg
111111 })
112112
113113 if(err) return content.appendChild(h('pre', err.stack))
114114 sort(thread).map(api.message_render).filter(Boolean).forEach(function (el) {
modules_extra/audio-mp3.jsView
@@ -4,25 +4,36 @@
44 var ref = require('ssb-ref');
55
66 //render a message
77
8-var plugs = require('../plugs');
9-var message_link = plugs.first(exports.message_link = []);
10-var message_confirm = plugs.first(exports.message_confirm = []);
11-var sbot_links = plugs.first(exports.sbot_links = []);
12-var blob_url = plugs.first(exports.blob_url = []);
8 +//var plugs = require('../plugs');
9 +//var message_link = plugs.first(exports.message_link = []);
10 +//var message_confirm = plugs.first(exports.message_confirm = []);
11 +//var sbot_links = plugs.first(exports.sbot_links = []);
12 +//var blob_url = plugs.first(exports.blob_url = []);
13 +//
14 +exports.needs = {
15 +// message_link: 'first',
16 +// message_confirm: 'first',
17 +// sbot_links: 'first',
18 + blobs_url: 'first'
19 +}
1320
14-exports.message_content = function(msg, sbot) {
21 +exports.gives = 'message_content'
22 +
23 +exports.create = function (api) {
24 +
25 + return function(msg) {
1526 if (msg.value.content.type !== 'audio-mp3')
1627 return;
1728
1829 var v = msg.value.content;
1930 return h('div',
2031 h('h2', "(" + v.Track + ") " + v.Title),
21- // h('img', { "src" : blob_url(v.cover) }),
32 + // h('img', { "src" : api.blob_url(v.cover) }),
2233 h('audio', {
2334 "controls" : true,
24- "src" : blob_url(v.link)
35 + "src" : api.blob_url(v.link)
2536 }))
2637 // h('dl',
2738 // Object.keys(v).map(function(k) {
2839 // return [
@@ -45,7 +56,7 @@
4556
4657 // "Title": "clouds",
4758 // "Track": "2",
4859 // "Width": "0",
49-
60 + }
5061 }
5162
modules_extra/channel.jsView
@@ -1,104 +1,123 @@
11 var h = require('hyperscript')
22 var u = require('../util')
33 var pull = require('pull-stream')
44 var Scroller = require('pull-scroll')
5-
6-var plugs = require('../plugs')
7-var message_render = plugs.first(exports.message_render = [])
8-var message_compose = plugs.first(exports.message_compose = [])
9-var sbot_log = plugs.first(exports.sbot_log = [])
10-var sbot_query = plugs.first(exports.sbot_query = [])
115 var mfr = require('map-filter-reduce')
126
13-exports.message_meta = function (msg) {
14- var chan = msg.value.content.channel
15- if (chan)
16- return h('a', {href: '##'+chan}, '#'+chan)
7 +//var plugs = require('../plugs')
8 +//var message_render = plugs.first(exports.message_render = [])
9 +//var message_compose = plugs.first(exports.message_compose = [])
10 +//var sbot_log = plugs.first(exports.sbot_log = [])
11 +//var sbot_query = plugs.first(exports.sbot_query = [])
12 +
13 +exports.needs = {
14 + message_render: 'first',
15 + message_compose: 'first',
16 + sbot_log: 'first',
17 + sbot_query: 'first',
1718 }
1819
19-exports.screen_view = function (path) {
20- if(path[0] === '#') {
21- var channel = path.substr(1)
20 +exports.gives = {
21 + message_meta: true, screen_view: true,
22 + connection_status: true, suggest_search: true
23 +}
2224
23- var content = h('div.column.scroller__content')
24- var div = h('div.column.scroller',
25- {style: {'overflow':'auto'}},
26- h('div.scroller__wrapper',
27- message_compose({type: 'post', channel: channel}),
28- content
29- )
30- )
25 +exports.create = function (api) {
3126
32- function matchesChannel(msg) {
33- if (msg.sync) console.error('SYNC', msg)
34- var c = msg && msg.value && msg.value.content
35- return c && c.channel === channel
36- }
27 + var channels
3728
38- pull(
39- sbot_log({old: false}),
40- pull.filter(matchesChannel),
41- Scroller(div, content, message_render, true, false)
42- )
29 + var filter = {$filter: {value: {content: {channel: {$gt: ''}}}}}
30 + var map = {$map: {'name': ['value', 'content', 'channel']}}
31 + var reduce = {$reduce: {
32 + name: 'name',
33 + rank: {$count: true}
34 + }}
4335
44- pull(
45- sbot_query({reverse: true, query: [
46- {$filter: {value: {content: {channel: channel}}}}
47- ]}),
48- Scroller(div, content, message_render, false, false)
49- )
36 + return {
37 + message_meta: function (msg) {
38 + var chan = msg.value.content.channel
39 + if (chan)
40 + return h('a', {href: '##'+chan}, '#'+chan)
41 + },
42 + screen_view: function (path) {
43 + if(path[0] === '#') {
44 + var channel = path.substr(1)
5045
51- return div
52- }
53-}
46 + var content = h('div.column.scroller__content')
47 + var div = h('div.column.scroller',
48 + {style: {'overflow':'auto'}},
49 + h('div.scroller__wrapper',
50 + api.message_compose({type: 'post', channel: channel}),
51 + content
52 + )
53 + )
5454
55-var channels
55 + function matchesChannel(msg) {
56 + if (msg.sync) console.error('SYNC', msg)
57 + var c = msg && msg.value && msg.value.content
58 + return c && c.channel === channel
59 + }
5660
57-var filter = {$filter: {value: {content: {channel: {$gt: ''}}}}}
58-var map = {$map: {'name': ['value', 'content', 'channel']}}
59-var reduce = {$reduce: {
60- name: 'name',
61- rank: {$count: true}
62-}}
61 + pull(
62 + api.sbot_log({old: false}),
63 + pull.filter(matchesChannel),
64 + Scroller(div, content, message_render, true, false)
65 + )
6366
64-exports.connection_status = function (err) {
65- if(err) return
67 + pull(
68 + api.sbot_query({reverse: true, query: [
69 + {$filter: {value: {content: {channel: channel}}}}
70 + ]}),
71 + Scroller(div, content, message_render, false, false)
72 + )
6673
67- channels = []
74 + return div
75 + }
76 + },
6877
69- pull(
70- sbot_query({query: [filter, map, reduce]}),
71- pull.collect(function (err, chans) {
72- if (err) return console.error(err)
73- channels = chans.concat(channels)
74- })
75- )
78 + connection_status: function (err) {
79 + if(err) return
7680
77- pull(
78- sbot_log({old: false}),
79- mfr.filter(filter),
80- mfr.map(map),
81- pull.drain(function (chan) {
82- var c = channels.find(function (e) {
83- return e.name === chan.name
84- })
85- if (c) c.rank++
86- else channels.push(chan)
87- })
88- )
89-}
81 + channels = []
9082
91-exports.suggest_search = function (query, cb) {
92- if(!/^#\w/.test(query)) return cb()
93- cb(null, channels.filter(function (chan) {
94- return ('#'+chan.name).substring(0, query.length) === query
95- })
96- .map(function (chan) {
97- var name = '#'+chan.name
98- return {
99- title: name,
100- value: name,
101- subtitle: chan.rank
83 + pull(
84 + api.sbot_query({query: [filter, map, reduce]}),
85 + pull.collect(function (err, chans) {
86 + if (err) return console.error(err)
87 + channels = chans.concat(channels)
88 + })
89 + )
90 +
91 + pull(
92 + api.sbot_log({old: false}),
93 + mfr.filter(filter),
94 + mfr.map(map),
95 + pull.drain(function (chan) {
96 + var c = channels.find(function (e) {
97 + return e.name === chan.name
98 + })
99 + if (c) c.rank++
100 + else channels.push(chan)
101 + })
102 + )
103 + },
104 +
105 + suggest_search: function (query) {
106 + return function (cb) {
107 + if(!/^#\w/.test(query)) return cb()
108 + cb(null, channels.filter(function (chan) {
109 + return ('#'+chan.name).substring(0, query.length) === query
110 + })
111 + .map(function (chan) {
112 + var name = '#'+chan.name
113 + return {
114 + title: name,
115 + value: name,
116 + subtitle: chan.rank
117 + }
118 + }))
119 + }
102120 }
103- }))
121 + }
104122 }
123 +
modules_extra/dns.jsView
@@ -7,22 +7,27 @@
77 function idLink(id) {
88 return h('a', {href: '#'+id}, id.substring(0, 10)+'…')
99 }
1010
11-exports.message_content = function (msg, sbot) {
12- var c = msg.value.content
11 +exports.gives = 'message_content'
1312
14- if(c.type === 'ssb-dns') {
15- var record = c.record || {}
16- return h('div',
17- h('p',
18- h('ins', {title: 'name'}, record.name), ' ',
19- h('em', {title: 'ttl'}, record.ttl), ' ',
20- h('span', {title: 'class'}, record.class), ' ',
21- h('span', {title: 'type'}, record.type),
22- h('pre', {title: 'data'},
23- JSON.stringify(record.data || record.value, null, 2)),
24- !c.branch ? null : h('div', h('span',
25- 'replaces: ', array(c.branch).map(idLink)))
26- ))
13 +exports.create = function () {
14 + return function (msg, sbot) {
15 + var c = msg.value.content
16 +
17 + if(c.type === 'ssb-dns') {
18 + var record = c.record || {}
19 + return h('div',
20 + h('p',
21 + h('ins', {title: 'name'}, record.name), ' ',
22 + h('em', {title: 'ttl'}, record.ttl), ' ',
23 + h('span', {title: 'class'}, record.class), ' ',
24 + h('span', {title: 'type'}, record.type),
25 + h('pre', {title: 'data'},
26 + JSON.stringify(record.data || record.value, null, 2)),
27 + !c.branch ? null : h('div', h('span',
28 + 'replaces: ', array(c.branch).map(idLink)))
29 + ))
30 + }
2731 }
32 +
2833 }
modules_extra/emoji.jsView
@@ -1,14 +1,22 @@
11 var emojis = require('emoji-named-characters')
22 var emojiNames = Object.keys(emojis)
33
4-var plugs = require('../plugs')
5-var blob_url = plugs.first(exports.blob_url = [])
4 +//var plugs = require('../plugs')
5 +//var blob_url = plugs.first(exports.blob_url = [])
6 +//
67
7-exports.emoji_names = function () {
8- return emojiNames
8 +exports.needs = { blob_url: 'first' }
9 +exports.gives = { emoji_names: true, emoji_url: true }
10 +
11 +exports.create = function (api) {
12 + return {
13 + emoji_names: function () {
14 + return emojiNames
15 + },
16 + emoji_url: function (emoji) {
17 + return emoji in emojis &&
18 + api.blob_url(emoji).replace(/\/blobs\/get/, '/img/emoji') + '.png'
19 + }
20 + }
921 }
1022
11-exports.emoji_url = function (emoji) {
12- return emoji in emojis &&
13- blob_url(emoji).replace(/\/blobs\/get/, '/img/emoji') + '.png'
14-}
modules_extra/git-ssb.jsView
@@ -2,40 +2,53 @@
22 var u = require('../util')
33 var pull = require('pull-stream')
44 var Scroller = require('pull-scroll')
55
6-var plugs = require('../plugs')
7-var message_render = plugs.first(exports.message_render = [])
8-var message_compose = plugs.first(exports.message_compose = [])
9-var sbot_log = plugs.first(exports.sbot_log = [])
6 +//var plugs = require('../plugs')
7 +//var message_render = plugs.first(exports.message_render = [])
8 +//var message_compose = plugs.first(exports.message_compose = [])
9 +//var sbot_log = plugs.first(exports.sbot_log = [])
1010
11-exports.menu_items = function () {
12- return h('a', {href: '#/git-ssb'}, '/git-ssb')
11 +exports.needs = {
12 + message_render: 'first',
13 + message_compose: 'first',
14 + sbot_log: 'first'
1315 }
1416
15-exports.screen_view = function (path, sbot) {
16- if(path === '/git-ssb') {
17 +exports.gives = {
18 + menu_items: true, screen_view: true
19 +}
1720
18- var content = h('div.column.scroller__content')
19- var div = h('div.column.scroller',
20- {style: {'overflow':'auto'}},
21- h('div.scroller__wrapper', content)
22- )
21 +exports.create = function (api) {
22 + return {
23 + menu_items: function () {
24 + return h('a', {href: '#/git-ssb'}, '/git-ssb')
25 + },
2326
24- pull(
25- u.next(sbot_log, {old: false, limit: 100}),
26- Scroller(div, content, message_render, true, false)
27- )
27 + screen_view: function (path, sbot) {
28 + if(path === '/git-ssb') {
2829
29- pull(
30- u.next(sbot_log, {reverse: true, limit: 100, live: false}),
31- pull.filter(function(msg) { return msg.value.content.type }),
32- pull.filter(function(msg) {
33- return msg.value.content.type.match(/^git/)
34- }),
35- Scroller(div, content, message_render, false, false)
36- )
30 + var content = h('div.column.scroller__content')
31 + var div = h('div.column.scroller',
32 + {style: {'overflow':'auto'}},
33 + h('div.scroller__wrapper', content)
34 + )
3735
38- return div
36 + pull(
37 + u.next(api.sbot_log, {old: false, limit: 100}),
38 + Scroller(div, content, api.message_render, true, false)
39 + )
40 +
41 + pull(
42 + u.next(api.sbot_log, {reverse: true, limit: 100, live: false}),
43 + pull.filter(function(msg) { return msg.value.content.type }),
44 + pull.filter(function(msg) {
45 + return msg.value.content.type.match(/^git/)
46 + }),
47 + Scroller(div, content, api.message_render, false, false)
48 + )
49 +
50 + return div
51 + }
52 + }
3953 }
4054 }
41-
modules_extra/git.jsView
@@ -1,491 +1,519 @@
1 +'use strict'
12 var h = require('hyperscript')
23 var pull = require('pull-stream')
34 var paramap = require('pull-paramap')
45 var cat = require('pull-cat')
56 var human = require('human-time')
67 var combobox = require('hypercombo')
78
8-var plugs = require('../plugs')
9-var message_link = plugs.first(exports.message_link = [])
10-var message_confirm = plugs.first(exports.message_confirm = [])
11-var message_compose = plugs.first(exports.message_compose = [])
12-var sbot_links = plugs.first(exports.sbot_links = [])
13-var sbot_links2 = plugs.first(exports.sbot_links2 = [])
14-var sbot_get = plugs.first(exports.sbot_get = [])
159 var getAvatar = require('ssb-avatar')
16-var avatar_name = plugs.first(exports.avatar_name = [])
17-var markdown = plugs.first(exports.markdown = [])
1810 var KVGraph = require('kvgraph')
1911 var mergeRepo = require('ssb-git/merge')
2012
21-var self_id = require('../keys').id
13 +//var plugs = require('../plugs')
14 +//var message_link = plugs.first(exports.message_link = [])
15 +//var message_confirm = plugs.first(exports.message_confirm = [])
16 +//var message_compose = plugs.first(exports.message_compose = [])
17 +//var sbot_links = plugs.first(exports.sbot_links = [])
18 +//var sbot_links2 = plugs.first(exports.sbot_links2 = [])
19 +//var sbot_get = plugs.first(exports.sbot_get = [])
20 +//var avatar_name = plugs.first(exports.avatar_name = [])
21 +//var markdown = plugs.first(exports.markdown = [])
2222
23-function shortRefName(ref) {
24- return ref.replace(/^refs\/(heads|tags)\//, '')
23 +exports.needs = {
24 + message_link: 'first',
25 + message_confirm: 'first',
26 + message_compose: 'first',
27 + sbot_links: 'first',
28 + sbot_links2: 'first',
29 + sbot_get: 'first',
30 + avatar_name: 'first',
31 + markdown: 'first'
2532 }
2633
27-function getRefs(msg) {
28- var updates = new KVGraph('key')
29- var _cb, _refs
30- pull(
31- sbot_links({
32- reverse: true,
33- // source: msg.value.author,
34- dest: msg.key,
35- rel: 'repo',
36- values: true
37- }),
38- pull.drain(function (link) {
39- if (link.value.content.type === 'git-update') {
40- updates.add(link)
41- }
42- }, function (err) {
43- var refs = updates.reduceRight(mergeRepo).refs
44- var cb = _cb
45- if (cb) delete _cb, cb(err, refs)
46- else _refs = refs
47- })
48- )
49-
50- return pull(
51- function fn(end, cb) {
52- if (end || fn.ended) cb(true)
53- fn.ended = true
54- if (_refs) cb(_refs)
55- else _cb = cb
56- },
57- pull.flatten()
58- )
34 +exports.gives = {
35 + message_action: true,
36 + message_meta: true,
37 + message_content: true
5938 }
6039
61-function getForks(id) {
62- return pull(
63- sbot_links({
64- reverse: true,
65- dest: id,
66- rel: 'upstream'
67- }),
68- pull.map(function (link) {
69- return {
70- id: link.key,
71- author: link.source
72- }
73- })
74- )
75-}
7640
77-function repoText(id) {
78- var text = document.createTextNode(id.substr(0, 10) + '…')
79- getAvatar({links: sbot_links, get: sbot_get}, self_id, id,
80- function (err, avatar) {
81- if(err) return console.error(err)
82- if (avatar.name[0] !== '%') avatar.name = '%' + avatar.name
83- text.nodeValue = avatar.name
84- })
85- return text
86-}
41 +var self_id = require('../keys').id
8742
88-function repoLink(id) {
89- return h('a', {href: '#'+id}, repoText(id))
43 +function shortRefName(ref) {
44 + return ref.replace(/^refs\/(heads|tags)\//, '')
9045 }
9146
92-function repoName(id) {
93- return h('ins', repoText(id))
94-}
47 +exports.create = function (api) {
9548
96-function getIssueState(id, cb) {
97- pull(
98- sbot_links({dest: id, rel: 'issues', values: true, reverse: true}),
99- pull.map(function (msg) {
100- return msg.value.content.issues
101- }),
102- pull.flatten(),
103- pull.filter(function (issue) {
104- return issue.link === id
105- }),
106- pull.map(function (issue) {
107- return issue.merged ? 'merged' : issue.open ? 'open' : 'closed'
108- }),
109- pull.take(1),
110- pull.collect(function (err, updates) {
111- cb(err, updates && updates[0] || 'open')
112- })
113- )
114-}
115-
116-//todo:
117-function messageTimestampLink(msg) {
118- var date = new Date(msg.value.timestamp)
119- return h('a.timestamp', {
120- timestamp: msg.value.timestamp,
121- title: date,
122- href: '#'+msg.key
123- }, human(date))
124-}
125-
126-// a thead+tbody where the thead only is added when the first row is added
127-function tableRows(headerRow) {
128- var thead = h('thead'), tbody = h('tbody')
129- var first = true
130- var t = [thead, tbody]
131- t.append = function (row) {
132- if (first) {
133- first = false
134- thead.appendChild(headerRow)
135- }
136- tbody.appendChild(row)
137- }
138- return t
139-}
140-
141-function renderIssueEdit(c) {
142- var id = c.issue || c.link
143- return [
144- c.title ? h('p', 'renamed issue ', message_link(id),
145- ' to ', h('ins', c.title)) : null,
146- c.open === false ? h('p', 'closed issue ', message_link(id)) : null,
147- c.open === true ? h('p', 'reopened issue ', message_link(id)) : null]
148-}
149-
150-exports.message_content = function (msg, sbot) {
151- var c = msg.value.content
152-
153- if(c.type === 'git-repo') {
154- var branchesT, tagsT, openIssuesT, closedIssuesT, openPRsT, closedPRsT
155- var forksT
156- var div = h('div',
157- h('p', 'git repo ', repoName(msg.key)),
158- c.upstream ? h('p', 'fork of ', repoLink(c.upstream)) : '',
159- h('p', h('code', 'ssb://' + msg.key)),
160- h('div.git-table-wrapper', {style: {'max-height': '12em'}},
161- h('table',
162- branchesT = tableRows(h('tr',
163- h('th', 'branch'),
164- h('th', 'commit'),
165- h('th', 'last update'))),
166- tagsT = tableRows(h('tr',
167- h('th', 'tag'),
168- h('th', 'commit'),
169- h('th', 'last update'))))),
170- h('div.git-table-wrapper', {style: {'max-height': '16em'}},
171- h('table',
172- openIssuesT = tableRows(h('tr',
173- h('th', 'open issues'))),
174- closedIssuesT = tableRows(h('tr',
175- h('th', 'closed issues'))))),
176- h('div.git-table-wrapper', {style: {'max-height': '16em'}},
177- h('table',
178- openPRsT = tableRows(h('tr',
179- h('th', 'open pull requests'))),
180- closedPRsT = tableRows(h('tr',
181- h('th', 'closed pull requests'))))),
182- h('div.git-table-wrapper',
183- h('table',
184- forksT = tableRows(h('tr',
185- h('th', 'forks'))))),
186- h('div', h('a', {href: '#', onclick: function (e) {
187- e.preventDefault()
188- this.parentNode.replaceChild(issueForm(msg), this)
189- }}, 'New Issue…')),
190- newPullRequestButton.call(this, msg)
191- )
192-
193- pull(getRefs(msg), pull.drain(function (ref) {
194- var name = ref.realname || ref.name
195- var author = ref.link && ref.link.value.author
196- var parts = /^refs\/(heads|tags)\/(.*)$/.exec(name) || []
197- var shortName = parts[2]
198- var t
199- if(parts[1] === 'heads') t = branchesT
200- else if(parts[1] === 'tags') t = tagsT
201- if(t) t.append(h('tr',
202- h('td', shortName,
203- ref.conflict ? [
204- h('br'),
205- h('a', {href: '#'+author}, avatar_name(author))
206- ] : ''),
207- h('td', h('code', ref.hash)),
208- h('td', messageTimestampLink(ref.link))))
209- }, function (err) {
210- if(err) console.error(err)
211- }))
212-
213- // list issues and pull requests
49 + function getRefs(msg) {
50 + var updates = new KVGraph('key')
51 + var _cb, _refs
21452 pull(
215- sbot_links({
53 + api.sbot_links({
21654 reverse: true,
55 + // source: msg.value.author,
21756 dest: msg.key,
218- rel: 'project',
57 + rel: 'repo',
21958 values: true
22059 }),
221- paramap(function (link, cb) {
222- getIssueState(link.key, function (err, state) {
223- if(err) return cb(err)
224- link.state = state
225- cb(null, link)
226- })
227- }),
22860 pull.drain(function (link) {
229- var c = link.value.content
230- var title = c.title || (c.text ? c.text.length > 70
231- ? c.text.substr(0, 70) + '…'
232- : c.text : link.key)
233- var author = link.value.author
234- var t = c.type === 'pull-request'
235- ? link.state === 'open' ? openPRsT : closedPRsT
236- : link.state === 'open' ? openIssuesT : closedIssuesT
237- t.append(h('tr',
238- h('td',
239- h('a', {href: '#'+link.key}, title), h('br'),
240- h('small',
241- 'opened ', messageTimestampLink(link),
242- ' by ', h('a', {href: '#'+author}, avatar_name(author))))))
61 + if (link.value.content.type === 'git-update') {
62 + updates.add(link)
63 + }
24364 }, function (err) {
244- if (err) console.error(err)
65 + var refs = updates.reduceRight(mergeRepo).refs
66 + var cb = _cb
67 + if (cb) _cb = null, cb(err, refs)
68 + else _refs = refs
24569 })
24670 )
24771
248- // list forks
249- pull(
250- getForks(msg.key),
251- pull.drain(function (fork) {
252- forksT.append(h('tr', h('td',
253- repoLink(fork.id),
254- ' by ', h('a', {href: '#'+fork.author}, avatar_name(fork.author)))))
255- }, function (err) {
256- if (err) console.error(err)
72 + return pull(
73 + function fn(end, cb) {
74 + if (end || fn.ended) cb(true)
75 + fn.ended = true
76 + if (_refs) cb(_refs)
77 + else _cb = cb
78 + },
79 + pull.flatten()
80 + )
81 + }
82 +
83 + function getForks(id) {
84 + return pull(
85 + api.sbot_links({
86 + reverse: true,
87 + dest: id,
88 + rel: 'upstream'
89 + }),
90 + pull.map(function (link) {
91 + return {
92 + id: link.key,
93 + author: link.source
94 + }
25795 })
25896 )
97 + }
25998
260- return div
99 + function repoText(id) {
100 + var text = document.createTextNode(id.substr(0, 10) + '…')
101 + getAvatar({links: api.sbot_links, get: api.sbot_get}, self_id, id,
102 + function (err, avatar) {
103 + if(err) return console.error(err)
104 + if (avatar.name[0] !== '%') avatar.name = '%' + avatar.name
105 + text.nodeValue = avatar.name
106 + })
107 + return text
261108 }
262109
263- if(c.type === 'git-update') {
264- return [
265- h('p', 'pushed to ', repoLink(c.repo)),
266- c.refs ? h('ul', Object.keys(c.refs).map(function (ref) {
267- var rev = c.refs[ref]
268- return h('li',
269- shortRefName(ref) + ': ',
270- rev ? h('code', rev) : h('em', 'deleted'))
271- })) : null,
272- Array.isArray(c.commits) ? [
273- h('ul',
274- c.commits.map(function (commit) {
275- return h('li',
276- typeof commit.sha1 === 'string' ?
277- [h('code', commit.sha1.substr(0, 8)), ' '] : null,
278- commit.title ?
279- h('q', commit.title) : null)
280- }),
281- c.commits_more > 0 ?
282- h('li', '+ ', c.commits_more, ' more') : null)
283- ] : null,
284- Array.isArray(c.issues) ? c.issues.map(function (issue) {
285- if (issue.merged === true)
286- return h('p', 'Merged ', message_link(issue.link), ' in ',
287- h('code', issue.object), ' ', h('q', issue.label))
288- if (issue.open === false)
289- return h('p', 'Closed ', message_link(issue.link), ' in ',
290- h('code', issue.object), ' ', h('q', issue.label))
291- }) : null,
292- newPullRequestButton.call(this, msg)
293- ]
110 + function repoLink(id) {
111 + return h('a', {href: '#'+id}, repoText(id))
294112 }
295113
296- if(c.type === 'issue-edit'
297- || (c.type === 'post' && c.text === '')) {
298- return h('div',
299- c.issue ? renderIssueEdit(c) : null,
300- c.issues ? c.issues.map(renderIssueEdit) : null)
114 + function repoName(id) {
115 + return h('ins', repoText(id))
301116 }
302117
303- if(c.type === 'issue') {
304- return h('div',
305- h('p', 'opened issue on ', repoLink(c.project)),
306- c.title ? h('h4', c.title) : '',
307- markdown(c)
118 + function getIssueState(id, cb) {
119 + pull(
120 + api.sbot_links({dest: id, rel: 'issues', values: true, reverse: true}),
121 + pull.map(function (msg) {
122 + return msg.value.content.issues
123 + }),
124 + pull.flatten(),
125 + pull.filter(function (issue) {
126 + return issue.link === id
127 + }),
128 + pull.map(function (issue) {
129 + return issue.merged ? 'merged' : issue.open ? 'open' : 'closed'
130 + }),
131 + pull.take(1),
132 + pull.collect(function (err, updates) {
133 + cb(err, updates && updates[0] || 'open')
134 + })
308135 )
309136 }
310137
311- if(c.type === 'pull-request') {
312- return h('div',
313- h('p', 'opened pull-request ',
314- 'to ', repoLink(c.repo), ':', c.branch, ' ',
315- 'from ', repoLink(c.head_repo), ':', c.head_branch),
316- c.title ? h('h4', c.title) : '',
317- markdown(c)
138 + //todo:
139 + function messageTimestampLink(msg) {
140 + var date = new Date(msg.value.timestamp)
141 + return h('a.timestamp', {
142 + timestamp: msg.value.timestamp,
143 + title: date,
144 + href: '#'+msg.key
145 + }, human(date))
146 + }
147 +
148 + // a thead+tbody where the thead only is added when the first row is added
149 + function tableRows(headerRow) {
150 + var thead = h('thead'), tbody = h('tbody')
151 + var first = true
152 + var t = [thead, tbody]
153 + t.append = function (row) {
154 + if (first) {
155 + first = false
156 + thead.appendChild(headerRow)
157 + }
158 + tbody.appendChild(row)
159 + }
160 + return t
161 + }
162 +
163 + function renderIssueEdit(c) {
164 + var id = c.issue || c.link
165 + return [
166 + c.title ? h('p', 'renamed issue ', api.message_link(id),
167 + ' to ', h('ins', c.title)) : null,
168 + c.open === false ? h('p', 'closed issue ', api.message_link(id)) : null,
169 + c.open === true ? h('p', 'reopened issue ', api.message_link(id)) : null]
170 + }
171 +
172 + function findMessageContent(el) {
173 + for(; el; el = el.parentNode) {
174 + if(el.classList.contains('message')) {
175 + return el.querySelector('.message_content')
176 + }
177 + }
178 + }
179 +
180 + function issueForm(msg, contentEl) {
181 + var form = h('form',
182 + h('strong', 'New Issue:'),
183 + api.message_compose(
184 + {type: 'issue', project: msg.key},
185 + function (value) { return value },
186 + function (err, issue) {
187 + if(err) return alert(err)
188 + if(!issue) return
189 + var title = issue.value.content.text
190 + if(title.length > 70) title = title.substr(0, 70) + '…'
191 + form.appendChild(h('div',
192 + h('a', {href: '#'+issue.key}, title)
193 + ))
194 + }
195 + )
318196 )
197 + return form
319198 }
320-}
321199
322-exports.message_meta = function (msg, sbot) {
323- var type = msg.value.content.type
324- if (type === 'issue' || type === 'pull-request') {
325- var el = h('em', '...')
326- // TODO: update if issue is changed
327- getIssueState(msg.key, function (err, state) {
328- if (err) return console.error(err)
329- el.textContent = state
200 + function branchMenu(msg, full) {
201 + return combobox({
202 + style: {'max-width': '14ex'},
203 + placeholder: 'branch…',
204 + default: 'master',
205 + read: msg && pull(getRefs(msg), pull.map(function (ref) {
206 + var m = /^refs\/heads\/(.*)$/.exec(ref.name)
207 + if(!m) return
208 + var branch = m[1]
209 + var label = branch
210 + if(full) {
211 + var updated = new Date(ref.link.value.timestamp)
212 + label = branch +
213 + ' · ' + human(updated) +
214 + ' · ' + ref.hash.substr(1, 8) +
215 + (ref.title ? ' · "' + ref.title + '"' : '')
216 + }
217 + return h('option', {value: branch}, label)
218 + }))
330219 })
331- return el
332220 }
333-}
334221
335-function findMessageContent(el) {
336- for(; el; el = el.parentNode) {
337- if(el.classList.contains('message')) {
338- return el.querySelector('.message_content')
339- }
222 + function newPullRequestButton(msg) {
223 + return h('div', [
224 + h('a', {
225 + href: '#',
226 + onclick: function (e) {
227 + e.preventDefault()
228 + this.parentNode.replaceChild(pullRequestForm(msg), this)
229 + }},
230 + 'New Pull Request…'
231 + )
232 + ])
340233 }
341-}
342234
343-function issueForm(msg, contentEl) {
344- var form = h('form',
345- h('strong', 'New Issue:'),
346- message_compose(
347- {type: 'issue', project: msg.key},
348- function (value) { return value },
349- function (err, issue) {
350- if(err) return alert(err)
351- if(!issue) return
352- var title = issue.value.content.text
353- if(title.length > 70) title = title.substr(0, 70) + '…'
354- form.appendChild(h('div',
355- h('a', {href: '#'+issue.key}, title)
356- ))
357- }
235 + function pullRequestForm(msg) {
236 + var headRepoInput
237 + var headBranchInput = branchMenu()
238 + var branchInput = branchMenu(msg)
239 + var form = h('form',
240 + h('strong', 'New Pull Request:'),
241 + h('div',
242 + 'from ',
243 + headRepoInput = combobox({
244 + style: {'max-width': '26ex'},
245 + onchange: function () {
246 + // list branches for selected repo
247 + var repoId = this.value
248 + if(repoId) api.sbot_get(repoId, function (err, value) {
249 + if(err) console.error(err)
250 + var msg = value && {key: repoId, value: value}
251 + headBranchInput = headBranchInput.swap(branchMenu(msg, true))
252 + })
253 + else headBranchInput = headBranchInput.swap(branchMenu())
254 + },
255 + read: pull(cat([
256 + pull.once({id: msg.key, author: msg.value.author}),
257 + getForks(msg.key)
258 + ]), pull.map(function (fork) {
259 + return h('option', {value: fork.id},
260 + repoLink(fork.id), ' by ', avatar_name(fork.author))
261 + }))
262 + }),
263 + ':',
264 + headBranchInput,
265 + ' to ',
266 + repoName(msg.key),
267 + ':',
268 + branchInput),
269 + api.message_compose(
270 + {
271 + type: 'pull-request',
272 + project: msg.key,
273 + repo: msg.key,
274 + },
275 + function (value) {
276 + value.branch = branchInput.value
277 + value.head_repo = headRepoInput.value
278 + value.head_branch = headBranchInput.value
279 + return value
280 + },
281 + function (err, issue) {
282 + if(err) return alert(err)
283 + if(!issue) return
284 + var title = issue.value.content.text
285 + if(title.length > 70) title = title.substr(0, 70) + '…'
286 + form.appendChild(h('div',
287 + h('a', {href: '#'+issue.key}, title)
288 + ))
289 + }
290 + )
358291 )
359- )
360- return form
361-}
292 + return form
293 + }
362294
363-function branchMenu(msg, full) {
364- return combobox({
365- style: {'max-width': '14ex'},
366- placeholder: 'branch…',
367- default: 'master',
368- read: msg && pull(getRefs(msg), pull.map(function (ref) {
369- var m = /^refs\/heads\/(.*)$/.exec(ref.name)
370- if(!m) return
371- var branch = m[1]
372- var label = branch
373- if(full) {
374- var updated = new Date(ref.link.value.timestamp)
375- label = branch +
376- ' · ' + human(updated) +
377- ' · ' + ref.hash.substr(1, 8) +
378- (ref.title ? ' · "' + ref.title + '"' : '')
295 +
296 +
297 + return {
298 + message_content: function (msg, sbot) {
299 + var c = msg.value.content
300 +
301 + if(c.type === 'git-repo') {
302 + var branchesT, tagsT, openIssuesT, closedIssuesT, openPRsT, closedPRsT
303 + var forksT
304 + var div = h('div',
305 + h('p', 'git repo ', repoName(msg.key)),
306 + c.upstream ? h('p', 'fork of ', repoLink(c.upstream)) : '',
307 + h('p', h('code', 'ssb://' + msg.key)),
308 + h('div.git-table-wrapper', {style: {'max-height': '12em'}},
309 + h('table',
310 + branchesT = tableRows(h('tr',
311 + h('th', 'branch'),
312 + h('th', 'commit'),
313 + h('th', 'last update'))),
314 + tagsT = tableRows(h('tr',
315 + h('th', 'tag'),
316 + h('th', 'commit'),
317 + h('th', 'last update'))))),
318 + h('div.git-table-wrapper', {style: {'max-height': '16em'}},
319 + h('table',
320 + openIssuesT = tableRows(h('tr',
321 + h('th', 'open issues'))),
322 + closedIssuesT = tableRows(h('tr',
323 + h('th', 'closed issues'))))),
324 + h('div.git-table-wrapper', {style: {'max-height': '16em'}},
325 + h('table',
326 + openPRsT = tableRows(h('tr',
327 + h('th', 'open pull requests'))),
328 + closedPRsT = tableRows(h('tr',
329 + h('th', 'closed pull requests'))))),
330 + h('div.git-table-wrapper',
331 + h('table',
332 + forksT = tableRows(h('tr',
333 + h('th', 'forks'))))),
334 + h('div', h('a', {href: '#', onclick: function (e) {
335 + e.preventDefault()
336 + this.parentNode.replaceChild(issueForm(msg), this)
337 + }}, 'New Issue…')),
338 + newPullRequestButton.call(this, msg)
339 + )
340 +
341 + pull(getRefs(msg), pull.drain(function (ref) {
342 + var name = ref.realname || ref.name
343 + var author = ref.link && ref.link.value.author
344 + var parts = /^refs\/(heads|tags)\/(.*)$/.exec(name) || []
345 + var shortName = parts[2]
346 + var t
347 + if(parts[1] === 'heads') t = branchesT
348 + else if(parts[1] === 'tags') t = tagsT
349 + if(t) t.append(h('tr',
350 + h('td', shortName,
351 + ref.conflict ? [
352 + h('br'),
353 + h('a', {href: '#'+author}, api.avatar_name(author))
354 + ] : ''),
355 + h('td', h('code', ref.hash)),
356 + h('td', messageTimestampLink(ref.link))))
357 + }, function (err) {
358 + if(err) console.error(err)
359 + }))
360 +
361 + // list issues and pull requests
362 + pull(
363 + api.sbot_links({
364 + reverse: true,
365 + dest: msg.key,
366 + rel: 'project',
367 + values: true
368 + }),
369 + paramap(function (link, cb) {
370 + getIssueState(link.key, function (err, state) {
371 + if(err) return cb(err)
372 + link.state = state
373 + cb(null, link)
374 + })
375 + }),
376 + pull.drain(function (link) {
377 + var c = link.value.content
378 + var title = c.title || (c.text ? c.text.length > 70
379 + ? c.text.substr(0, 70) + '…'
380 + : c.text : link.key)
381 + var author = link.value.author
382 + var t = c.type === 'pull-request'
383 + ? link.state === 'open' ? openPRsT : closedPRsT
384 + : link.state === 'open' ? openIssuesT : closedIssuesT
385 + t.append(h('tr',
386 + h('td',
387 + h('a', {href: '#'+link.key}, title), h('br'),
388 + h('small',
389 + 'opened ', messageTimestampLink(link),
390 + ' by ', h('a', {href: '#'+author}, avatar_name(author))))))
391 + }, function (err) {
392 + if (err) console.error(err)
393 + })
394 + )
395 +
396 + // list forks
397 + pull(
398 + getForks(msg.key),
399 + pull.drain(function (fork) {
400 + forksT.append(h('tr', h('td',
401 + repoLink(fork.id),
402 + ' by ', h('a', {href: '#'+fork.author}, api.avatar_name(fork.author)))))
403 + }, function (err) {
404 + if (err) console.error(err)
405 + })
406 + )
407 +
408 + return div
379409 }
380- return h('option', {value: branch}, label)
381- }))
382- })
383-}
384410
385-function newPullRequestButton(msg) {
386- return h('div', [
387- h('a', {
388- href: '#',
389- onclick: function (e) {
390- e.preventDefault()
391- this.parentNode.replaceChild(pullRequestForm(msg), this)
392- }},
393- 'New Pull Request…'
394- )
395- ])
396-}
411 + if(c.type === 'git-update') {
412 + return [
413 + h('p', 'pushed to ', repoLink(c.repo)),
414 + c.refs ? h('ul', Object.keys(c.refs).map(function (ref) {
415 + var rev = c.refs[ref]
416 + return h('li',
417 + shortRefName(ref) + ': ',
418 + rev ? h('code', rev) : h('em', 'deleted'))
419 + })) : null,
420 + Array.isArray(c.commits) ? [
421 + h('ul',
422 + c.commits.map(function (commit) {
423 + return h('li',
424 + typeof commit.sha1 === 'string' ?
425 + [h('code', commit.sha1.substr(0, 8)), ' '] : null,
426 + commit.title ?
427 + h('q', commit.title) : null)
428 + }),
429 + c.commits_more > 0 ?
430 + h('li', '+ ', c.commits_more, ' more') : null)
431 + ] : null,
432 + Array.isArray(c.issues) ? c.issues.map(function (issue) {
433 + if (issue.merged === true)
434 + return h('p', 'Merged ', api.message_link(issue.link), ' in ',
435 + h('code', issue.object), ' ', h('q', issue.label))
436 + if (issue.open === false)
437 + return h('p', 'Closed ', api.message_link(issue.link), ' in ',
438 + h('code', issue.object), ' ', h('q', issue.label))
439 + }) : null,
440 + newPullRequestButton.call(this, msg)
441 + ]
442 + }
397443
398-function pullRequestForm(msg) {
399- var headRepoInput
400- var headBranchInput = branchMenu()
401- var branchInput = branchMenu(msg)
402- var form = h('form',
403- h('strong', 'New Pull Request:'),
404- h('div',
405- 'from ',
406- headRepoInput = combobox({
407- style: {'max-width': '26ex'},
408- onchange: function () {
409- // list branches for selected repo
410- var repoId = this.value
411- if(repoId) sbot_get(repoId, function (err, value) {
412- if(err) console.error(err)
413- var msg = value && {key: repoId, value: value}
414- headBranchInput = headBranchInput.swap(branchMenu(msg, true))
444 + if(c.type === 'issue-edit'
445 + || (c.type === 'post' && c.text === '')) {
446 + return h('div',
447 + c.issue ? renderIssueEdit(c) : null,
448 + c.issues ? c.issues.map(renderIssueEdit) : null)
449 + }
450 +
451 + if(c.type === 'issue') {
452 + return h('div',
453 + h('p', 'opened issue on ', repoLink(c.project)),
454 + c.title ? h('h4', c.title) : '',
455 + markdown(c)
456 + )
457 + }
458 +
459 + if(c.type === 'pull-request') {
460 + return h('div',
461 + h('p', 'opened pull-request ',
462 + 'to ', repoLink(c.repo), ':', c.branch, ' ',
463 + 'from ', repoLink(c.head_repo), ':', c.head_branch),
464 + c.title ? h('h4', c.title) : '',
465 + api.markdown(c)
466 + )
467 + }
468 + },
469 +
470 + message_meta: function (msg, sbot) {
471 + var type = msg.value.content.type
472 + if (type === 'issue' || type === 'pull-request') {
473 + var el = h('em', '...')
474 + // TODO: update if issue is changed
475 + getIssueState(msg.key, function (err, state) {
476 + if (err) return console.error(err)
477 + el.textContent = state
478 + })
479 + return el
480 + }
481 + },
482 +
483 + message_action: function (msg, sbot) {
484 + var c = msg.value.content
485 + if(c.type === 'issue' || c.type === 'pull-request') {
486 + var isOpen
487 + var a = h('a', {href: '#', onclick: function (e) {
488 + e.preventDefault()
489 + api.message_confirm({
490 + type: 'issue-edit',
491 + root: msg.key,
492 + issues: [{
493 + link: msg.key,
494 + open: !isOpen
495 + }]
496 + }, function (err, msg) {
497 + if(err) return alert(err)
498 + if(!msg) return
499 + isOpen = msg.value.content.open
500 + update()
415501 })
416- else headBranchInput = headBranchInput.swap(branchMenu())
417- },
418- read: pull(cat([
419- pull.once({id: msg.key, author: msg.value.author}),
420- getForks(msg.key)
421- ]), pull.map(function (fork) {
422- return h('option', {value: fork.id},
423- repoLink(fork.id), ' by ', avatar_name(fork.author))
424- }))
425- }),
426- ':',
427- headBranchInput,
428- ' to ',
429- repoName(msg.key),
430- ':',
431- branchInput),
432- message_compose(
433- {
434- type: 'pull-request',
435- project: msg.key,
436- repo: msg.key,
437- },
438- function (value) {
439- value.branch = branchInput.value
440- value.head_repo = headRepoInput.value
441- value.head_branch = headBranchInput.value
442- return value
443- },
444- function (err, issue) {
445- if(err) return alert(err)
446- if(!issue) return
447- var title = issue.value.content.text
448- if(title.length > 70) title = title.substr(0, 70) + '…'
449- form.appendChild(h('div',
450- h('a', {href: '#'+issue.key}, title)
451- ))
502 + }})
503 + getIssueState(msg.key, function (err, state) {
504 + if (err) return console.error(err)
505 + isOpen = state === 'open'
506 + update()
507 + })
508 + function update() {
509 + a.textContent = c.type === 'pull-request'
510 + ? isOpen ? 'Close Pull Request' : 'Reopen Pull Request'
511 + : isOpen ? 'Close Issue' : 'Reopen Issue'
512 + }
513 + return a
452514 }
453- )
454- )
455- return form
456-}
457-
458-exports.message_action = function (msg, sbot) {
459- var c = msg.value.content
460- if(c.type === 'issue' || c.type === 'pull-request') {
461- var isOpen
462- var a = h('a', {href: '#', onclick: function (e) {
463- e.preventDefault()
464- message_confirm({
465- type: 'issue-edit',
466- root: msg.key,
467- issues: [{
468- link: msg.key,
469- open: !isOpen
470- }]
471- }, function (err, msg) {
472- if(err) return alert(err)
473- if(!msg) return
474- isOpen = msg.value.content.open
475- update()
476- })
477- }})
478- getIssueState(msg.key, function (err, state) {
479- if (err) return console.error(err)
480- isOpen = state === 'open'
481- update()
482- })
483- function update() {
484- a.textContent = c.type === 'pull-request'
485- ? isOpen ? 'Close Pull Request' : 'Reopen Pull Request'
486- : isOpen ? 'Close Issue' : 'Reopen Issue'
487515 }
488- return a
489516 }
490517 }
491518
519 +
modules_extra/meta-image.jsView
@@ -4,22 +4,26 @@
44 var ref = require('ssb-ref');
55
66 //render a message
77
8-var plugs = require('../plugs');
9-var message_link = plugs.first(exports.message_link = []);
10-var message_confirm = plugs.first(exports.message_confirm = []);
11-var sbot_links = plugs.first(exports.sbot_links = []);
12-var blob_url = plugs.first(exports.blob_url = []);
8 +//var plugs = require('../plugs');
9 +//var message_link = plugs.first(exports.message_link = []);
10 +//var message_confirm = plugs.first(exports.message_confirm = []);
11 +//var sbot_links = plugs.first(exports.sbot_links = []);
12 +//var blob_url = plugs.first(exports.blob_url = []);
13 +//
14 +exports.needs = { blob_url: 'first' }
15 +exports.gives = 'message_content'
1316
14-exports.message_content = function(msg, sbot) {
17 +exports.create = function (api) {
18 + return function(msg, sbot) {
1519 if (msg.value.content.type !== 'meta-image')
1620 return;
1721
1822 var v = msg.value.content;
1923 return h('div',
2024 // h('h2', "(" + v.Track + ") " + v.Title),
21- h('img', { "src" : blob_url(v.link) }))
25 + h('img', { "src" : api.blob_url(v.link) }))
2226
2327 // h('dl',
2428 // Object.keys(v).map(function(k) {
2529 // return [
@@ -43,6 +47,6 @@
4347 // "Title": "clouds",
4448 // "Track": "2",
4549 // "Width": "0",
4650
51 + }
4752 }
48-
modules_extra/music-release-cc.jsView
@@ -4,36 +4,42 @@
44 var ref = require('ssb-ref');
55
66 //render a message
77
8-var plugs = require('../plugs');
9-var message_link = plugs.first(exports.message_link = []);
10-var message_confirm = plugs.first(exports.message_confirm = []);
11-var sbot_links = plugs.first(exports.sbot_links = []);
12-var blob_url = plugs.first(exports.blob_url = []);
8 +//var plugs = require('../plugs');
9 +//var message_link = plugs.first(exports.message_link = []);
10 +//var message_confirm = plugs.first(exports.message_confirm = []);
11 +//var sbot_links = plugs.first(exports.sbot_links = []);
12 +//var blob_url = plugs.first(exports.blob_url = []);
13 +//
1314
14-exports.message_content = function(msg, sbot) {
15- if (msg.value.content.type !== 'music-release-cc')
16- return;
15 +exports.needs = { blob_url: 'first' }
16 +exports.gives = 'message_content'
1717
18- var tracks = msg.value.content.tracks;
19- return h('div',
20- h('img', { "src" : blob_url(msg.value.content.cover) }),
21- h('h1', msg.value.content.title),
22- h('ol',
23- Object.keys(tracks).map(function(k) {
24- var t = tracks[k];
25- return h('li', t.fname,
26- h("br"),
27- h('audio', {
28- "controls" : true,
29- "src" : blob_url(t.link)
30- }))
31- })),
32- h('p',
33- "More info:", h('a', { href : msg.value.content.archivedotorg }, "archive.org"),
34- h("br"),
35- "License:", h('a', { href : msg.value.content.license }, "Link")))
18 +exports.create = function (api) {
19 + return function(msg, sbot) {
20 + if (msg.value.content.type !== 'music-release-cc')
21 + return;
22 +
23 + var tracks = msg.value.content.tracks;
24 + return h('div',
25 + h('img', { "src" : api.blob_url(msg.value.content.cover) }),
26 + h('h1', msg.value.content.title),
27 + h('ol',
28 + Object.keys(tracks).map(function(k) {
29 + var t = tracks[k];
30 + return h('li', t.fname,
31 + h("br"),
32 + h('audio', {
33 + "controls" : true,
34 + "src" : api.blob_url(t.link)
35 + }))
36 + })),
37 + h('p',
38 + "More info:", h('a', { href : msg.value.content.archivedotorg }, "archive.org"),
39 + h("br"),
40 + "License:", h('a', { href : msg.value.content.license }, "Link")))
41 + }
3642 }
3743
3844 // copied from like.js
3945
@@ -77,4 +83,5 @@
7783 // }}, 'yup')
7884
7985 // }
8086
87 +
modules_extra/music-release.jsView
@@ -4,38 +4,43 @@
44 var ref = require('ssb-ref');
55
66 //render a message
77
8-var plugs = require('../plugs');
9-var message_link = plugs.first(exports.message_link = []);
10-var message_confirm = plugs.first(exports.message_confirm = []);
11-var sbot_links = plugs.first(exports.sbot_links = []);
8 +//var plugs = require('../plugs');
9 +//var message_link = plugs.first(exports.message_link = []);
10 +//var message_confirm = plugs.first(exports.message_confirm = []);
11 +//var sbot_links = plugs.first(exports.sbot_links = []);
12 +//
13 +exports.gives = 'message_content'
1214
13-exports.message_content = function(msg, sbot) {
14- if (msg.value.content.type !== 'music-release')
15- return;
15 +exports.create = function () {
1616
17- var v = msg.value.content;
18- return h('div',
19- // h('img', { "src" : "http://localhost:7777/" + encodeURIComponent(v.cover) }),
20- h('h1', v.Title),
21- h("p", v.Description),
22- h("dl",
17 + return function(msg, sbot) {
18 + if (msg.value.content.type !== 'music-release')
19 + return;
2320
24- h("dt", "Creator"),
25- h("dd", v.Creator),
21 + var v = msg.value.content;
22 + return h('div',
23 + // h('img', { "src" : "http://localhost:7777/" + encodeURIComponent(v.cover) }),
24 + h('h1', v.Title),
25 + h("p", v.Description),
26 + h("dl",
2627
27- h("dt", "Identifier"),
28- h("dd", v.Identifier),
28 + h("dt", "Creator"),
29 + h("dd", v.Creator),
2930
30- h("dt", "Published"),
31- h("dd", v.Publicdate),
31 + h("dt", "Identifier"),
32 + h("dd", v.Identifier),
3233
33- h("dt", "Runtime"),
34- h("dd", v.Runtime),
34 + h("dt", "Published"),
35 + h("dd", v.Publicdate),
3536
36- h("dt", "Source"),
37- h("dd", v.Source),
37 + h("dt", "Runtime"),
38 + h("dd", v.Runtime),
3839
39- h("dt", "License"),
40- h("dd", h('a', { href : v.Licenseurl }, "Link"))))
40 + h("dt", "Source"),
41 + h("dd", v.Source),
42 +
43 + h("dt", "License"),
44 + h("dd", h('a', { href : v.Licenseurl }, "Link"))))
45 + }
4146 }
modules_extra/network.jsView
@@ -1,11 +1,23 @@
11 var isVisible = require('is-visible').isVisible
22 var h = require('hyperscript')
3-var plugs = require('../plugs')
43
5-var avatar = plugs.first(exports.avatar = [])
6-var sbot_gossip_peers = plugs.first(exports.sbot_gossip_peers = [])
7-var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = [])
4 +//var avatar = plugs.first(exports.avatar = [])
5 +//var sbot_gossip_peers = plugs.first(exports.sbot_gossip_peers = [])
6 +//var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = [])
7 +
8 +exports.needs = {
9 + avatar: 'first',
10 + sbot_gossip_peers: 'first',
11 + sbot_gossip_connect: 'first'
12 +}
13 +
14 +exports.gives = {
15 + menu_items: true,
16 + builtin_tabs: true,
17 + screen_view: true
18 +}
19 +
820 //sbot_gossip_connect
921 //sbot_gossip_add
1022
1123 var human = require('human-time')
@@ -13,16 +25,8 @@
1325 function legacyToMultiServer(addr) {
1426 return 'net:'+addr.host + ':'+addr.port + '~shs:'+addr.key.substring(1).replace('.ed25519','')
1527 }
1628
17-exports.menu_items = function () {
18- return h('a', {href: '#/network'}, '/network')
19-}
20-
21-exports.builtin_tabs = function () {
22- return ['/network']
23-}
24-
2529 //types of peers
2630
2731
2832 //on the same wifi network
@@ -91,62 +95,76 @@
9195 else
9296 return round(s)+'ms'
9397 }
9498
95-exports.screen_view = function (path) {
9699
97- if(path !== '/network') return
98100
99- var ol = h('ul.network')
101 +exports.create = function (api) {
100102
101- ;(function poll () {
103 + return {
104 + menu_items: function () {
105 + return h('a', {href: '#/network'}, '/network')
106 + },
102107
103- //if this tab isn't open, don't update.
104- //todo: make a better way to do this...
105- if(!isVisible(ol))
106- return setTimeout(poll, 1000)
108 + builtin_tabs: function () {
109 + return ['/network']
110 + },
107111
108- sbot_gossip_peers(function (err, list) {
109- ol.innerHTML = ''
110- list.sort(function (a, b) {
111- return (
112- (states[b.state] || 0) - (states[a.state] || 0)
113- || types[getType(b)] - types[getType(a)]
114- || b.stateChange - a.stateChange
115- )
116- }).forEach(function (peer) {
117- ol.appendChild(h('div',
118- avatar(peer.key, 'thumbnail'),
119- h('div',
120- peer.state || 'not connected',
121- ' ',
122- getType(peer),
123- ' ',
124- //TODO: show nicer details, with labels. etc.
125- (peer.ping && peer.ping.rtt) ? duration(peer.ping.rtt.mean) : '',
126- ' ',
127- (peer.ping && peer.ping.skew) ? duration(peer.ping.skew.mean) : '',
128- h('label',
129- {title: new Date(peer.stateChange).toString()},
130- peer.stateChange && ('(' + human(new Date(peer.stateChange))) + ')')
131- ),
132- 'source:'+peer.source,
133- h('pre', legacyToMultiServer(peer)),
134- h('button', 'connect', {onclick: function () {
135- sbot_gossip_connect(peer, function (err) {
136- if(err) console.error(err)
137- else console.log('connected to', peer)
138- })
139- }})
140- )
141- )
142- })
112 + screen_view: function (path) {
143113
144- setTimeout(poll, 5000)
145- })
114 + if(path !== '/network') return
146115
147- })()
116 + var ol = h('ul.network')
148117
149- return h('div.column.scroll-y', ol)
118 + ;(function poll () {
119 +
120 + //if this tab isn't open, don't update.
121 + //todo: make a better way to do this...
122 + if(!isVisible(ol))
123 + return setTimeout(poll, 1000)
124 +
125 + sbot_gossip_peers(function (err, list) {
126 + ol.innerHTML = ''
127 + list.sort(function (a, b) {
128 + return (
129 + (states[b.state] || 0) - (states[a.state] || 0)
130 + || types[getType(b)] - types[getType(a)]
131 + || b.stateChange - a.stateChange
132 + )
133 + }).forEach(function (peer) {
134 + ol.appendChild(h('div',
135 + avatar(peer.key, 'thumbnail'),
136 + h('div',
137 + peer.state || 'not connected',
138 + ' ',
139 + getType(peer),
140 + ' ',
141 + //TODO: show nicer details, with labels. etc.
142 + (peer.ping && peer.ping.rtt) ? duration(peer.ping.rtt.mean) : '',
143 + ' ',
144 + (peer.ping && peer.ping.skew) ? duration(peer.ping.skew.mean) : '',
145 + h('label',
146 + {title: new Date(peer.stateChange).toString()},
147 + peer.stateChange && ('(' + human(new Date(peer.stateChange))) + ')')
148 + ),
149 + 'source:'+peer.source,
150 + h('pre', legacyToMultiServer(peer)),
151 + h('button', 'connect', {onclick: function () {
152 + sbot_gossip_connect(peer, function (err) {
153 + if(err) console.error(err)
154 + else console.log('connected to', peer)
155 + })
156 + }})
157 + )
158 + )
159 + })
160 +
161 + setTimeout(poll, 5000)
162 + })
163 +
164 + })()
165 +
166 + return h('div.column.scroll-y', ol)
167 + }
168 + }
150169 }
151170
152-
modules_extra/notifications.jsView
@@ -1,4 +1,5 @@
1 +'use strict'
12 var h = require('hyperscript')
23 var u = require('../util')
34 var pull = require('pull-stream')
45 var Scroller = require('pull-scroll')
@@ -6,150 +7,172 @@
67 var plugs = require('../plugs')
78 var cont = require('cont')
89 var ref = require('ssb-ref')
910
10-var message_render = plugs.first(exports.message_render = [])
11-var sbot_log = plugs.first(exports.sbot_log = [])
12-var sbot_get = plugs.first(exports.sbot_get = [])
13-var sbot_user_feed = plugs.first(exports.sbot_user_feed = [])
14-var message_unbox = plugs.first(exports.message_unbox = [])
11 +//var message_render = plugs.first(exports.message_render = [])
12 +//var sbot_log = plugs.first(exports.sbot_log = [])
13 +//var sbot_get = plugs.first(exports.sbot_get = [])
14 +//var sbot_user_feed = plugs.first(exports.sbot_user_feed = [])
15 +//var message_unbox = plugs.first(exports.message_unbox = [])
1516
16-function unbox() {
17- return pull(
18- pull.map(function (msg) {
19- return msg.value && 'string' === typeof msg.value.content ?
20- message_unbox(msg) : msg
21- }),
22- pull.filter(Boolean)
23- )
17 +exports.needs = {
18 + message_render: 'first',
19 + sbot_log: 'first',
20 + sbot_get: 'first',
21 + sbot_user_feed: 'first',
22 + message_unbox: 'first'
2423 }
2524
26-exports.builtin_tabs = function () {
27- return ['/notifications']
25 +
26 +exports.gives = {
27 + builtin_tabs: true,
28 + screen_view: true
2829 }
2930
30-function notifications(ourIds) {
31-
32- function linksToUs(link) {
33- return link && link.link in ourIds
31 +exports.create = function (api) {
32 + function unbox() {
33 + return pull(
34 + pull.map(function (msg) {
35 + return msg.value && 'string' === typeof msg.value.content ?
36 + api.message_unbox(msg) : msg
37 + }),
38 + pull.filter(Boolean)
39 + )
3440 }
3541
36- function isOurMsg(id, cb) {
37- if (!id) return cb(null, false)
38- if (typeof id === 'object' && typeof id.link === 'string') id = id.link
39- if (!ref.isMsg(id)) return cb(null, false)
40- sbot_get(id, function (err, msg) {
41- if (err && err.name == 'NotFoundError') cb(null, false)
42- else if (err) cb(err)
43- else if (msg.content.type === 'issue' || msg.content.type === 'pull-request')
44- isOurMsg(msg.content.repo || msg.content.project, cb)
45- else cb(err, msg.author in ourIds)
46- })
47- }
42 + function notifications(ourIds) {
4843
49- function isAnyOurMessage(msg, ids, cb) {
50- cont.para(ids.map(function (id) {
51- return function (cb) { isOurMsg(id, cb) }
52- }))
53- (function (err, results) {
54- if (err) cb(err)
55- else if (results.some(Boolean)) cb(null, msg)
56- else cb()
57- })
58- }
44 + function linksToUs(link) {
45 + return link && link.link in ourIds
46 + }
5947
60- return paramap(function (msg, cb) {
61- var c = msg.value && msg.value.content
62- if (!c || typeof c !== 'object') return cb()
63- if (msg.value.author in ourIds) return cb()
48 + function isOurMsg(id, cb) {
49 + if (!id) return cb(null, false)
50 + if (typeof id === 'object' && typeof id.link === 'string') id = id.link
51 + if (!ref.isMsg(id)) return cb(null, false)
52 + console.log('LOOKUP', id)
53 + api.sbot_get(id, function (err, msg) {
54 + console.log('FOUND', msg)
55 + if (err && err.name == 'NotFoundError') cb(null, false)
56 + else if (err) cb(err)
57 + else if (msg.content.type === 'issue' || msg.content.type === 'pull-request')
58 + isOurMsg(msg.content.repo || msg.content.project, cb)
59 + else cb(err, msg.author in ourIds)
60 + })
61 + }
6462
65- if (c.mentions && Array.isArray(c.mentions) && c.mentions.some(linksToUs))
66- return cb(null, msg)
63 + function isAnyOurMessage(msg, ids, cb) {
64 + cont.para(ids.map(function (id) {
65 + return function (cb) { isOurMsg(id, cb) }
66 + }))
67 + (function (err, results) {
68 + if (err) cb(err)
69 + else if (results.some(Boolean)) cb(null, msg)
70 + else cb()
71 + })
72 + }
6773
68- if (msg.private)
69- return cb(null, msg)
74 + return paramap(function (msg, cb) {
75 + console.log("LOOKUP", msg)
76 + var c = msg.value && msg.value.content
77 + if (!c || typeof c !== 'object') return cb()
78 + console.log(msg.value.author, ourIds)
79 + if (msg.value.author in ourIds) return cb()
7080
71- switch (c.type) {
72- case 'post':
73- if (c.branch || c.root)
74- return isAnyOurMessage(msg, [].concat(c.branch, c.root), cb)
75- else return cb()
81 + if (c.mentions && Array.isArray(c.mentions) && c.mentions.some(linksToUs))
82 + return cb(null, msg)
7683
77- case 'contact':
78- return cb(null, c.contact in ourIds ? msg : null)
84 + if (msg.private)
85 + return cb(null, msg)
7986
80- case 'vote':
81- if (c.vote && c.vote.link)
82- return isOurMsg(c.vote.link, function (err, isOurs) {
87 + switch (c.type) {
88 + case 'post':
89 + if (c.branch || c.root)
90 + return isAnyOurMessage(msg, [].concat(c.branch, c.root), cb)
91 + else return cb()
92 +
93 + case 'contact':
94 + return cb(null, c.contact in ourIds ? msg : null)
95 +
96 + case 'vote':
97 + if (c.vote && c.vote.link)
98 + return isOurMsg(c.vote.link, function (err, isOurs) {
99 + cb(err, isOurs ? msg : null)
100 + })
101 + else return cb()
102 +
103 + case 'issue':
104 + case 'pull-request':
105 + return isOurMsg(c.project || c.repo, function (err, isOurs) {
83106 cb(err, isOurs ? msg : null)
84107 })
85- else return cb()
86108
87- case 'issue':
88- case 'pull-request':
89- return isOurMsg(c.project || c.repo, function (err, isOurs) {
90- cb(err, isOurs ? msg : null)
91- })
109 + case 'issue-edit':
110 + return isAnyOurMessage(msg, [c.issue].concat(c.issues), cb)
92111
93- case 'issue-edit':
94- return isAnyOurMessage(msg, [c.issue].concat(c.issues), cb)
112 + default:
113 + cb()
114 + }
115 + }, 4)
116 + }
95117
96- default:
97- cb()
98- }
99- }, 4)
100-}
118 + function getFirstMessage(feedId, cb) {
119 + api.sbot_user_feed({id: feedId, gte: 0, limit: 1})(null, cb)
120 + }
101121
102-function getFirstMessage(feedId, cb) {
103- sbot_user_feed({id: feedId, gte: 0, limit: 1})(null, cb)
104-}
122 + return {
123 + builtin_tabs: function () {
124 + return ['/notifications']
125 + },
105126
106-exports.screen_view = function (path) {
107- if(path === '/notifications') {
108- var ids = {}
109- var oldest
127 + screen_view: function (path) {
128 + if(path === '/notifications') {
129 + var ids = {}
130 + var oldest
110131
111- var id = require('../keys').id
112- ids[id] = true
113- getFirstMessage(id, function (err, msg) {
114- if (err) return console.error(err)
115- if (!oldest || msg.value.timestamp < oldest) {
116- oldest = msg.value.timestamp
117- }
118- })
132 + var id = require('../keys').id
133 + ids[id] = true
134 + getFirstMessage(id, function (err, msg) {
135 + if (err) return console.error(err)
136 + if (!oldest || msg.value.timestamp < oldest) {
137 + oldest = msg.value.timestamp
138 + console.log('OLDEST', msg)
139 + }
140 + })
119141
120- var content = h('div.column.scroller__content')
121- var div = h('div.column.scroller',
122- {style: {'overflow':'auto'}},
123- h('div.scroller__wrapper',
124- content
125- )
126- )
142 + var content = h('div.column.scroller__content')
143 + var div = h('div.column.scroller',
144 + {style: {'overflow':'auto'}},
145 + h('div.scroller__wrapper',
146 + content
147 + )
148 + )
127149
128- pull(
129- u.next(sbot_log, {old: false, limit: 100}),
130- unbox(),
131- notifications(ids),
132- pull.filter(),
133- Scroller(div, content, message_render, true, false)
134- )
150 + pull(
151 + u.next(api.sbot_log, {old: false, limit: 100}),
152 + unbox(),
153 + notifications(ids),
154 + pull.filter(),
155 + Scroller(div, content, api.message_render, true, false)
156 + )
135157
136- pull(
137- u.next(sbot_log, {reverse: true, limit: 100, live: false}),
138- unbox(),
139- notifications(ids),
140- pull.filter(),
141- pull.take(function (msg) {
142- // abort stream after we pass the oldest messages of our feeds
143- return !oldest || msg.value.timestamp > oldest
144- }),
145- Scroller(div, content, message_render, false, false)
146- )
158 + pull(
159 + u.next(api.sbot_log, {reverse: true, limit: 100, live: false}),
160 + unbox(),
161 + notifications(ids),
162 + pull.filter(),
163 + pull.take(function (msg) {
164 + // abort stream after we pass the oldest messages of our feeds
165 + console.log('old?', msg.value.timestamp, oldest)
166 + return !oldest ? true : msg.value.timestamp > oldest
167 + }),
168 + Scroller(div, content, api.message_render, false, false)
169 + )
147170
148- return div
171 + return div
172 + }
173 + }
149174 }
150175 }
151176
152177
153178
154-
155-
modules_extra/query.jsView
@@ -1,60 +1,66 @@
11 var h = require('hyperscript')
22 var pull = require('pull-stream')
33 var HJSON = require('hjson')
44
5-var sbot_query = require('../plugs').first(exports.sbot_query = [])
5 +//var sbot_query = require('../plugs').first(exports.sbot_query = [])
66
7-exports.menu_items = function () {
8- return h('a', {href:'#/query'}, '/query')
9-}
7 +exports.needs = { sbot_query: 'first' }
108
11-exports.builtin_tabs = function () {
12- return ['/query']
9 +exports.gives = {
10 + menu_items: true,
11 + builtin_tabs: true,
12 + screen_view: true
1313 }
1414
15-exports.screen_view = function (path) {
16- if(path != '/query') return
17- var output, status, editor, stream, query
15 +exports.create = function (api) {
1816
19- function parse () {
20- try {
21- query = HJSON.parse(editor.value)
22- } catch (err) {
23- return status.textContent = err.message
24- }
25- status.textContent = 'okay'
26- }
17 + return {
18 + menu_items: function () {
19 + return h('a', {href:'#/query'}, '/query')
20 + },
2721
28- return h('div.column.scroll',
29- editor = h('textarea', {style: 'min-height:100px;', oninput: parse, onkeydown: function (e) {
30- if(!(e.keyCode === 13 && e.ctrlKey)) return
22 + builtin_tabs: function () {
23 + return ['/query']
24 + },
25 +
26 + screen_view: function (path) {
27 + if(path != '/query') return
28 + var output, status, editor, stream, query
29 +
30 + function parse () {
31 + try {
32 + query = HJSON.parse(editor.value)
33 + } catch (err) {
34 + return status.textContent = err.message
35 + }
36 + status.textContent = 'okay'
37 + }
38 +
39 + return h('div.column.scroll',
40 + editor = h('textarea', {style: 'min-height:100px;', oninput: parse, onkeydown: function (e) {
41 + if(!(e.keyCode === 13 && e.ctrlKey)) return
3142
32- status.textContent = 'running...'
33- parse()
34- output.innerHTML = ''
35- if(stream) stream.abort()
43 + status.textContent = 'running...'
44 + parse()
45 + output.innerHTML = ''
46 + if(stream) stream.abort()
3647
37- console.log(query)
48 + console.log(query)
3849
39- stream = pull(
40- sbot_query({query: query, limit: 100}),
41- pull.drain(function (data) {
42- output.appendChild(h('pre.query__data',
43- JSON.stringify(data, null, 2)
44- ))
45- }, function (err) {
46- if(err) status.textContent = err.stack
47- })
50 + stream = pull(
51 + api.sbot_query({query: query, limit: 100}),
52 + pull.drain(function (data) {
53 + output.appendChild(h('pre.query__data',
54 + JSON.stringify(data, null, 2)
55 + ))
56 + }, function (err) {
57 + if(err) status.textContent = err.stack
58 + })
59 + )
60 + }}),
61 + status = h('div.query__status'),
62 + output = h('div.column.query__output', {style: 'overflow-y: scroll;'})
4863 )
49- }}),
50- status = h('div.query__status'),
51- output = h('div.column.query__output', {style: 'overflow-y: scroll;'})
52- )
64 + }
65 + }
5366 }
54-
55-
56-
57-
58-
59-
60-
modules_extra/raw.jsView
@@ -3,50 +3,53 @@
33 var pull = require('pull-stream')
44 var Scroller = require('pull-scroll')
55
66 var plugs = require('../plugs')
7-var message_render = plugs.first(exports.message_render = [])
8-var message_compose = plugs.first(exports.message_compose = [])
7 +//var message_render = plugs.first(exports.message_render = [])
8 +//var message_compose = plugs.first(exports.message_compose = [])
99
1010 // from ssb-ref
1111 var refRegex = /((?:@|%|&)[A-Za-z0-9\/+]{43}=\.[\w\d]+)/g
1212
13-exports.linkify = function (text) {
13 +exports.gives = 'message_meta'
14 +
15 +function linkify (text) {
1416 var arr = text.split(refRegex)
1517 for (var i = 1; i < arr.length; i += 2) {
1618 arr[i] = h('a', {href: '#' + arr[i]}, arr[i])
1719 }
1820 return arr
1921 }
2022
21-exports.message_meta = function (msg) {
22- var tmp = h('div')
23- var el
24- var pre
25- return h('input', {
26- type: 'checkbox',
27- title: 'View Data',
28- onclick: function () {
29- var msgEl = this.parentNode.parentNode.parentNode
30- var msgContentEl = msgEl.querySelector('.message_content')
31- if (this.checked) {
32- // move away the content
33- while (el = msgContentEl.firstChild)
34- tmp.appendChild(el)
35- // show the raw stuff
36- if (!pre) pre = h('pre', exports.linkify(JSON.stringify({
37- key: msg.key,
38- value: msg.value
39- }, 0, 2)))
40- msgContentEl.appendChild(pre)
41- } else {
42- // hide the raw stuff
43- msgContentEl.removeChild(pre)
44- // put back the content
45- while (el = tmp.firstChild)
46- msgContentEl.appendChild(el)
23 +exports.create = function (api) {
24 + return function (msg) {
25 + var tmp = h('div')
26 + var el
27 + var pre
28 + return h('input', {
29 + type: 'checkbox',
30 + title: 'View Data',
31 + onclick: function () {
32 + var msgEl = this.parentNode.parentNode.parentNode
33 + var msgContentEl = msgEl.querySelector('.message_content')
34 + if (this.checked) {
35 + // move away the content
36 + while (el = msgContentEl.firstChild)
37 + tmp.appendChild(el)
38 + // show the raw stuff
39 + if (!pre) pre = h('pre', linkify(JSON.stringify({
40 + key: msg.key,
41 + value: msg.value
42 + }, 0, 2)))
43 + msgContentEl.appendChild(pre)
44 + } else {
45 + // hide the raw stuff
46 + msgContentEl.removeChild(pre)
47 + // put back the content
48 + while (el = tmp.firstChild)
49 + msgContentEl.appendChild(el)
50 + }
4751 }
48- }
49- })
52 + })
53 + }
5054 }
5155
52-
modules_extra/search.jsView
@@ -3,11 +3,19 @@
33 var pull = require('pull-stream')
44 var Scroller = require('pull-scroll')
55 var TextNodeSearcher = require('text-node-searcher')
66
7-var plugs = require('../plugs')
8-var message_render = plugs.first(exports.message_render = [])
9-var sbot_log = plugs.first(exports.sbot_log = [])
7 +//var plugs = require('../plugs')
8 +//var message_render = plugs.first(exports.message_render = [])
9 +//var sbot_log = plugs.first(exports.sbot_log = [])
10 +
11 +exports.needs = {
12 + message_render: 'first',
13 + sbot_log: 'first'
14 +}
15 +
16 +exports.gives = 'screen_view'
17 +
1018 var whitespace = /\s+/
1119
1220 function andSearch(terms, inputs) {
1321 for(var i = 0; i < terms.length; i++) {
@@ -45,61 +53,56 @@
4553 searcher.highlight()
4654 return el
4755 }
4856
49-exports.screen_view = function (path) {
50- if(path[0] === '?') {
51- var query = path.substr(1).trim().split(whitespace)
52- var _matches = searchFilter(query)
57 +exports.create = function (api) {
5358
54- var total = 0, matches = 0
59 + return function (path) {
60 + if(path[0] === '?') {
61 + var query = path.substr(1).trim().split(whitespace)
62 + var _matches = searchFilter(query)
5563
56- var header = h('div.search_header', '')
57- var content = h('div.column.scroller__content')
58- var div = h('div.column.scroller',
59- {style: {'overflow':'auto'}},
60- h('div.scroller__wrapper',
61- header,
62- content
64 + var total = 0, matches = 0
65 +
66 + var header = h('div.search_header', '')
67 + var content = h('div.column.scroller__content')
68 + var div = h('div.column.scroller',
69 + {style: {'overflow':'auto'}},
70 + h('div.scroller__wrapper',
71 + header,
72 + content
73 + )
6374 )
64- )
6575
66- function matchesQuery (data) {
67- total++
68- var m = _matches(data)
69- if(m) matches++
70- header.textContent = 'searched:'+total+', found:'+matches
71- return m
72- }
76 + function matchesQuery (data) {
77 + total++
78 + var m = _matches(data)
79 + if(m) matches++
80 + header.textContent = 'searched:'+total+', found:'+matches
81 + return m
82 + }
7383
7484
7585
76- function renderMsg(msg) {
77- var el = message_render(msg)
78- highlight(el, createOrRegExp(query))
79- return el
80- }
86 + function renderMsg(msg) {
87 + var el = api.message_render(msg)
88 + highlight(el, createOrRegExp(query))
89 + return el
90 + }
8191
82- pull(
83- sbot_log({old: false}),
84- pull.filter(matchesQuery),
85- Scroller(div, content, renderMsg, true, false)
86- )
92 + pull(
93 + api.sbot_log({old: false}),
94 + pull.filter(matchesQuery),
95 + Scroller(div, content, renderMsg, true, false)
96 + )
8797
88- pull(
89- u.next(sbot_log, {reverse: true, limit: 500, live: false}),
90- pull.filter(matchesQuery),
91- Scroller(div, content, renderMsg, false, false)
92- )
98 + pull(
99 + u.next(api.sbot_log, {reverse: true, limit: 500, live: false}),
100 + pull.filter(matchesQuery),
101 + Scroller(div, content, renderMsg, false, false)
102 + )
93103
94- return div
104 + return div
105 + }
95106 }
107 +
96108 }
97-
98-
99-
100-
101-
102-
103-
104-
105-
modules_extra/split.jsView
@@ -1,17 +1,27 @@
11 var h = require('hyperscript')
22
3-var screen_view =
4- require('../plugs').first(exports._screen_view = [])
3 +//var screen_view =
4 +// require('../plugs').first(exports._screen_view = [])
55
6-exports.screen_view = function (path) {
7- var m = /^split\s*\((.*)\)$/.exec(path)
8- if(!m)
9- return
106
11- return h('div.row',
12- m[1].split(',').map(function (e) {
13- return screen_view(e.trim())
14- }).filter(Boolean)
15- )
7 +exports.needs = {
8 + screen_view: 'first'
169 }
1710
11 +exports.gives = 'screen_view'
12 +
13 +exports.create = function (api) {
14 +
15 + return function (path) {
16 + var m = /^split\s*\((.*)\)$/.exec(path)
17 + if(!m)
18 + return
19 +
20 + return h('div.row',
21 + m[1].split(',').map(function (e) {
22 + return api.screen_view(e.trim())
23 + }).filter(Boolean)
24 + )
25 + }
26 +
27 +}
modules_extra/suggest-emoji.jsView
@@ -1,19 +1,32 @@
1-var plugs = require('../plugs')
2-var emoji_url = plugs.first(exports.emoji_url = [])
3-var emoji_names = plugs.first(exports.emoji_names = [])
1 +//var plugs = require('../plugs')
2 +//var emoji_url = plugs.first(exports.emoji_url = [])
3 +//var emoji_names = plugs.first(exports.emoji_names = [])
44
5-exports.suggest_mentions = function (word, cb) {
6- if (word[0] !== ':' || word.length < 2) return cb()
7- word = word.substr(1)
8- if (word[word.length-1] === ':') word = word.substr(0, word.length-1)
9- cb(null, emoji_names().filter(function (name) {
10- return name.substr(0, word.length) === word
11- }).slice(0, 50).map(function (emoji) {
12- return {
13- image: emoji_url(emoji),
14- title: emoji,
15- subtitle: emoji,
16- value: ':' + emoji + ':'
5 +exports.needs = {
6 + emoji_url: 'first',
7 + emoji_names: 'first'
8 +}
9 +
10 +exports.gives = 'suggest_mentions'
11 +
12 +exports.create = function (api) {
13 +
14 + return function (word) {
15 + return function (cb) {
16 + if (word[0] !== ':' || word.length < 2) return cb()
17 + word = word.substr(1)
18 + if (word[word.length-1] === ':') word = word.substr(0, word.length-1)
19 + cb(null, api.emoji_names().filter(function (name) {
20 + return name.substr(0, word.length) === word
21 + }).slice(0, 50).map(function (emoji) {
22 + return {
23 + image: api.emoji_url(emoji),
24 + title: emoji,
25 + subtitle: emoji,
26 + value: ':' + emoji + ':'
27 + }
28 + }))
1729 }
18- }))
30 + }
31 +
1932 }
modules_extra/versions.jsView
@@ -1,40 +1,50 @@
11 var h = require('hyperscript')
22
3-exports.menu_items = function () {
4- return h('a', {href: '#/versions'}, '/versions')
3 +exports.gives = {
4 + menu_items: true,
5 + builtin_tabs: true,
6 + screen_view: true
57 }
68
7-exports.builtin_tabs = function () {
8- return ['/versions']
9-}
9 +exports.create = function () {
1010
11-exports.screen_view = function (path) {
12- if(path !== '/versions') return
11 + return {
12 + menu_items: function () {
13 + return h('a', {href: '#/versions'}, '/versions')
14 + },
1315
14- if('undefined' === typeof WebBoot)
15- return h('h1', 'must run with web-boot enabled enviroment')
16 + builtin_tabs: function () {
17 + return ['/versions']
18 + },
1619
17- var content = h('div.column')
20 + screen_view: function (path) {
21 + if(path !== '/versions') return
1822
19- WebBoot.versions(function (err, log) {
20- log.forEach(function (e, i) {
21- content.appendChild(
22- h('div.row',
23- h('a', {
24- href: '#/run:'+e.value,
25- onclick: function () {
26- WebBoot.run(e.value, function () {
27- console.log('rebooting to:', e.value)
28- })
29- }
30- }, ' ', e.value, ' ', new Date(e.ts)),
31- !i && h('label', '(current)')
32- )
33- )
34- })
23 + if('undefined' === typeof WebBoot)
24 + return h('h1', 'must run with web-boot enabled enviroment')
3525
36- })
26 + var content = h('div.column')
3727
38- return content
28 + WebBoot.versions(function (err, log) {
29 + log.forEach(function (e, i) {
30 + content.appendChild(
31 + h('div.row',
32 + h('a', {
33 + href: '#/run:'+e.value,
34 + onclick: function () {
35 + WebBoot.run(e.value, function () {
36 + console.log('rebooting to:', e.value)
37 + })
38 + }
39 + }, ' ', e.value, ' ', new Date(e.ts)),
40 + !i && h('label', '(current)')
41 + )
42 + )
43 + })
44 +
45 + })
46 +
47 + return content
48 + }
49 + }
3950 }
40-

Built with git-ssb-web