git ssb

16+

Dominic / patchbay



Commit 560b4eeaebdc81616f23b3384a8c6ac9c0126e09

merge

Dominic Tarr committed on 12/6/2016, 3:20:44 PM
Parent: 3a059da9a5018fb341af69ba26f2bf1a59c0005c
Parent: 86745d2ae3eb9733681d16c4e9cfabeeef30b588

Files changed

README.mdchanged
modules_basic/compose.jschanged
modules_basic/follow.jschanged
modules_basic/index.jschanged
modules_basic/invite.jschanged
modules_basic/like.jschanged
modules_basic/markdown.jschanged
modules_basic/message-name.jschanged
modules_basic/message.jschanged
modules_basic/names.jschanged
modules_basic/private.jschanged
modules_basic/public.jschanged
modules_basic/search-box.jschanged
modules_basic/suggest-mentions.jschanged
modules_basic/thread.jschanged
modules_basic/timestamp.jschanged
modules_basic/pub.jsadded
modules_core/tabs.jschanged
modules_extra/channel.jschanged
modules_extra/git.jschanged
modules_extra/index.jschanged
modules_extra/network.jschanged
modules_extra/notifications.jschanged
modules_extra/query.jschanged
modules_extra/versions.jschanged
modules_extra/dns.jsadded
modules_extra/emoji.jsadded
modules_extra/git-ssb.jsadded
modules_extra/suggest-emoji.jsadded
package.jsonchanged
plugs.jschanged
style.csschanged
README.mdView
@@ -33,11 +33,11 @@
3333 ```
3434 git clone https://github.com/dominictarr/patchbay.git
3535 cd patchbay
3636 npm install
37-npm install electro electron-prebuilt -g
38-npm run build
39-electro index.js
37 +npm run rebuild
38 +npm run bundle
39 +npm start
4040 ```
4141
4242 ## how to add a feature
4343
modules_basic/compose.jsView
@@ -1,22 +1,19 @@
11 'use strict'
22 var h = require('hyperscript')
33 var u = require('../util')
44 var suggest = require('suggest-box')
5-var cont = require('cont')
65 var mentions = require('ssb-mentions')
76 var lightbox = require('hyperlightbox')
87
98 var plugs = require('../plugs')
109
11-//var suggest = plugs.map(exports.suggest = [])
10 +var suggest_mentions= plugs.asyncConcat(exports.suggest_mentions = [])
1211 var publish = plugs.first(exports.sbot_publish = [])
1312 var message_content = plugs.first(exports.message_content = [])
1413 var message_confirm = plugs.first(exports.message_confirm = [])
1514 var file_input = plugs.first(exports.file_input = [])
1615
17-exports.suggest = []
18-
1916 function id (e) { return e }
2017
2118 /*
2219 opts can take
@@ -125,26 +122,11 @@
125122 publishBtn)
126123 )
127124 )
128125
129- suggest(ta, function (word, cb) {
130- cont.para(exports.suggest.map(function (fn) {
131- return function (cb) { fn(word, cb) }
132- }))
133- (function (err, results) {
134- if(err) console.error(err)
135- results = results.reduce(function (ary, item) {
136- return ary.concat(item)
137- }, []).sort(function (a, b) {
138- return b.rank - a.rank
139- }).filter(Boolean)
126 + suggest(ta, suggest_mentions, {})
140127
141- cb(null, results)
142- })
143- }, {})
144-
145128 return composer
146129
147130 }
148131
149132
150-
modules_basic/follow.jsView
@@ -52,9 +52,9 @@
5252 update()
5353 })
5454
5555 var state = h('label')
56- var label = h('label')
56 + var label = h('span')
5757
5858 function update () {
5959 state.textContent = (
6060 follows_you && you_follow ? 'friend'
@@ -71,10 +71,12 @@
7171 message_confirm({
7272 type: 'contact',
7373 contact: id,
7474 following: !you_follow
75- }, function (err) {
76- //TODO: update after following.
75 + }, function (err, msg) {
76 + if (err) return console.error(err)
77 + you_follow = msg.value.content.following
78 + update()
7779 })
7880 }}, h('br'), label)
7981 )
8082 }
modules_basic/index.jsView
@@ -17,8 +17,9 @@
1717 "message.js": require('./message.js'),
1818 "names.js": require('./names.js'),
1919 "post.js": require('./post.js'),
2020 "private.js": require('./private.js'),
21 + "pub.js": require('./pub.js'),
2122 "public.js": require('./public.js'),
2223 "relationships.js": require('./relationships.js'),
2324 "search-box.js": require('./search-box.js'),
2425 "setup.js": require('./setup'),
modules_basic/invite.jsView
@@ -92,9 +92,9 @@
9292
9393 //TODO: handle in a consistent way with either hashrouting
9494 //or with tabs...
9595 if(parts[0] === data.invite)
96- location.hash = data.redirect
96 + location.hash = ''
9797 else
9898 console.log("NO REDIRECT")
9999 })
100100 }
modules_basic/like.jsView
@@ -14,9 +14,9 @@
1414 exports.message_content_mini = function (msg, sbot) {
1515 if(msg.value.content.type !== 'vote') return
1616 var link = msg.value.content.vote.link
1717 return [
18- msg.value.content.vote.value > 0 ? 'Dug' : 'Undug',
18 + msg.value.content.vote.value > 0 ? 'dug' : 'undug',
1919 ' ', message_link(link)
2020 ]
2121 }
2222
modules_basic/markdown.jsView
@@ -1,10 +1,21 @@
11 var markdown = require('ssb-markdown')
22 var h = require('hyperscript')
33 var ref = require('ssb-ref')
44
5-var blob_url = require('../plugs').first(exports.blob_url = [])
5 +var plugs = require('../plugs')
6 +var blob_url = plugs.first(exports.blob_url = [])
7 +var emoji_url = plugs.first(exports.emoji_url = [])
68
9 +function renderEmoji(emoji) {
10 + var url = emoji_url(emoji)
11 + if (!url) return ':' + emoji + ':'
12 + return '<img src="' + encodeURI(url) + '"'
13 + + ' alt=":' + escape(emoji) + ':"'
14 + + ' title=":' + escape(emoji) + ':"'
15 + + ' class="emoji">'
16 +}
17 +
718 exports.markdown = function (content) {
819 if('string' === typeof content)
920 content = {text: content}
1021 //handle patchwork style mentions.
@@ -15,8 +26,9 @@
1526 })
1627
1728 var md = h('div.markdown')
1829 md.innerHTML = markdown.block(content.text, {
30 + emoji: renderEmoji,
1931 toUrl: function (id) {
2032 if(ref.isBlob(id)) return blob_url(id)
2133 return '#'+(mentions[id]?mentions[id]:id)
2234 }
modules_basic/message-name.jsView
@@ -1,10 +1,10 @@
11
22 var sbot_get = require('../plugs').first(exports.sbot_get = [])
33
44 function title (s) {
5- var m = /^[^\n]{0,40}/.exec(s)
6- return m && (m[0].length == 40 ? m[0]+'...' : m[0])
5 + var m = /^\n*([^\n]{0,40})/.exec(s)
6 + return m && (m[1].length == 40 ? m[1]+'...' : m[1])
77 }
88
99 exports.message_name = function (id, cb) {
1010 sbot_get(id, function (err, value) {
modules_basic/message.jsView
@@ -13,26 +13,31 @@
1313 var message_link = plugs.first(exports.message_link = [])
1414
1515 var sbot_links = plugs.first(exports.sbot_links = [])
1616
17-exports.message_render = function (msg, sbot) {
18- var elMini = message_content_mini(msg)
19- if (elMini) {
20- var div = h('div.message.message--mini',
21- h('div.row',
22- h('div',
23- avatar_link(msg.value.author, avatar_name(msg.value.author), ''),
24- ' ',
25- h('span.message_content', elMini)),
26- h('div.message_meta.row', message_meta(msg))
27- )
17 +function mini(msg, el) {
18 + var div = h('div.message.message--mini',
19 + h('div.row',
20 + h('div',
21 + avatar_link(msg.value.author, avatar_name(msg.value.author)),
22 + h('span.message_content', el)),
23 + h('div.message_meta.row', message_meta(msg))
2824 )
29- div.setAttribute('tabindex', '0')
30- return div
31- }
25 + )
26 + div.setAttribute('tabindex', '0')
27 + return div
28 +}
3229
30 +function message_content_mini_fallback(msg) {
31 + return h('code', msg.value.content.type)
32 +}
33 +
34 +exports.message_render = function (msg, sbot) {
35 + var el = message_content_mini(msg)
36 + if(el) return mini(msg, el)
37 +
3338 var el = message_content(msg)
34- if(!el) return
39 + if(!el) return mini(msg, message_content_mini_fallback(msg))
3540
3641 var links = []
3742 for(var k in CACHE) {
3843 var _msg = CACHE[k]
modules_basic/names.jsView
@@ -91,14 +91,33 @@
9191 })
9292 )
9393 }
9494
95 +var queryNamedGitRepos = [
96 + {$filter: {
97 + value: {
98 + content: {
99 + type: "git-repo",
100 + name: {"$prefix": ""}
101 + }
102 + }
103 + }},
104 + {$map: {
105 + name: ["value", "content", "name"],
106 + id: ['key'],
107 + ts: "timestamp"
108 + }},
109 + reduce
110 +]
111 +
112 +
95113 exports.connection_status = function (err) {
96114 if(!err) {
97115 pull(
98116 many([
99117 sbot_links2({query: [filter, map, reduce]}),
100- add_sigil(sbot_query({query: [filter2, map2, reduce]}))
118 + add_sigil(sbot_query({query: [filter2, map2, reduce]})),
119 + add_sigil(sbot_query({query: queryNamedGitRepos}))
101120 ]),
102121 //reducing also ensures order by the lookup properties
103122 //in this case: [name, id]
104123 mfr.reduce(merge),
@@ -112,9 +131,10 @@
112131 )
113132
114133 pull(many([
115134 sbot_links2({query: [filter, map], old: false}),
116- add_sigil(sbot_query({query: [filter2, map2], old: false}))
135 + add_sigil(sbot_query({query: [filter2, map2], old: false})),
136 + add_sigil(sbot_query({query: queryNamedGitRepos, old: false}))
117137 ]),
118138 pull.drain(update))
119139 }
120140 }
modules_basic/private.jsView
@@ -11,8 +11,9 @@
1111 var message_unbox = plugs.first(exports.message_unbox = [])
1212 var sbot_log = plugs.first(exports.sbot_log = [])
1313 var sbot_whoami = plugs.first(exports.sbot_whoami = [])
1414 var avatar_image_link = plugs.first(exports.avatar_image_link = [])
15 +var emoji_url = plugs.first(exports.emoji_url = [])
1516
1617 function unbox () {
1718 return pull(
1819 pull.filter(function (msg) {
@@ -24,8 +25,12 @@
2425 pull.filter(Boolean)
2526 )
2627 }
2728
29 +exports.builtin_tabs = function () {
30 + return ['/private']
31 +}
32 +
2833 exports.screen_view = function (path) {
2934 if(path !== '/private') return
3035
3136 var div = h('div.column.scroller',
@@ -86,5 +91,15 @@
8691 return avatar_image_link('string' == typeof id ? id : id.link, 'thumbnail')
8792 }))
8893 }
8994
95 +exports.message_content_mini = function (msg, sbot) {
96 + if (typeof msg.value.content === 'string') {
97 + var icon = emoji_url('lock')
98 + return icon
99 + ? h('img', {className: 'emoji', src: icon})
100 + : 'PRIVATE'
101 + }
102 +}
90103
104 +
105 +
modules_basic/public.jsView
@@ -7,8 +7,12 @@
77 var message_render = plugs.first(exports.message_render = [])
88 var message_compose = plugs.first(exports.message_compose = [])
99 var sbot_log = plugs.first(exports.sbot_log = [])
1010
11 +exports.builtin_tabs = function () {
12 + return ['/public']
13 +}
14 +
1115 exports.screen_view = function (path, sbot) {
1216 if(path === '/public') {
1317
1418 var content = h('div.column.scroller__content')
@@ -33,25 +37,4 @@
3337 return div
3438 }
3539 }
3640
37-
38-
39-
40-
41-
42-
43-
44-
45-
46-
47-
48-
49-
50-
51-
52-
53-
54-
55-
56-
57-
modules_basic/search-box.jsView
@@ -3,30 +3,19 @@
33 var pull = require('pull-stream')
44 var plugs = require('../plugs')
55 var sbot_query = plugs.first(exports.sbot_query = [])
66 var sbot_links2 = plugs.first(exports.sbot_links2 = [])
7 +var suggest_search = plugs.asyncConcat(exports.suggest_search = [])
78
89 var channels = []
910
10-var signified = require('../plugs').first(exports.signified = [])
1111
12-//TODO: this list should be generated from plugs
13-var builtinTabs = [
14- '/public', '/private', '/notifications',
15- '/network', '/query', '/versions'
16-].map(function (name) {
17- return {
18- title: name,
19- value: name,
20- }
21-})
22-
2312 exports.search_box = function (go) {
2413
2514 var suggestBox
2615 var search = h('input.searchprompt', {
2716 type: 'search',
28- placeholder: '?word, @key, #channel',
17 + placeholder: 'Commands',
2918 onkeydown: function (ev) {
3019 switch (ev.keyCode) {
3120 case 13: // enter
3221 if (suggestBox && suggestBox.active) {
@@ -58,55 +47,9 @@
5847 var suggestions = {}
5948
6049 // delay until the element has a parent
6150 setTimeout(function () {
62- suggestBox = suggest(search, function (word, cb) {
63- if(/^#\w/.test(word))
64- cb(null, channels.filter(function (chan) {
65- return ('#'+chan.name).substring(0, word.length) === word
66- })
67- .map(function (chan) {
68- var name = '#'+chan.name
69- return {
70- title: name,
71- value: name,
72- subtitle: chan.rank
73- }
74- }))
75- else if(/^[@%]\w/.test(word)) {
76- signified(word, function (_, names) {
77- cb(null, names.map(function (e) {
78- return {
79- title: e.name + ':'+e.id.substring(0, 10),
80- value: e.id,
81- subtitle: e.rank
82- }
83- }))
84- })
85- } else if(/^\//.test(word)) {
86- cb(null, builtinTabs.filter(function (name) {
87- return name.value.substr(0, word.length) === word
88- }))
89- }
90- }, {})
51 + suggestBox = suggest(search, suggest_search, {})
9152 }, 10)
9253
93-
94- pull(
95- sbot_query({query: [
96- {$filter: {value: {content: {channel: {$gt: ''}}}}},
97- {$reduce: {
98- name: ['value', 'content', 'channel'],
99- rank: {$count: true}
100- }}
101- ]}),
102- pull.collect(function (err, chans) {
103- if (err) return console.error(err)
104- channels = chans
105- })
106- )
107-
10854 return search
10955 }
110-
111-
112-
modules_basic/suggest-mentions.jsView
@@ -1,15 +1,15 @@
11 var pull = require('pull-stream')
2-var cont = require('cont')
32 function isImage (filename) {
43 return /\.(gif|jpg|png|svg)$/i.test(filename)
54 }
65
76 var sbot_links2 = require('../plugs').first(exports.sbot_links2 = [])
87 var blob_url = require('../plugs').first(exports.blob_url = [])
98 var signified = require('../plugs').first(exports.signified = [])
9 +var builtin_tabs = require('../plugs').map(exports.builtin_tabs = [])
1010
11-exports.suggest = cont.to(function (word, cb) {
11 +exports.suggest_mentions = function (word, cb) {
1212 if(!/^[%&@]\w/.test(word)) return cb()
1313
1414
1515 signified(word, function (err, names) {
@@ -22,11 +22,35 @@
2222 //TODO: avatar images...
2323 }
2424 }))
2525 })
26-})
26 +}
2727
28 +exports.suggest_search = function (query, cb) {
29 + if(/^[@%]\w/.test(query)) {
30 + signified(query, function (_, names) {
31 + cb(null, names.map(function (e) {
32 + return {
33 + title: e.name + ':'+e.id.substring(0, 10),
34 + value: e.id,
35 + subtitle: e.rank,
36 + rank: e.rank
37 + }
38 + }))
39 + })
2840
41 + } else if(/^\//.test(query)) {
42 + var tabs = [].concat.apply([], builtin_tabs())
43 + cb(null, tabs.filter(function (name) {
44 + return name.substr(0, query.length) === query
45 + }).map(function (name) {
46 + return {
47 + title: name,
48 + value: name,
49 + }
50 + }))
51 + } else cb()
52 +}
2953
3054
3155
3256
@@ -37,4 +61,5 @@
3761
3862
3963
4064
65 +
modules_basic/thread.jsView
@@ -35,8 +35,9 @@
3535 //in this case, it's inconvienent that panel only takes
3636 //a stream. maybe it would be better to accept an array?
3737
3838 sbot_get(root, function (err, value) {
39 + if (err) return cb(err)
3940 var msg = {key: root, value: value}
4041 // if(value.content.root) return getThread(value.content.root, cb)
4142
4243 pull(
@@ -87,8 +88,10 @@
8788 //would probably be better keep an id for each message element
8889 //(i.e. message key) and then update it if necessary.
8990 //also, it may have moved (say, if you received a missing message)
9091 content.innerHTML = ''
92 + if(err) return content.appendChild(h('pre', err.stack))
93 +
9194 //decrypt
9295 thread = thread.map(function (msg) {
9396 return 'string' === typeof msg.value.content ? message_unbox(msg) : msg
9497 })
modules_basic/timestamp.jsView
@@ -1,12 +1,7 @@
11 var h = require('hyperscript')
2-var _human = require('human-time')
2 +var human = require('human-time')
33
4-function human (date) {
5- var s =_human(date).split(' ')
6- return s[0] + (s[1] == 'month' ? 'M' : s[1][0])
7-}
8-
94 function updateTimestampEl(el) {
105 el.firstChild.nodeValue = human(new Date(el.timestamp))
116 return el
127 }
@@ -16,14 +11,11 @@
1611 els.forEach(updateTimestampEl)
1712 }, 60e3)
1813
1914 exports.message_meta = function (msg) {
20- var d = new Date(msg.value.timestamp)
2115 return updateTimestampEl(h('a.enter.timestamp', {
2216 href: '#'+msg.key,
2317 timestamp: msg.value.timestamp,
24- title: _human(d) + '\n'+d
18 + title: new Date(msg.value.timestamp)
2519 }, ''))
2620 }
2721
28-
29-
modules_basic/pub.jsView
@@ -1,0 +1,18 @@
1 +var h = require('hyperscript')
2 +var plugs = require('../plugs')
3 +var avatar_name = plugs.first(exports.avatar_name = [])
4 +var avatar_link = plugs.first(exports.avatar_link = [])
5 +
6 +exports.message_content = function (msg, sbot) {
7 + var c = msg.value.content
8 + if (c.type === 'pub') {
9 + var address = c.address || {}
10 + return [
11 + h('p', 'announced an address for ',
12 + avatar_link(address.key, avatar_name(address.key)), ':'),
13 + h('blockquote',
14 + h('code', address.host + ':' + address.port)
15 + )
16 + ]
17 + }
18 +}
modules_core/tabs.jsView
@@ -85,8 +85,11 @@
8585
8686 ev.preventDefault()
8787 ev.stopPropagation()
8888
89 + //let the application handle this link
90 + if (link.getAttribute('href') === '#') return
91 +
8992 //open external links.
9093 //this ought to be made into something more runcible
9194 if(open.isExternal(link.href)) return open(link.href)
9295
@@ -160,11 +163,12 @@
160163 })
161164
162165 // errors tab
163166 var errorsContent = h('div.column.scroller__content')
164- var errors = h('div.column.scroller',
165- {style: {'overflow':'auto'}},
166- h('div.scroller__wrapper',
167 + var errors = h('div.column.scroller', {
168 + id: 'errors',
169 + style: {'overflow':'auto'}
170 + }, h('div.scroller__wrapper',
167171 errorsContent
168172 )
169173 )
170174
@@ -173,10 +177,8 @@
173177 window.removeEventListener('error', window.onError)
174178 delete window.onError
175179 }
176180
177- var errors = h('div.errors', {id: 'errors'})
178-
179181 // put errors in a tab
180182 window.addEventListener('error', function (ev) {
181183 var err = ev.error || ev
182184 if(!tabs.has('errors'))
modules_extra/channel.jsView
@@ -7,8 +7,9 @@
77 var message_render = plugs.first(exports.message_render = [])
88 var message_compose = plugs.first(exports.message_compose = [])
99 var sbot_log = plugs.first(exports.sbot_log = [])
1010 var sbot_query = plugs.first(exports.sbot_query = [])
11 +var mfr = require('map-filter-reduce')
1112
1213 exports.message_meta = function (msg) {
1314 var chan = msg.value.content.channel
1415 if (chan)
@@ -49,4 +50,55 @@
4950
5051 return div
5152 }
5253 }
54 +
55 +var channels
56 +
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 +}}
63 +
64 +exports.connection_status = function (err) {
65 + if(err) return
66 +
67 + channels = []
68 +
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 + )
76 +
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 +}
90 +
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
102 + }
103 + }))
104 +}
modules_extra/git.jsView
@@ -186,12 +186,10 @@
186186 h('div', h('a', {href: '#', onclick: function (e) {
187187 e.preventDefault()
188188 this.parentNode.replaceChild(issueForm(msg), this)
189189 }}, 'New Issue…')),
190- h('div', h('a', {href: '#', onclick: function (e) {
191- e.preventDefault()
192- this.parentNode.replaceChild(pullRequestForm(msg), this)
193- }}, 'New Pull Request…')))
190 + newPullRequestButton.call(this, msg)
191 + )
194192
195193 pull(getRefs(msg), pull.drain(function (ref) {
196194 var name = ref.realname || ref.name
197195 var author = ref.link && ref.link.value.author
@@ -289,9 +287,10 @@
289287 h('code', issue.object), ' ', h('q', issue.label))
290288 if (issue.open === false)
291289 return h('p', 'Closed ', message_link(issue.link), ' in ',
292290 h('code', issue.object), ' ', h('q', issue.label))
293- }) : null
291 + }) : null,
292 + newPullRequestButton.call(this, msg)
294293 ]
295294 }
296295
297296 if(c.type === 'issue-edit'
@@ -382,8 +381,21 @@
382381 }))
383382 })
384383 }
385384
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 +}
397 +
386398 function pullRequestForm(msg) {
387399 var headRepoInput
388400 var headBranchInput = branchMenu()
389401 var branchInput = branchMenu(msg)
modules_extra/index.jsView
@@ -1,8 +1,12 @@
11 module.exports = {
22 "audio-mp3.js": require('./audio-mp3.js'),
33 "channel.js": require('./channel.js'),
4 + "emoji.js": require('./emoji.js'),
5 + "suggest-emoji.js": require('./suggest-emoji.js'),
6 + "dns.js": require('./dns.js'),
47 "git.js": require('./git.js'),
8 + "git-ssb.js": require('./git-ssb.js'),
59 "notifications.js": require('./notifications.js'),
610 "meta-image.js": require('./meta-image.js'),
711 "music-release-cc.js": require('./music-release-cc.js'),
812 "music-release.js": require('./music-release.js'),
modules_extra/network.jsView
@@ -17,8 +17,12 @@
1717 exports.menu_items = function () {
1818 return h('a', {href: '#/network'}, '/network')
1919 }
2020
21 +exports.builtin_tabs = function () {
22 + return ['/network']
23 +}
24 +
2125 //types of peers
2226
2327
2428 //on the same wifi network
modules_extra/notifications.jsView
@@ -22,8 +22,12 @@
2222 pull.filter(Boolean)
2323 )
2424 }
2525
26 +exports.builtin_tabs = function () {
27 + return ['/notifications']
28 +}
29 +
2630 function notifications(ourIds) {
2731
2832 function linksToUs(link) {
2933 return link && link.link in ourIds
modules_extra/query.jsView
@@ -7,8 +7,12 @@
77 exports.menu_items = function () {
88 return h('a', {href:'#/query'}, '/query')
99 }
1010
11 +exports.builtin_tabs = function () {
12 + return ['/query']
13 +}
14 +
1115 exports.screen_view = function (path) {
1216 if(path != '/query') return
1317 var output, status, editor, stream, query
1418
modules_extra/versions.jsView
@@ -3,8 +3,12 @@
33 exports.menu_items = function () {
44 return h('a', {href: '#/versions'}, '/versions')
55 }
66
7 +exports.builtin_tabs = function () {
8 + return ['/versions']
9 +}
10 +
711 exports.screen_view = function (path) {
812 if(path !== '/versions') return
913
1014 if('undefined' === typeof WebBoot)
modules_extra/dns.jsView
@@ -1,0 +1,28 @@
1 +var h = require('hyperscript')
2 +
3 +function array(obj) {
4 + return !obj ? [] : Array.isArray(obj) ? obj : [obj]
5 +}
6 +
7 +function idLink(id) {
8 + return h('a', {href: '#'+id}, id.substring(0, 10)+'…')
9 +}
10 +
11 +exports.message_content = function (msg, sbot) {
12 + var c = msg.value.content
13 +
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 + ))
27 + }
28 +}
modules_extra/emoji.jsView
@@ -1,0 +1,14 @@
1 +var emojis = require('emoji-named-characters')
2 +var emojiNames = Object.keys(emojis)
3 +
4 +var plugs = require('../plugs')
5 +var blob_url = plugs.first(exports.blob_url = [])
6 +
7 +exports.emoji_names = function () {
8 + return emojiNames
9 +}
10 +
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
@@ -1,0 +1,41 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var pull = require('pull-stream')
4 +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 +
11 +exports.menu_items = function () {
12 + return h('a', {href: '#/git-ssb'}, '/git-ssb')
13 +}
14 +
15 +exports.screen_view = function (path, sbot) {
16 + if(path === '/git-ssb') {
17 +
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 + )
23 +
24 + pull(
25 + u.next(sbot_log, {old: false, limit: 100}),
26 + Scroller(div, content, message_render, true, false)
27 + )
28 +
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 + )
37 +
38 + return div
39 + }
40 +}
41 +
modules_extra/suggest-emoji.jsView
@@ -1,0 +1,19 @@
1 +var plugs = require('../plugs')
2 +var emoji_url = plugs.first(exports.emoji_url = [])
3 +var emoji_names = plugs.first(exports.emoji_names = [])
4 +
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 + ':'
17 + }
18 + }))
19 +}
package.jsonView
@@ -1,8 +1,8 @@
11 {
22 "name": "patchbay",
33 "description": "a pluggable patchwork",
4- "version": "5.2.0",
4 + "version": "5.5.0",
55 "homepage": "https://github.com/dominictarr/patchbay",
66 "repository": {
77 "type": "git",
88 "url": "git://github.com/dominictarr/patchbay.git"
@@ -55,14 +55,21 @@
5555 "text-node-searcher": "^1.1.0",
5656 "visualize-buffer": "0.0.0"
5757 },
5858 "devDependencies": {
59- "browselectrify": "^1.0.1"
59 + "browselectrify": "^1.0.1",
60 + "electro": "^2.0.3",
61 + "electron": "^1.4.10"
6062 },
6163 "scripts": {
62- "build": "node scripts/style.js && mkdir -p build && browselectrify index.js > build/bundle.js",
64 + "lite": "node scripts/style.js && mkdir -p build && browserify index.js | indexhtmlify > build/index.html",
65 + "start": "electro index.js",
66 + "bundle": "node scripts/style.js && mkdir -p build && browselectrify index.js > build/bundle.js",
67 + "rebuild": "npm rebuild --runtime=electron --target=$(electron -v) --abi=$(electron --abi) --disturl=https://atom.io/download/atom-shell",
6368 "graph": "node index.js | dot -Tsvg > graph.svg",
6469 "test": "set -e; for t in test/*.js; do node $t; done"
6570 },
6671 "author": "Dominic Tarr <dominic.tarr@gmail.com> (http://dominictarr.com)",
6772 "license": "MIT"
6873 }
74 +
75 +
plugs.jsView
@@ -16,5 +16,25 @@
1616 }).filter(Boolean)
1717 }
1818 }
1919
20 +exports.asyncConcat = function (plug) {
21 + return function () {
22 + var args = [].slice.call(arguments)
23 + var cb = args.pop()
24 + var allResults = []
25 + var waiting = plug.length
26 + plug.forEach(function (fn) {
27 + if (!fn) return next()
28 + fn.apply(null, args.concat(next))
29 + })
30 + function next(err, results) {
31 + if (err) {
32 + waiting = 0
33 + return cb(err)
34 + }
35 + if (results) allResults = allResults.concat(results)
36 + if (--waiting === 0) cb(null, allResults)
37 + }
38 + }
39 +}
2040
style.cssView
@@ -1,8 +1,19 @@
11 body {
22 font-family: sans-serif;
33 }
44
5 +h1, h2, h3, h4, h5, h6, p, ul, ol {
6 + margin-top: .35em;
7 +}
8 +
9 +h1 { font-size: 1.2em; }
10 +h2 { font-size: 1.18em; }
11 +h3 { font-size: 1.15em; }
12 +h4 { font-size: 1.12em; }
13 +h5 { font-size: 1.1em; }
14 +h6 { font-size: 1em; }
15 +
516 * {
617 word-break: break-word;
718 }
819
@@ -18,10 +29,10 @@
1829 }
1930
2031 .screen {
2132 position: absolute;
22- top: 0px; bottom: 0px;
23- left: 0px; right: 0px;
33 + top: 0; bottom: 0;
34 + left: 0; right: 0;
2435 overflow-y: hidden;
2536 }
2637
2738 .column {
@@ -98,14 +109,14 @@
98109 }
99110
100111 textarea {
101112 padding: .5em;
113 + font-size: 1em;
102114 }
103115
104116 textarea:focus {
105117 outline: none;
106118 border-color: none;
107- box-shadow: none;
108119 }
109120
110121 button {
111122 background: #fff;
@@ -134,10 +145,10 @@
134145 padding-right: 1em;
135146 padding-left: 1em;
136147 background: #f5f5f5;
137148 border: 1px solid #eee;
138- box-shadow: 3px 0px 3px #ccc;
139149 border-radius: .2em;
150 + z-index: 5;
140151 }
141152
142153 /* scrolling feeds, threads */
143154
@@ -157,9 +168,9 @@
157168 .compose {
158169 width: 100%;
159170 margin-top: .5em;
160171 margin-bottom: .5em;
161- box-shadow: #dadada 1px 2px 8px;
172 + border: 1px solid #f5f5f5;
162173 }
163174
164175 .compose button {
165176 float: right;
@@ -167,36 +178,41 @@
167178
168179 /* messages */
169180
170181 .message {
171- word-wrap: break-word;
172- margin-bottom: 1em;
173- padding: 0.3rem;
174- border-radius: 2px;
175- box-shadow: #dadada 1px 2px 8px;
182 + position: relative;
183 + flex-basis: 0;
184 + margin-top: .25em;
185 + margin-bottom: .25em;
186 + padding: .2em;
187 + border-top: 1px solid #f5f5f5;
188 + // border-bottom: 1px solid #f5f5f5;
176189 background: white;
177190 }
178191
192 +.message:hover {
193 + background: #f9f9f9;
194 +}
195 +
179196 .message--mini {
180- margin-bottom: 1em;
181- padding: ;
182- border-radius: 0;
183- box-shadow: none;
197 + font-size: 1em;
198 + margin: 0;
199 + padding: .2em;
200 + border: none;
184201 background: inherit;
185202 }
186203
187204 .message_content div > span {
188- font-size: 0.8rem;
189- margin-bottom: 0.7rem;
205 + font-size: 0.9em;
206 + margin-bottom: 0.7em;
190207 display: block;
191208 color: #888;
192209 }
193210
194211 .message_content--mini div > span {
195212 display: inline-block;
196213 }
197214
198-
199215 .message_content div > span a {
200216 color: #005d8c;
201217 }
202218
@@ -212,9 +228,10 @@
212228 margin-left: .5ex;
213229 }
214230
215231 .message_actions {
216- float: right;
232 + position: absolute;
233 + bottom: 0; right: 0;
217234 margin-right: .5ex;
218235 margin-bottom: .5ex;
219236 }
220237
@@ -243,30 +260,46 @@
243260 border-right: 2px solid #eee;
244261 padding-right: 5px;
245262 }
246263
264 +.emoji {
265 + height: 1em;
266 + width: 1em;
267 + vertical-align: top;
268 +}
247269
270 +
248271 /* -- suggest box */
249272
250273 .suggest-box > * {
251274 display: block;
252275 }
253276
254277 .suggest-box ul {
278 + padding: 0;
255279 list-style-type: none;
256280 padding-left: 0;
281 + background: #eee;
282 + border: 1px solid #eee;
283 + border-radius: 2px;
257284 }
258285
259286 .suggest-box .selected {
260- background: #eee;
287 + background: white;
261288 }
262289
263290 .suggest-box {
264291 width: max-content;
265- background: white;
292 + background: #white;
266293 border-radius: 1em;
267294 }
268295
296 +/* emoji */
297 +.suggest-box img {
298 + height: 20px;
299 + width: 20px;
300 +}
301 +
269302 /* avatar */
270303
271304 .avatar--large,
272305 .avatar--thumbnail,
@@ -281,13 +314,14 @@
281314
282315 .avatar--thumbnail {
283316 width: 2.5em;
284317 height: 2.5em;
318 + float: left;
285319 margin-right: .5ex;
286320 }
287321
288322 .avatar--fullsize {
289- width: 100%;
323 + width: 50%;
290324 }
291325
292326 .profile {
293327 padding: .5ex;
@@ -314,9 +348,9 @@
314348 margin-left: auto;
315349 margin-right: auto;
316350 border: 1px solid #eee;
317351 border-radius: .2em;
318- box-shadow: #dadada 1px 2px 8px;
352 + z-index: 2;
319353 }
320354
321355 /* searchprompt */
322356
@@ -374,9 +408,8 @@
374408
375409 .header {
376410 background: #f5f5f5;
377411 border-bottom: 1px inset;
378- box-shadow: 3px 0px 3px #ccc;
379412 flex-shrink: 0;
380413 }
381414
382415 .header__tabs {
@@ -437,12 +470,8 @@
437470 .hypertabs--selected .hypertabs__x {
438471 display: block;
439472 }
440473
441-.screen {
442- background: #f5f5f5
443-}
444-
445474 /* progress bar */
446475
447476 .hyperprogress__bar {
448477 background: darkgrey;

Built with git-ssb-web