Commit e33a98abcc85d3a3b35c0b2db5b98200b0614954
Merge branch 'master' into blob
cel committed on 12/9/2016, 11:52:43 PMParent: cc9a7d40d27d6abfd9be99ee32cc20b8df57accf
Parent: 3e23c0d59b19aeeeb752a8470c4637a82bea21d9
Files changed
basic.js | ||
---|---|---|
@@ -1,6 +1,6 @@ | ||
1 | 1 … | require('depject')( |
2 | 2 … | require('./modules_core'), |
3 | 3 … | require('./modules_basic') |
4 | -).plugs.app[0]() | |
4 … | +).app[0]() | |
5 | 5 … | |
6 | 6 … |
index.js | ||
---|---|---|
@@ -2,6 +2,6 @@ | ||
2 | 2 … | // from more specialized to more general |
3 | 3 … | require('./modules_extra'), |
4 | 4 … | require('./modules_basic'), |
5 | 5 … | require('./modules_core') |
6 | -).plugs.app[0]() | |
6 … | +).app[0]() | |
7 | 7 … |
modules_basic/about.js | ||
---|---|---|
@@ -8,33 +8,41 @@ | ||
8 | 8 … | function asLink (ln) { |
9 | 9 … | return 'string' === typeof ln ? ln : ln.link |
10 | 10 … | } |
11 | 11 … | |
12 | -var blob_url = require('../plugs').first(exports.blob_url = []) | |
12 … | +//var blob_url = require('../plugs').first(exports.blob_url = []) | |
13 | 13 … | |
14 | -exports.message_content = function (msg) { | |
15 | - if(msg.value.content.type !== 'about') return | |
14 … | +exports.needs = { | |
15 … | + blob_url: 'first' | |
16 … | +} | |
16 | 17 … | |
17 | - if(!msg.value.content.image && !msg.value.content.name) | |
18 | - return | |
18 … | +exports.gives = 'message_content' | |
19 | 19 … | |
20 | - var about = msg.value.content | |
21 | - var id = msg.value.content.about | |
22 | - return h('p', | |
23 | - about.about === msg.value.author | |
24 | - ? h('span', 'self-identifies ') | |
25 | - : h('span', 'identifies ', idLink(id)), | |
26 | - ' as ', | |
27 | - h('a', {href:"#"+about.about}, | |
28 | - about.name || null, | |
29 | - about.image | |
30 | - ? h('img.avatar--fullsize', {src: blob_url(about.image)}) | |
31 | - : null | |
20 … | +exports.create = function (api) { | |
21 … | + | |
22 … | + return function (msg) { | |
23 … | + if(msg.value.content.type !== 'about') return | |
24 … | + | |
25 … | + if(!msg.value.content.image && !msg.value.content.name) | |
26 … | + return | |
27 … | + | |
28 … | + var about = msg.value.content | |
29 … | + var id = msg.value.content.about | |
30 … | + return h('p', | |
31 … | + about.about === msg.value.author | |
32 … | + ? h('span', 'self-identifies ') | |
33 … | + : h('span', 'identifies ', idLink(id)), | |
34 … | + ' as ', | |
35 … | + h('a', {href:"#"+about.about}, | |
36 … | + about.name || null, | |
37 … | + about.image | |
38 … | + ? h('img.avatar--fullsize', {src: api.blob_url(about.image)}) | |
39 … | + : null | |
40 … | + ) | |
32 | 41 … | ) |
33 | - ) | |
34 | 42 … | |
43 … | + } | |
44 … | + | |
35 | 45 … | } |
36 | 46 … | |
37 | 47 … | |
38 | 48 … | |
39 | - | |
40 | - |
modules_basic/avatar-edit.js | ||
---|---|---|
@@ -1,4 +1,5 @@ | ||
1 … | +'use strict' | |
1 | 2 … | var dataurl = require('dataurl-') |
2 | 3 … | var hyperfile = require('hyperfile') |
3 | 4 … | var hypercrop = require('hypercrop') |
4 | 5 … | var hyperlightbox = require('hyperlightbox') |
@@ -9,13 +10,14 @@ | ||
9 | 10 … | var ref = require('ssb-ref') |
10 | 11 … | var visualize = require('visualize-buffer') |
11 | 12 … | var self_id = require('../keys').id |
12 | 13 … | |
13 | -var confirm = plugs.first(exports.message_confirm = []) | |
14 | -var sbot_blobs_add = plugs.first(exports.sbot_blobs_add = []) | |
15 | -var blob_url = plugs.first(exports.blob_url = []) | |
16 | -var sbot_links = plugs.first(exports.sbot_links = []) | |
17 | -var avatar_name = plugs.first(exports.avatar_name = []) | |
14 … | +//var confirm = plugs.first(exports.message_confirm = []) | |
15 … | +//var sbot_blobs_add = plugs.first(exports.sbot_blobs_add = []) | |
16 … | +//var blob_url = plugs.first(exports.blob_url = []) | |
17 … | +//var sbot_links = plugs.first(exports.sbot_links = []) | |
18 … | +//var avatar_name = plugs.first(exports.avatar_name = []) | |
19 … | +// | |
18 | 20 … | |
19 | 21 … | function crop (d, cb) { |
20 | 22 … | var data |
21 | 23 … | var canvas = hypercrop(h('img', {src: d})) |
@@ -33,109 +35,118 @@ | ||
33 | 35 … | ) |
34 | 36 … | ) |
35 | 37 … | } |
36 | 38 … | |
37 | -exports.avatar_edit = function (id) { | |
39 … | +exports.needs = { | |
40 … | + message_confirm: 'first', | |
41 … | + sbot_blobs_add: 'first', | |
42 … | + blob_url: 'first', | |
43 … | + sbot_links: 'first', | |
44 … | + avatar_name: 'first' | |
45 … | +} | |
38 | 46 … | |
39 | - var img = visualize(new Buffer(id.substring(1), 'base64'), 256) | |
40 | - img.classList.add('avatar--large') | |
47 … | +exports.gives = 'avatar_edit' | |
41 | 48 … | |
42 | - var lb = hyperlightbox() | |
43 | - var name_input = h('input', {placeholder: 'rename'}) | |
44 | - var name = avatar_name(id) | |
45 | - var selected = null, selected_data = null | |
49 … | +exports.create = function (api) { | |
50 … | + return function (id) { | |
46 | 51 … | |
47 | - getAvatar({links: sbot_links}, self_id, id, function (err, avatar) { | |
48 | - if (err) return console.error(err) | |
49 | - //don't show user has already selected an avatar. | |
50 | - if(selected) return | |
51 | - if(ref.isBlob(avatar.image)) | |
52 | - img.src = blob_url(avatar.image) | |
53 | - }) | |
52 … | + var img = visualize(new Buffer(id.substring(1), 'base64'), 256) | |
53 … | + img.classList.add('avatar--large') | |
54 | 54 … | |
55 | - var also_pictured = h('div.profile__alsopicturedas.wrap') | |
55 … | + var lb = hyperlightbox() | |
56 … | + var name_input = h('input', {placeholder: 'rename'}) | |
57 … | + var name = api.avatar_name(id) | |
58 … | + var selected = null, selected_data = null | |
56 | 59 … | |
57 | - pull( | |
58 | - sbot_links({dest: id, rel: 'about', values: true}), | |
59 | - pull.map(function (e) { | |
60 | - return e.value.content.image | |
61 | - }), | |
62 | - pull.filter(function (e) { | |
63 | - return e && 'string' == typeof e.link | |
64 | - }), | |
65 | - pull.unique('link'), | |
66 | - pull.drain(function (image) { | |
67 | - also_pictured.appendChild( | |
68 | - h('a', {href:'#', onclick: function (ev) { | |
69 | - ev.stopPropagation() | |
70 | - ev.preventDefault() | |
71 | - selected = image | |
72 | - img.src = blob_url(image.link || image) | |
73 | - }}, | |
74 | - h('img.avatar--thumbnail', {src: blob_url(image)}) | |
75 | - ) | |
76 | - ) | |
60 … | + getAvatar({links: api.sbot_links}, self_id, id, function (err, avatar) { | |
61 … | + if (err) return console.error(err) | |
62 … | + //don't show user has already selected an avatar. | |
63 … | + if(selected) return | |
64 … | + if(ref.isBlob(avatar.image)) | |
65 … | + img.src = api.blob_url(avatar.image) | |
77 | 66 … | }) |
78 | - ) | |
79 | 67 … | |
80 | - return h('div.row.profile', | |
81 | - lb, | |
82 | - img, | |
83 | - h('div.column.profile__info', | |
84 | - h('strong', name), | |
85 | - name_input, | |
68 … | + var also_pictured = h('div.profile__alsopicturedas.wrap') | |
86 | 69 … | |
87 | - hyperfile.asDataURL(function (data) { | |
88 | - var el = crop(data, function (err, data) { | |
89 | - if(data) { | |
90 | - img.src = data | |
91 | - var _data = dataurl.parse(data) | |
92 | - pull( | |
93 | - pull.once(_data.data), | |
94 | - sbot_blobs_add(function (err, hash) { | |
95 | - //TODO. Alerts are EVIL. | |
96 | - //I use them only in a moment of weakness. | |
70 … | + pull( | |
71 … | + api.sbot_links({dest: id, rel: 'about', values: true}), | |
72 … | + pull.map(function (e) { | |
73 … | + return e.value.content.image | |
74 … | + }), | |
75 … | + pull.filter(function (e) { | |
76 … | + return e && 'string' == typeof e.link | |
77 … | + }), | |
78 … | + pull.unique('link'), | |
79 … | + pull.drain(function (image) { | |
80 … | + also_pictured.appendChild( | |
81 … | + h('a', {href:'#', onclick: function (ev) { | |
82 … | + ev.stopPropagation() | |
83 … | + ev.preventDefault() | |
84 … | + selected = image | |
85 … | + img.src = api.blob_url(image.link || image) | |
86 … | + }}, | |
87 … | + h('img.avatar--thumbnail', {src: api.blob_url(image)}) | |
88 … | + ) | |
89 … | + ) | |
90 … | + }) | |
91 … | + ) | |
97 | 92 … | |
98 | - if(err) return alert(err.stack) | |
99 | - selected = { | |
100 | - link: hash, | |
101 | - size: _data.data.length, | |
102 | - type: _data.mimetype, | |
103 | - width: 512, | |
104 | - height: 512 | |
105 | - } | |
93 … | + return h('div.row.profile', | |
94 … | + lb, | |
95 … | + img, | |
96 … | + h('div.column.profile__info', | |
97 … | + h('strong', name), | |
98 … | + name_input, | |
106 | 99 … | |
107 | - }) | |
108 | - ) | |
109 | - } | |
110 | - lb.close() | |
111 | - }) | |
112 | - lb.show(el) | |
113 | - }), | |
114 | - h('button', 'update', {onclick: function () { | |
115 | - if(name_input.value) | |
116 | - name.textContent = name_input.value | |
100 … | + hyperfile.asDataURL(function (data) { | |
101 … | + var el = crop(data, function (err, data) { | |
102 … | + if(data) { | |
103 … | + img.src = data | |
104 … | + var _data = dataurl.parse(data) | |
105 … | + pull( | |
106 … | + pull.once(_data.data), | |
107 … | + api.sbot_blobs_add(function (err, hash) { | |
108 … | + //TODO. Alerts are EVIL. | |
109 … | + //I use them only in a moment of weakness. | |
117 | 110 … | |
118 | - if(selected) | |
119 | - confirm({ | |
120 | - type: 'about', | |
121 | - about: id, | |
122 | - name: name_input.value || undefined, | |
123 | - image: selected | |
111 … | + if(err) return alert(err.stack) | |
112 … | + selected = { | |
113 … | + link: hash, | |
114 … | + size: _data.data.length, | |
115 … | + type: _data.mimetype, | |
116 … | + width: 512, | |
117 … | + height: 512 | |
118 … | + } | |
119 … | + | |
120 … | + }) | |
121 … | + ) | |
122 … | + } | |
123 … | + lb.close() | |
124 | 124 … | }) |
125 | - else if(name_input.value) //name only | |
126 | - confirm({ | |
127 | - type: 'about', | |
128 | - about: id, | |
129 | - name: name_input.value || undefined, | |
130 | - }) | |
131 | - else | |
132 | - //another moment of weakness | |
133 | - alert('must select a name or image') | |
134 | - }}), | |
135 | - also_pictured | |
125 … | + lb.show(el) | |
126 … | + }), | |
127 … | + h('button', 'update', {onclick: function () { | |
128 … | + if(name_input.value) | |
129 … | + name.textContent = name_input.value | |
130 … | + | |
131 … | + if(selected) | |
132 … | + api.message_confirm({ | |
133 … | + type: 'about', | |
134 … | + about: id, | |
135 … | + name: name_input.value || undefined, | |
136 … | + image: selected | |
137 … | + }) | |
138 … | + else if(name_input.value) //name only | |
139 … | + confirm({ | |
140 … | + type: 'about', | |
141 … | + about: id, | |
142 … | + name: name_input.value || undefined, | |
143 … | + }) | |
144 … | + else | |
145 … | + //another moment of weakness | |
146 … | + alert('must select a name or image') | |
147 … | + }}), | |
148 … | + also_pictured | |
149 … | + ) | |
136 | 150 … | ) |
137 | - ) | |
151 … | + } | |
138 | 152 … | } |
139 | - | |
140 | - | |
141 | - |
modules_basic/avatar-image.js | ||
---|---|---|
@@ -1,108 +1,110 @@ | ||
1 | - | |
1 … | +'use strict' | |
2 | 2 … | var getAvatar = require('ssb-avatar') |
3 | 3 … | var h = require('hyperscript') |
4 | 4 … | var ref = require('ssb-ref') |
5 | 5 … | var path = require('path') |
6 | 6 … | var visualize = require('visualize-buffer') |
7 | 7 … | |
8 | -var plugs = require('../plugs') | |
9 | -var sbot_query = plugs.first(exports.sbot_query = []) | |
10 | -var blob_url = require('../plugs').first(exports.blob_url = []) | |
11 | - | |
12 | 8 … | var pull = require('pull-stream') |
13 | 9 … | |
14 | -var id = require('../keys').id | |
10 … | +var self_id = require('../keys').id | |
15 | 11 … | |
16 | -var avatars = AVATARS = {} | |
12 … | +//var plugs = require('../plugs') | |
13 … | +//var sbot_query = plugs.first(exports.sbot_query = []) | |
14 … | +//var blob_url = require('../plugs').first(exports.blob_url = []) | |
15 … | +// | |
17 | 16 … | |
17 … | +exports.needs = { | |
18 … | + sbot_query: 'first', | |
19 … | + blob_url: 'first' | |
20 … | +} | |
21 … | + | |
22 … | +exports.gives = { | |
23 … | + connection_status: true, avatar_image: true | |
24 … | +} | |
25 … | + | |
26 … | + | |
18 | 27 … | function isFunction (f) { |
19 | 28 … | return 'function' === typeof f |
20 | 29 … | } |
21 | 30 … | |
22 | -var self_id = require('../keys').id | |
23 | 31 … | |
24 | 32 … | var ready = false |
25 | 33 … | var waiting = [] |
26 | 34 … | |
27 | 35 … | var last = 0 |
28 | 36 … | |
29 | -//blah blah | |
30 | -exports.connection_status = function (err) { | |
31 | - if (err) return | |
32 | -pull( | |
33 | - sbot_query({ | |
34 | - query: [{ | |
35 | - $filter: { | |
36 | - timestamp: {$gt: last || 0 }, | |
37 | - value: { content: { | |
38 | - type: "about", | |
39 | - about: {$prefix: "@"}, | |
40 | - image: {link: {$prefix: "&"}} | |
41 | - }} | |
42 | - }}, | |
43 | - { | |
44 | - $map: { | |
45 | - id: ["value", "content", "about"], | |
46 | - image: ["value", "content", "image", "link"], | |
47 | - by: ["value", "author"], | |
48 | - ts: 'timestamp' | |
49 | - }}], | |
50 | - live: true | |
51 | - }), | |
52 | - pull.drain(function (a) { | |
53 | - if(a.sync) { | |
54 | - ready = true | |
55 | - while(waiting.length) waiting.shift()() | |
56 | - return | |
57 | - } | |
58 | - last = a.ts | |
59 | - //set image for avatar. | |
60 | - //overwrite another avatar | |
61 | - //you picked. | |
62 | - if( | |
63 | - //if there is no avatar | |
64 | - (!avatars[a.id]) || | |
65 | - //if i chose this avatar | |
66 | - (a.by == self_id) || | |
67 | - //they chose their own avatar, | |
68 | - //and current avatar was not chosen by me | |
69 | - (a.by === a.id && avatars[a.id].by != self_id) | |
70 | - ) | |
71 | - avatars[a.id] = a | |
37 … | +exports.create = function (api) { | |
38 … | + var avatars = {} | |
72 | 39 … | |
73 | - }) | |
74 | -) | |
75 | -} | |
40 … | + //blah blah | |
41 … | + return { | |
42 … | + connection_status: function (err) { | |
43 … | + if (err) return | |
44 … | + pull( | |
45 … | + api.sbot_query({ | |
46 … | + query: [{ | |
47 … | + $filter: { | |
48 … | + timestamp: {$gt: last || 0 }, | |
49 … | + value: { content: { | |
50 … | + type: "about", | |
51 … | + about: {$prefix: "@"}, | |
52 … | + image: {link: {$prefix: "&"}} | |
53 … | + }} | |
54 … | + }}, | |
55 … | + { | |
56 … | + $map: { | |
57 … | + id: ["value", "content", "about"], | |
58 … | + image: ["value", "content", "image", "link"], | |
59 … | + by: ["value", "author"], | |
60 … | + ts: 'timestamp' | |
61 … | + }}], | |
62 … | + live: true | |
63 … | + }), | |
64 … | + pull.drain(function (a) { | |
65 … | + if(a.sync) { | |
66 … | + ready = true | |
67 … | + while(waiting.length) waiting.shift()() | |
68 … | + return | |
69 … | + } | |
70 … | + last = a.ts | |
71 … | + //set image for avatar. | |
72 … | + //overwrite another avatar | |
73 … | + //you picked. | |
74 … | + if( | |
75 … | + //if there is no avatar | |
76 … | + (!avatars[a.id]) || | |
77 … | + //if i chose this avatar | |
78 … | + (a.by == self_id) || | |
79 … | + //they chose their own avatar, | |
80 … | + //and current avatar was not chosen by me | |
81 … | + (a.by === a.id && avatars[a.id].by != self_id) | |
82 … | + ) | |
83 … | + avatars[a.id] = a | |
76 | 84 … | |
77 | -exports.avatar_image = function (author, classes) { | |
78 | - classes = classes || '' | |
79 | - if(classes && 'string' === typeof classes) classes = '.avatar--'+classes | |
85 … | + }) | |
86 … | + ) | |
87 … | + }, | |
80 | 88 … | |
81 | - var img = visualize(new Buffer(author.substring(1), 'base64'), 256) | |
82 | - ;(classes || '').split('.').filter(Boolean).forEach(function (c) { | |
83 | - img.classList.add(c) | |
84 | - }) | |
89 … | + avatar_image: function (author, classes) { | |
90 … | + classes = classes || '' | |
91 … | + if(classes && 'string' === typeof classes) classes = '.avatar--'+classes | |
85 | 92 … | |
86 | - function go () { | |
87 | - if(avatars[author]) img.src = blob_url(avatars[author].image) | |
88 | - } | |
93 … | + var img = visualize(new Buffer(author.substring(1), 'base64'), 256) | |
94 … | + ;(classes || '').split('.').filter(Boolean).forEach(function (c) { | |
95 … | + img.classList.add(c) | |
96 … | + }) | |
89 | 97 … | |
90 | - if(!ready) | |
91 | - waiting.push(go) | |
92 | - else go() | |
98 … | + function go () { | |
99 … | + if(avatars[author]) img.src = api.blob_url(avatars[author].image) | |
100 … | + } | |
93 | 101 … | |
94 | - return img | |
102 … | + if(!ready) | |
103 … | + waiting.push(go) | |
104 … | + else go() | |
105 … | + | |
106 … | + return img | |
107 … | + } | |
108 … | + } | |
95 | 109 … | } |
96 | 110 … | |
97 | - | |
98 | - | |
99 | - | |
100 | - | |
101 | - | |
102 | - | |
103 | - | |
104 | - | |
105 | - | |
106 | - | |
107 | - | |
108 | - |
modules_basic/avatar-link.js | ||
---|---|---|
@@ -1,18 +1,22 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | -var plugs = require('../plugs') | |
3 | -var avatar_name = plugs.first(exports.avatar_name = []) | |
4 | 2 … | |
5 | -var signifier = require('../plugs').first(exports.signifier = []) | |
3 … | +exports.needs = {signifier: 'first'} | |
6 | 4 … | |
7 | -exports.avatar_link = function (id, element) { | |
5 … | +exports.gives = 'avatar_link' | |
8 | 6 … | |
9 | - var link = h('a.avatar', {href: "#"+id, title: id}, element) | |
7 … | +exports.create = function (api) { | |
8 … | + return function (id, element) { | |
10 | 9 … | |
11 | - signifier(id, function (_, names) { | |
12 | - if(names.length) | |
13 | - link.title = names[0].name + '\n '+id | |
14 | - }) | |
10 … | + var link = h('a.avatar', {href: "#"+id, title: id}, element) | |
15 | 11 … | |
16 | - return link | |
12 … | + api.signifier(id, function (_, names) { | |
13 … | + if(names.length) | |
14 … | + link.title = names[0].name + '\n '+id | |
15 … | + }) | |
16 … | + | |
17 … | + return link | |
18 … | + } | |
17 | 19 … | } |
18 | 20 … | |
21 … | + | |
22 … | + |
modules_basic/avatar-name.js | ||
---|---|---|
@@ -1,22 +1,29 @@ | ||
1 | 1 … | |
2 | 2 … | var signifier = require('../plugs').first(exports.signifier = []) |
3 | 3 … | var h = require('hyperscript') |
4 | 4 … | |
5 | -exports.avatar_name = | |
6 | -function name (id) { | |
7 | - var n = h('span', id.substring(0, 10)) | |
5 … | +exports.needs = { signifier: 'first' } | |
8 | 6 … | |
9 | - //choose the most popular name for this person. | |
10 | - //for anything like this you'll see I have used sbot.links2 | |
11 | - //which is the ssb-links plugin. as you'll see the query interface | |
12 | - //is pretty powerful! | |
13 | - //TODO: "most popular" name is easily gameable. | |
14 | - //must come up with something better than this. | |
7 … | +exports.gives = 'avatar_name' | |
15 | 8 … | |
16 | - signifier(id, function (_, names) { | |
17 | - if(names.length) n.textContent = names[0].name | |
18 | - }) | |
9 … | +exports.create = function (api) { | |
19 | 10 … | |
20 | - return n | |
11 … | + return function name (id) { | |
12 … | + var n = h('span', id.substring(0, 10)) | |
13 … | + | |
14 … | + //choose the most popular name for this person. | |
15 … | + //for anything like this you'll see I have used sbot.links2 | |
16 … | + //which is the ssb-links plugin. as you'll see the query interface | |
17 … | + //is pretty powerful! | |
18 … | + //TODO: "most popular" name is easily gameable. | |
19 … | + //must come up with something better than this. | |
20 … | + | |
21 … | + api.signifier(id, function (_, names) { | |
22 … | + if(names.length) n.textContent = names[0].name | |
23 … | + }) | |
24 … | + | |
25 … | + return n | |
26 … | + } | |
27 … | + | |
21 | 28 … | } |
22 | 29 … |
modules_basic/avatar-profile.js | ||
---|---|---|
@@ -1,15 +1,25 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | -var plugs = require('../plugs') | |
3 | 2 … | var pull = require('pull-stream') |
4 | 3 … | |
5 | -var avatar_image_link = plugs.first(exports.avatar_image_link = []) | |
6 | -var avatar_action = plugs.map(exports.avatar_action = []) | |
7 | -var avatar_edit = plugs.first(exports.avatar_edit = []) | |
4 … | +//var plugs = require('../plugs') | |
5 … | +//var avatar_image_link = plugs.first(exports.avatar_image_link = []) | |
6 … | +//var avatar_action = plugs.map(exports.avatar_action = []) | |
7 … | +//var avatar_edit = plugs.first(exports.avatar_edit = []) | |
8 | 8 … | |
9 | -var follows = plugs.first(exports.follows = []) | |
10 | -var followers = plugs.first(exports.followers = []) | |
9 … | +//var follows = plugs.first(exports.follows = []) | |
10 … | +//var followers = plugs.first(exports.followers = []) | |
11 … | +// | |
12 … | +exports.needs = { | |
13 … | + avatar_image_link: 'first', | |
14 … | + avatar_action: 'map', | |
15 … | + avatar_edit: 'first', | |
16 … | + follows: 'first', | |
17 … | + followers: 'first' | |
18 … | +} | |
11 | 19 … | |
20 … | +exports.gives = 'avatar_profile' | |
21 … | + | |
12 | 22 … | function streamToList(stream, el) { |
13 | 23 … | pull( |
14 | 24 … | stream, |
15 | 25 … | pull.drain(function (item) { |
@@ -18,57 +28,61 @@ | ||
18 | 28 … | ) |
19 | 29 … | return el |
20 | 30 … | } |
21 | 31 … | |
22 | -function image_link (id) { | |
23 | - return avatar_image_link(id, 'thumbnail') | |
24 | -} | |
32 … | +exports.create = function (api) { | |
25 | 33 … | |
26 | -exports.avatar_profile = function (id) { | |
34 … | + function image_link (id) { | |
35 … | + return api.avatar_image_link(id, 'thumbnail') | |
36 … | + } | |
27 | 37 … | |
28 | - var follows_el = h('div.profile__follows.wrap') | |
29 | - var friends_el = h('div.profile__friendss.wrap') | |
30 | - var followers_el = h('div.profile__followers.wrap') | |
31 | - var a, b | |
38 … | + return function (id) { | |
32 | 39 … | |
33 | - pull(follows(id), pull.unique(), pull.collect(function (err, ary) { | |
34 | - a = ary || []; next() | |
35 | - })) | |
36 | - pull(followers(id), pull.unique(), pull.collect(function (err, ary) { | |
37 | - b = ary || {}; next() | |
38 | - })) | |
40 … | + var follows_el = h('div.profile__follows.wrap') | |
41 … | + var friends_el = h('div.profile__friendss.wrap') | |
42 … | + var followers_el = h('div.profile__followers.wrap') | |
43 … | + var a, b | |
39 | 44 … | |
40 | - function next () { | |
41 | - if(!(a && b)) return | |
42 | - var _c = [], _a = [], _b = [] | |
45 … | + pull(api.follows(id), pull.unique(), pull.collect(function (err, ary) { | |
46 … | + a = ary || []; next() | |
47 … | + })) | |
48 … | + pull(api.followers(id), pull.unique(), pull.collect(function (err, ary) { | |
49 … | + b = ary || {}; next() | |
50 … | + })) | |
43 | 51 … | |
44 | - a.forEach(function (id) { | |
45 | - if(!~b.indexOf(id)) _a.push(id) | |
46 | - else _c.push(id) | |
47 | - }) | |
48 | - b.forEach(function (id) { | |
49 | - if(!~_c.indexOf(id)) _b.push(id) | |
50 | - }) | |
51 | - function add (ary, el) { | |
52 | - ary.forEach(function (id) { el.appendChild(image_link(id)) }) | |
52 … | + function next () { | |
53 … | + if(!(a && b)) return | |
54 … | + var _c = [], _a = [], _b = [] | |
55 … | + | |
56 … | + a.forEach(function (id) { | |
57 … | + if(!~b.indexOf(id)) _a.push(id) | |
58 … | + else _c.push(id) | |
59 … | + }) | |
60 … | + b.forEach(function (id) { | |
61 … | + if(!~_c.indexOf(id)) _b.push(id) | |
62 … | + }) | |
63 … | + function add (ary, el) { | |
64 … | + ary.forEach(function (id) { el.appendChild(image_link(id)) }) | |
65 … | + } | |
66 … | + | |
67 … | + add(_a, follows_el) | |
68 … | + add(_c, friends_el) | |
69 … | + add(_b, followers_el) | |
53 | 70 … | } |
54 | 71 … | |
55 | - add(_a, follows_el) | |
56 | - add(_c, friends_el) | |
57 | - add(_b, followers_el) | |
72 … | + | |
73 … | + return h('div.column.profile', | |
74 … | + api.avatar_edit(id), | |
75 … | + api.avatar_action(id), | |
76 … | + h('div.profile__relationships.column', | |
77 … | + h('strong', 'follows'), | |
78 … | + follows_el, | |
79 … | + h('strong', 'friends'), | |
80 … | + friends_el, | |
81 … | + h('strong', 'followers'), | |
82 … | + followers_el | |
83 … | + ) | |
84 … | + ) | |
58 | 85 … | } |
59 | 86 … | |
60 | - | |
61 | - return h('div.column.profile', | |
62 | - avatar_edit(id), | |
63 | - avatar_action(id), | |
64 | - h('div.profile__relationships.column', | |
65 | - h('strong', 'follows'), | |
66 | - follows_el, | |
67 | - h('strong', 'friends'), | |
68 | - friends_el, | |
69 | - h('strong', 'followers'), | |
70 | - followers_el | |
71 | - ) | |
72 | - ) | |
73 | 87 … | } |
74 | 88 … |
modules_basic/avatar.js | ||
---|---|---|
@@ -1,23 +1,37 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | -var plugs = require('../plugs') | |
4 | 3 … | |
5 | -var avatar_name = plugs.first(exports.avatar_name = []) | |
6 | -var avatar_image = plugs.first(exports.avatar_image = []) | |
7 | -var avatar_link = plugs.first(exports.avatar_link = []) | |
8 | - | |
9 | -exports.avatar = function (author, classes) { | |
10 | - return exports.avatar_image_name_link(author, classes) | |
4 … | +exports.needs = { | |
5 … | + avatar_name: 'first', | |
6 … | + avatar_image: 'first', | |
7 … | + avatar_link: 'first' | |
11 | 8 … | } |
12 | 9 … | |
13 | -exports.avatar_image_name_link = function (author, classes) { | |
14 | - return avatar_link(author, [ | |
15 | - avatar_image(author, classes), | |
16 | - avatar_name(author) | |
17 | - ]) | |
10 … | +exports.gives = { | |
11 … | + avatar: true, | |
12 … | + avatar_image_name_link: true, | |
13 … | + avatar_image_link: true | |
18 | 14 … | } |
19 | 15 … | |
20 | -exports.avatar_image_link = function (author, classes) { | |
21 | - return avatar_link(author, avatar_image(author, classes)) | |
16 … | +exports.create = function (api) { | |
17 … | + | |
18 … | + var exports = {} | |
19 … | + exports.avatar = function (author, classes) { | |
20 … | + return exports.avatar_image_name_link(author, classes) | |
21 … | + } | |
22 … | + | |
23 … | + exports.avatar_image_name_link = function (author, classes) { | |
24 … | + return api.avatar_link(author, [ | |
25 … | + api.avatar_image(author, classes), | |
26 … | + api.avatar_name(author) | |
27 … | + ]) | |
28 … | + } | |
29 … | + | |
30 … | + exports.avatar_image_link = function (author, classes) { | |
31 … | + return api.avatar_link(author, api.avatar_image(author, classes)) | |
32 … | + } | |
33 … | + | |
34 … | + return exports | |
22 | 35 … | } |
23 | 36 … | |
37 … | + |
modules_basic/compose.js | ||
---|---|---|
@@ -3,17 +3,27 @@ | ||
3 | 3 … | var u = require('../util') |
4 | 4 … | var suggest = require('suggest-box') |
5 | 5 … | var mentions = require('ssb-mentions') |
6 | 6 … | var lightbox = require('hyperlightbox') |
7 … | +var cont = require('cont') | |
7 | 8 … | |
8 | -var plugs = require('../plugs') | |
9 … | +//var plugs = require('../plugs') | |
10 … | +//var suggest_mentions= plugs.asyncConcat(exports.suggest_mentions = []) | |
11 … | +//var publish = plugs.first(exports.sbot_publish = []) | |
12 … | +//var message_content = plugs.first(exports.message_content = []) | |
13 … | +//var message_confirm = plugs.first(exports.message_confirm = []) | |
14 … | +//var file_input = plugs.first(exports.file_input = []) | |
9 | 15 … | |
10 | -var suggest_mentions= plugs.asyncConcat(exports.suggest_mentions = []) | |
11 | -var publish = plugs.first(exports.sbot_publish = []) | |
12 | -var message_content = plugs.first(exports.message_content = []) | |
13 | -var message_confirm = plugs.first(exports.message_confirm = []) | |
14 | -var file_input = plugs.first(exports.file_input = []) | |
16 … | +exports.needs = { | |
17 … | + suggest_mentions: 'map', //<-- THIS MUST BE REWRITTEN | |
18 … | + publish: 'first', | |
19 … | + message_content: 'first', | |
20 … | + message_confirm: 'first', | |
21 … | + file_input: 'first' | |
22 … | +} | |
15 | 23 … | |
24 … | +exports.gives = 'message_compose' | |
25 … | + | |
16 | 26 … | function id (e) { return e } |
17 | 27 … | |
18 | 28 … | /* |
19 | 29 … | opts can take |
@@ -22,111 +32,124 @@ | ||
22 | 32 … | prepublish: function. called before publishing a message. |
23 | 33 … | shrink: boolean. set to false, to make composer not shrink (or hide controls) when unfocused. |
24 | 34 … | */ |
25 | 35 … | |
26 | -exports.message_compose = function (meta, opts, cb) { | |
27 | - if('function' === typeof cb) { | |
28 | - if('function' === typeof opts) | |
29 | - opts = {prepublish: opts} | |
30 | - } | |
36 … | +exports.create = function (api) { | |
31 | 37 … | |
32 | - if(!opts) opts = {} | |
33 | - opts.prepublish = opts.prepublish || id | |
38 … | + return function (meta, opts, cb) { | |
39 … | + if('function' === typeof cb) { | |
40 … | + if('function' === typeof opts) | |
41 … | + opts = {prepublish: opts} | |
42 … | + } | |
34 | 43 … | |
35 | - var accessories | |
36 | - meta = meta || {} | |
37 | - if(!meta.type) throw new Error('message must have type') | |
38 | - var ta = h('textarea', { | |
39 | - placeholder: opts.placeholder || 'Write a message', | |
40 | - style: {height: opts.shrink === false ? '200px' : ''} | |
41 | - }) | |
44 … | + if(!opts) opts = {} | |
45 … | + opts.prepublish = opts.prepublish || id | |
42 | 46 … | |
43 | - if(opts.shrink !== false) { | |
44 | - var blur | |
45 | - ta.addEventListener('focus', function () { | |
46 | - clearTimeout(blur) | |
47 | - if(!ta.value) { | |
48 | - ta.style.height = '200px' | |
49 | - } | |
50 | - accessories.style.display = 'block' | |
47 … | + var accessories | |
48 … | + meta = meta || {} | |
49 … | + if(!meta.type) throw new Error('message must have type') | |
50 … | + var ta = h('textarea', { | |
51 … | + placeholder: opts.placeholder || 'Write a message', | |
52 … | + style: {height: opts.shrink === false ? '200px' : ''} | |
51 | 53 … | }) |
52 | - ta.addEventListener('blur', function () { | |
53 | - //don't shrink right away, so there is time | |
54 | - //to click the publish button. | |
55 | - clearTimeout(blur) | |
56 | - blur = setTimeout(function () { | |
57 | - if(ta.value) return | |
58 | - ta.style.height = '50px' | |
59 | - accessories.style.display = 'none' | |
60 | - }, 200) | |
54 … | + | |
55 … | + if(opts.shrink !== false) { | |
56 … | + var blur | |
57 … | + ta.addEventListener('focus', function () { | |
58 … | + clearTimeout(blur) | |
59 … | + if(!ta.value) { | |
60 … | + ta.style.height = '200px' | |
61 … | + } | |
62 … | + accessories.style.display = 'block' | |
63 … | + }) | |
64 … | + ta.addEventListener('blur', function () { | |
65 … | + //don't shrink right away, so there is time | |
66 … | + //to click the publish button. | |
67 … | + clearTimeout(blur) | |
68 … | + blur = setTimeout(function () { | |
69 … | + if(ta.value) return | |
70 … | + ta.style.height = '50px' | |
71 … | + accessories.style.display = 'none' | |
72 … | + }, 200) | |
73 … | + }) | |
74 … | + } | |
75 … | + | |
76 … | + ta.addEventListener('keydown', function (ev) { | |
77 … | + if(ev.keyCode === 13 && ev.ctrlKey) publish() | |
61 | 78 … | }) |
62 | - } | |
63 | 79 … | |
64 | - ta.addEventListener('keydown', function (ev) { | |
65 | - if(ev.keyCode === 13 && ev.ctrlKey) publish() | |
66 | - }) | |
80 … | + var files = [] | |
81 … | + var filesById = {} | |
67 | 82 … | |
68 | - var files = [] | |
69 | - var filesById = {} | |
70 | - | |
71 | - function publish() { | |
72 | - publishBtn.disabled = true | |
73 | - var content | |
74 | - try { | |
75 | - content = JSON.parse(ta.value) | |
76 | - } catch (err) { | |
77 | - meta.text = ta.value | |
78 | - meta.mentions = mentions(ta.value).map(function (mention) { | |
79 | - // merge markdown-detected mention with file info | |
80 | - var file = filesById[mention.link] | |
81 | - if (file) { | |
82 | - if (file.type) mention.type = file.type | |
83 | - if (file.size) mention.size = file.size | |
84 | - } | |
85 | - return mention | |
86 | - }) | |
83 … | + function publish() { | |
84 … | + publishBtn.disabled = true | |
85 … | + var content | |
87 | 86 … | try { |
88 | - meta = opts.prepublish(meta) | |
87 … | + content = JSON.parse(ta.value) | |
89 | 88 … | } catch (err) { |
90 | - publishBtn.disabled = false | |
91 | - if (cb) cb(err) | |
92 | - else alert(err.message) | |
89 … | + meta.text = ta.value | |
90 … | + meta.mentions = mentions(ta.value).map(function (mention) { | |
91 … | + // merge markdown-detected mention with file info | |
92 … | + var file = filesById[mention.link] | |
93 … | + if (file) { | |
94 … | + if (file.type) mention.type = file.type | |
95 … | + if (file.size) mention.size = file.size | |
96 … | + } | |
97 … | + return mention | |
98 … | + }) | |
99 … | + try { | |
100 … | + meta = opts.prepublish(meta) | |
101 … | + } catch (err) { | |
102 … | + publishBtn.disabled = false | |
103 … | + if (cb) cb(err) | |
104 … | + else alert(err.message) | |
105 … | + } | |
106 … | + return api.message_confirm(meta, done) | |
93 | 107 … | } |
94 | - return message_confirm(meta, done) | |
95 | - } | |
96 | - message_confirm(content, done) | |
97 | 108 … | |
98 | - function done (err, msg) { | |
99 | - publishBtn.disabled = false | |
100 | - if(err) return alert(err.stack) | |
101 | - else if (msg) ta.value = '' | |
109 … | + api.message_confirm(content, done) | |
102 | 110 … | |
103 | - if (cb) cb(err, msg) | |
111 … | + function done (err, msg) { | |
112 … | + publishBtn.disabled = false | |
113 … | + if(err) return alert(err.stack) | |
114 … | + else if (msg) ta.value = '' | |
115 … | + | |
116 … | + if (cb) cb(err, msg) | |
117 … | + } | |
104 | 118 … | } |
105 | - } | |
106 | 119 … | |
107 | 120 … | |
108 | - var publishBtn = h('button', 'Publish', {onclick: publish}) | |
109 | - var composer = | |
110 | - h('div.compose', h('div.column', ta, | |
111 | - accessories = h('div.row.compose__controls', | |
112 | - //hidden until you focus the textarea | |
113 | - {style: {display: opts.shrink === false ? '' : 'none'}}, | |
114 | - file_input(function (file) { | |
115 | - files.push(file) | |
116 | - filesById[file.link] = file | |
121 … | + var publishBtn = h('button', 'Publish', {onclick: publish}) | |
122 … | + var composer = | |
123 … | + h('div.compose', h('div.column', ta, | |
124 … | + accessories = h('div.row.compose__controls', | |
125 … | + //hidden until you focus the textarea | |
126 … | + {style: {display: opts.shrink === false ? '' : 'none'}}, | |
127 … | + api.file_input(function (file) { | |
128 … | + files.push(file) | |
129 … | + filesById[file.link] = file | |
117 | 130 … | |
118 | - var embed = file.type.indexOf('image/') === 0 ? '!' : '' | |
119 | - ta.value += embed + '['+file.name+']('+file.link+')' | |
120 | - console.log('added:', file) | |
121 | - }), | |
122 | - publishBtn) | |
131 … | + var embed = file.type.indexOf('image/') === 0 ? '!' : '' | |
132 … | + ta.value += embed + '['+file.name+']('+file.link+')' | |
133 … | + console.log('added:', file) | |
134 … | + }), | |
135 … | + publishBtn) | |
136 … | + ) | |
123 | 137 … | ) |
124 | - ) | |
125 | 138 … | |
126 | - suggest(ta, suggest_mentions, {}) | |
139 … | + suggest(ta, function (name, cb) { | |
140 … | + cont.para(api.suggest_mentions(name)) | |
141 … | + (function (err, ary) { | |
142 … | + cb(null, ary.reduce(function (a, b) { | |
143 … | + if(!b) return a | |
144 … | + return a.concat(b) | |
145 … | + }, [])) | |
146 … | + }) | |
147 … | + }, {}) | |
127 | 148 … | |
128 | - return composer | |
149 … | + return composer | |
129 | 150 … | |
151 … | + } | |
152 … | + | |
130 | 153 … | } |
131 | 154 … | |
132 | 155 … |
modules_basic/feed.js | ||
---|---|---|
@@ -3,54 +3,64 @@ | ||
3 | 3 … | var h = require('hyperscript') |
4 | 4 … | var pull = require('pull-stream') |
5 | 5 … | var u = require('../util') |
6 | 6 … | |
7 | -var plugs = require('../plugs') | |
8 | -var sbot_user_feed = plugs.first(exports.sbot_user_feed = []) | |
9 | -var message_render = plugs.first(exports.message_render = []) | |
10 | -var avatar_profile = plugs.first(exports.avatar_profile = []) | |
11 | -var signifier = plugs.first(exports.signifier = []) | |
7 … | +//var plugs = require('../plugs') | |
8 … | +//var sbot_user_feed = plugs.first(exports.sbot_user_feed = []) | |
9 … | +//var message_render = plugs.first(exports.message_render = []) | |
10 … | +//var avatar_profile = plugs.first(exports.avatar_profile = []) | |
11 … | +//var signifier = plugs.first(exports.signifier = []) | |
12 | 12 … | |
13 | -exports.screen_view = function (id) { | |
14 | - //TODO: header of user info, avatars, names, follows. | |
13 … | +exports.needs = { | |
14 … | + sbot_user_feed: 'first', | |
15 … | + message_render: 'first', | |
16 … | + avatar_profile: 'first', | |
17 … | + signifier: 'first' | |
18 … | +} | |
15 | 19 … | |
16 | - if(ref.isFeed(id)) { | |
20 … | +exports.gives = 'screen_view' | |
17 | 21 … | |
18 | - var content = h('div.column.scroller__content') | |
19 | - var div = h('div.column.scroller', | |
20 | - {style: {'overflow':'auto'}}, | |
21 | - h('div.scroller__wrapper', | |
22 | - h('div', avatar_profile(id)), | |
23 | - content | |
24 | - ) | |
25 | - ) | |
26 | 22 … | |
27 | - signifier(id, function (_, names) { | |
28 | - if(names.length) div.title = names[0].name | |
29 | - }) | |
23 … | +exports.create = function (api) { | |
30 | 24 … | |
25 … | + return function (id) { | |
26 … | + //TODO: header of user info, avatars, names, follows. | |
31 | 27 … | |
32 | - pull( | |
33 | - sbot_user_feed({id: id, old: false, live: true}), | |
34 | - Scroller(div, content, message_render, true, false) | |
35 | - ) | |
28 … | + if(ref.isFeed(id)) { | |
36 | 29 … | |
37 | - //how to handle when have scrolled past the start??? | |
30 … | + var content = h('div.column.scroller__content') | |
31 … | + var div = h('div.column.scroller', | |
32 … | + {style: {'overflow':'auto'}}, | |
33 … | + h('div.scroller__wrapper', | |
34 … | + h('div', api.avatar_profile(id)), | |
35 … | + content | |
36 … | + ) | |
37 … | + ) | |
38 | 38 … | |
39 | - pull( | |
40 | - u.next(sbot_user_feed, { | |
41 | - id: id, reverse: true, | |
42 | - limit: 50, live: false | |
43 | - }, ['value', 'sequence']), | |
44 | - Scroller(div, content, message_render, false, false) | |
45 | - ) | |
39 … | + api.signifier(id, function (_, names) { | |
40 … | + if(names.length) div.title = names[0].name | |
41 … | + }) | |
46 | 42 … | |
47 | - return div | |
48 | 43 … | |
49 | - } | |
50 | -} | |
44 … | + pull( | |
45 … | + api.sbot_user_feed({id: id, old: false, live: true}), | |
46 … | + Scroller(div, content, api.message_render, true, false) | |
47 … | + ) | |
51 | 48 … | |
49 … | + //how to handle when have scrolled past the start??? | |
52 | 50 … | |
51 … | + pull( | |
52 … | + u.next(api.sbot_user_feed, { | |
53 … | + id: id, reverse: true, | |
54 … | + limit: 50, live: false | |
55 … | + }, ['value', 'sequence']), | |
56 … | + pull.through(console.log.bind(console)), | |
57 … | + Scroller(div, content, api.message_render, false, false) | |
58 … | + ) | |
53 | 59 … | |
60 … | + return div | |
54 | 61 … | |
62 … | + } | |
63 … | + } | |
55 | 64 … | |
65 … | +} | |
56 | 66 … |
modules_basic/follow.js | ||
---|---|---|
@@ -1,86 +1,99 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | -var plugs = require('../plugs') | |
4 | -var avatar = plugs.first(exports.avatar = []) | |
5 | -var avatar_name = plugs.first(exports.avatar_name = []) | |
6 | -var avatar_link = plugs.first(exports.avatar_link = []) | |
7 | 3 … | var pull = require('pull-stream') |
8 | -var plugs = require('../plugs') | |
9 | 4 … | |
5 … | +//var plugs = require('../plugs') | |
6 … | +//var avatar = plugs.first(exports.avatar = []) | |
7 … | +//var avatar_name = plugs.first(exports.avatar_name = []) | |
8 … | +//var avatar_link = plugs.first(exports.avatar_link = []) | |
9 … | +//var message_confirm = plugs.first(exports.message_confirm = []) | |
10 … | +//var follower_of = plugs.first(exports.follower_of = []) | |
11 … | + | |
10 | 12 … | //render a message when someone follows someone, |
11 | 13 … | //so you see new users |
12 | 14 … | function isRelated(value, name) { |
13 | 15 … | return value ? name : value === false ? 'un'+name : '' |
14 | 16 … | } |
15 | 17 … | |
16 | -exports.message_content = | |
17 | -exports.message_content_mini = function (msg) { | |
18 | - var content = msg.value.content | |
19 | - if(content.type == 'contact' && content.contact) { | |
20 | - var relation = isRelated(content.following, 'follows') | |
21 | - if(content.blocking) relation = 'blocks' | |
22 | - return [ | |
23 | - relation, ' ', | |
24 | - avatar_link(content.contact, avatar_name(content.contact), '') | |
25 | - ] | |
26 | - } | |
18 … | +exports.needs = { | |
19 … | + avatar: 'first', | |
20 … | + avatar_name: 'first', | |
21 … | + avatar_link: 'first', | |
22 … | + message_confirm: 'first', | |
23 … | + follower_of: 'first' | |
27 | 24 … | } |
28 | 25 … | |
29 | -exports.message_content = function (msg) { | |
26 … | +exports.gives = { | |
27 … | + message_content: true, | |
28 … | + message_content_mini: true, | |
29 … | + avatar_action: true, | |
30 … | +} | |
30 | 31 … | |
31 | - var content = msg.value.content | |
32 | - if(content.type == 'contact' && content.contact) { | |
33 | - var relation = isRelated(content.following, 'follows') | |
34 | - if(content.blocking) relation = 'blocks' | |
35 | - return h('div.contact', relation, avatar(msg.value.content.contact, 'thumbnail')) | |
32 … | +exports.create = function (api) { | |
33 … | + var exports = {} | |
34 … | + exports.message_content = | |
35 … | + exports.message_content_mini = function (msg) { | |
36 … | + var content = msg.value.content | |
37 … | + if(content.type == 'contact' && content.contact) { | |
38 … | + var relation = isRelated(content.following, 'follows') | |
39 … | + if(content.blocking) relation = 'blocks' | |
40 … | + return [ | |
41 … | + relation, ' ', | |
42 … | + api.avatar_link(content.contact, api.avatar_name(content.contact), '') | |
43 … | + ] | |
44 … | + } | |
36 | 45 … | } |
37 | -} | |
38 | 46 … | |
39 | -var message_confirm = plugs.first(exports.message_confirm = []) | |
40 | -var follower_of = plugs.first(exports.follower_of = []) | |
47 … | + exports.message_content = function (msg) { | |
41 | 48 … | |
42 | -exports.avatar_action = function (id) { | |
43 | - var follows_you, you_follow | |
49 … | + var content = msg.value.content | |
50 … | + if(content.type == 'contact' && content.contact) { | |
51 … | + var relation = isRelated(content.following, 'follows') | |
52 … | + if(content.blocking) relation = 'blocks' | |
53 … | + return h('div.contact', relation, api.avatar(msg.value.content.contact, 'thumbnail')) | |
54 … | + } | |
55 … | + } | |
44 | 56 … | |
45 | - var self_id = require('../keys').id | |
46 | - follower_of(self_id, id, function (err, f) { | |
47 | - you_follow = f | |
48 | - update() | |
49 | - }) | |
50 | - follower_of(id, self_id, function (err, f) { | |
51 | - follows_you = f | |
52 | - update() | |
53 | - }) | |
57 … | + exports.avatar_action = function (id) { | |
58 … | + var follows_you, you_follow | |
54 | 59 … | |
55 | - var state = h('label') | |
56 | - var label = h('span') | |
60 … | + var self_id = require('../keys').id | |
61 … | + api.follower_of(self_id, id, function (err, f) { | |
62 … | + you_follow = f | |
63 … | + update() | |
64 … | + }) | |
65 … | + api.follower_of(id, self_id, function (err, f) { | |
66 … | + follows_you = f | |
67 … | + update() | |
68 … | + }) | |
57 | 69 … | |
58 | - function update () { | |
59 | - state.textContent = ( | |
60 | - follows_you && you_follow ? 'friend' | |
61 | - : follows_you ? 'follows you' | |
62 | - : you_follow ? 'you follow' | |
63 | - : '' | |
70 … | + var state = h('label') | |
71 … | + var label = h('span') | |
72 … | + | |
73 … | + function update () { | |
74 … | + state.textContent = ( | |
75 … | + follows_you && you_follow ? 'friend' | |
76 … | + : follows_you ? 'follows you' | |
77 … | + : you_follow ? 'you follow' | |
78 … | + : '' | |
79 … | + ) | |
80 … | + | |
81 … | + label.textContent = you_follow ? 'unfollow' : 'follow' | |
82 … | + } | |
83 … | + | |
84 … | + return h('div', state, | |
85 … | + h('a', {href:'#', onclick: function () { | |
86 … | + api.message_confirm({ | |
87 … | + type: 'contact', | |
88 … | + contact: id, | |
89 … | + following: !you_follow | |
90 … | + }, function (err, msg) { | |
91 … | + if (err) return console.error(err) | |
92 … | + you_follow = msg.value.content.following | |
93 … | + update() | |
94 … | + }) | |
95 … | + }}, h('br'), label) | |
64 | 96 … | ) |
65 | - | |
66 | - label.textContent = you_follow ? 'unfollow' : 'follow' | |
67 | 97 … | } |
68 | - | |
69 | - return h('div', state, | |
70 | - h('a', {href:'#', onclick: function () { | |
71 | - message_confirm({ | |
72 | - type: 'contact', | |
73 | - contact: id, | |
74 | - following: !you_follow | |
75 | - }, function (err, msg) { | |
76 | - if (err) return console.error(err) | |
77 | - you_follow = msg.value.content.following | |
78 | - update() | |
79 | - }) | |
80 | - }}, h('br'), label) | |
81 | - ) | |
98 … | + return exports | |
82 | 99 … | } |
83 | - | |
84 | - | |
85 | - | |
86 | - |
modules_basic/index.js | ||
---|---|---|
@@ -23,8 +23,8 @@ | ||
23 | 23 … | "relationships.js": require('./relationships.js'), |
24 | 24 … | "search-box.js": require('./search-box.js'), |
25 | 25 … | "setup.js": require('./setup'), |
26 | 26 … | "suggest-mentions.js": require('./suggest-mentions.js'), |
27 | - "suggest.js": require('./suggest.js'), | |
28 | 27 … | "thread.js": require('./thread.js'), |
29 | 28 … | "timestamp.js": require('./timestamp.js') |
30 | 29 … | } |
30 … | + |
modules_basic/invite.js | ||
---|---|---|
@@ -1,112 +1,126 @@ | ||
1 | - | |
1 … | +'use strict' | |
2 | 2 … | var ref = require('ssb-ref') |
3 | 3 … | var ssbClient = require('ssb-client') |
4 | 4 … | var id = require('../keys').id |
5 | 5 … | var h = require('hyperscript') |
6 | 6 … | |
7 | 7 … | var Progress = require('hyperprogress') |
8 | 8 … | |
9 | -var plugs = require('../plugs') | |
10 | -var sbot_publish = plugs.first(exports.sbot_publish = []) | |
11 | -var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = []) | |
12 | -var follower_of = plugs.first(exports.follower_of = []) | |
9 … | +//var plugs = require('../plugs') | |
10 … | +//var sbot_publish = plugs.first(exports.sbot_publish = []) | |
11 … | +//var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = []) | |
12 … | +//var follower_of = plugs.first(exports.follower_of = []) | |
13 | 13 … | |
14 | -exports.invite_parse = function (invite) { | |
15 | - return ref.parseInvite(invite) | |
14 … | +exports.needs = { | |
15 … | + sbot_publish: 'first', | |
16 … | + sbot_gossip_connect: 'first', | |
17 … | + follower_of: 'first', | |
18 … | + invite_parse: 'first', | |
16 | 19 … | } |
17 | 20 … | |
18 | -exports.invite_accept = function (invite, onProgress, cb) { | |
19 | - var data = exports.invite_parse(invite) | |
20 | - if(!data) return cb(new Error('not a valid invite code:' + invite)) | |
21 … | +exports.gives = { | |
22 … | + invite_parse: true, | |
23 … | + invite_accept: true, | |
24 … | + screen_view: true | |
25 … | +} | |
21 | 26 … | |
22 | - onProgress('connecting...') | |
27 … | +exports.create = function (api) { | |
28 … | + var self | |
29 … | + return self = { | |
30 … | + invite_parse: function (invite) { | |
31 … | + return ref.parseInvite(invite) | |
32 … | + }, | |
33 … | + | |
34 … | + invite_accept: function (invite, onProgress, cb) { | |
35 … | + var data = self.invite_parse(invite) | |
36 … | + if(!data) return cb(new Error('not a valid invite code:' + invite)) | |
37 … | + | |
38 … | + onProgress('connecting...') | |
23 | 39 … | |
24 | - sbot_gossip_connect(data.remote, function (err) { | |
25 | - if(err) console.log(err) | |
26 | - }) | |
40 … | + api.sbot_gossip_connect(data.remote, function (err) { | |
41 … | + if(err) console.log(err) | |
42 … | + }) | |
27 | 43 … | |
28 | - ssbClient(null, { | |
29 | - remote: data.invite, | |
30 | - manifest: { invite: {use: 'async'}, getAddress: 'async' } | |
31 | - }, function (err, sbot) { | |
32 | - if(err) return cb(err) | |
33 | - onProgress('requesting follow...') | |
34 | - console.log(sbot) | |
35 | - sbot.invite.use({feed: id}, function (err, msg) { | |
44 … | + ssbClient(null, { | |
45 … | + remote: data.invite, | |
46 … | + manifest: { invite: {use: 'async'}, getAddress: 'async' } | |
47 … | + }, function (err, sbot) { | |
48 … | + if(err) return cb(err) | |
49 … | + onProgress('requesting follow...') | |
50 … | + console.log(sbot) | |
51 … | + sbot.invite.use({feed: id}, function (err, msg) { | |
36 | 52 … | |
37 | - //if they already follow us, just check we actually follow them. | |
38 | - if(err) follower_of(id, data.key, function (_err, follows) { | |
39 | - if(follows) cb(err) | |
53 … | + //if they already follow us, just check we actually follow them. | |
54 … | + if(err) api.follower_of(id, data.key, function (_err, follows) { | |
55 … | + if(follows) cb(err) | |
56 … | + else next() | |
57 … | + }) | |
40 | 58 … | else next() |
41 | - }) | |
42 | - else next() | |
43 | 59 … | |
44 | - function next () { | |
45 | - onProgress('following...') | |
60 … | + function next () { | |
61 … | + onProgress('following...') | |
46 | 62 … | |
47 | - //remove the seed from the shs address. | |
48 | - //then it's correct address. | |
49 | - //this should make the browser connect to this as remote. | |
50 | - //we don't want to do this if when using this locally, though. | |
51 | - if(process.title === 'browser') | |
52 | - localStorage.remote = data.remote | |
63 … | + //remove the seed from the shs address. | |
64 … | + //then it's correct address. | |
65 … | + //this should make the browser connect to this as remote. | |
66 … | + //we don't want to do this if when using this locally, though. | |
67 … | + if(process.title === 'browser') | |
68 … | + localStorage.remote = data.remote | |
53 | 69 … | |
54 | - sbot_publish({ | |
55 | - type: 'contact', | |
56 | - contact: data.key, | |
57 | - following: true, | |
58 | - }, cb) | |
59 | - } | |
60 | - }) | |
61 | - }) | |
62 | -} | |
70 … | + api.sbot_publish({ | |
71 … | + type: 'contact', | |
72 … | + contact: data.key, | |
73 … | + following: true, | |
74 … | + }, cb) | |
75 … | + } | |
76 … | + }) | |
77 … | + }) | |
78 … | + }, | |
63 | 79 … | |
64 | -exports.screen_view = function (invite) { | |
80 … | + screen_view: function (invite) { | |
65 | 81 … | |
66 | - var data = ref.parseInvite(invite) | |
67 | - if(!data) return | |
82 … | + var data = ref.parseInvite(invite) | |
83 … | + if(!data) return | |
68 | 84 … | |
69 | - var progress = Progress(4) | |
85 … | + var progress = Progress(4) | |
70 | 86 … | |
71 | - //connect to server | |
72 | - //request follow | |
73 | - //post pub announce | |
74 | - //post follow pub | |
75 | - var div = h('div.column', | |
76 | - h('div', | |
77 | - "you have been invited to join:", h('br'), | |
78 | - h('code', data.invite) | |
79 | - ), | |
80 | - h('button', 'accept', {onclick: attempt}), | |
81 | - progress | |
82 | - ) | |
87 … | + //connect to server | |
88 … | + //request follow | |
89 … | + //post pub announce | |
90 … | + //post follow pub | |
91 … | + var div = h('div.column', | |
92 … | + h('div', | |
93 … | + "you have been invited to join:", h('br'), | |
94 … | + h('code', data.invite) | |
95 … | + ), | |
96 … | + h('button', 'accept', {onclick: attempt}), | |
97 … | + progress | |
98 … | + ) | |
83 | 99 … | |
84 | - function attempt () { | |
85 | - exports.invite_accept(invite, function (message) { | |
86 | - progress.next(message) | |
87 | - }, function (err) { | |
88 | - if(err) return progress.fail(err) | |
89 | - progress.complete() | |
90 | - //check for redirect | |
91 | - var parts = location.hash.substring(1).split('#') | |
100 … | + function attempt () { | |
101 … | + self.invite_accept(invite, function (message) { | |
102 … | + progress.next(message) | |
103 … | + }, function (err) { | |
104 … | + if(err) return progress.fail(err) | |
105 … | + progress.complete() | |
106 … | + //check for redirect | |
107 … | + var parts = location.hash.substring(1).split('#') | |
92 | 108 … | |
93 | - //TODO: handle in a consistent way with either hashrouting | |
94 | - //or with tabs... | |
95 | - if(parts[0] === data.invite) | |
96 | - location.hash = '' | |
97 | - else | |
98 | - console.log("NO REDIRECT") | |
99 | - }) | |
100 | - } | |
109 … | + //TODO: handle in a consistent way with either hashrouting | |
110 … | + //or with tabs... | |
111 … | + if(parts[0] === data.invite) | |
112 … | + location.hash = '' | |
113 … | + else | |
114 … | + console.log("NO REDIRECT") | |
115 … | + }) | |
116 … | + } | |
101 | 117 … | |
102 | - // If we are in the browser, | |
103 | - // and do not already have a remote set, automatically trigger the invite. | |
104 | - if(process.title == 'browser' && !localStorage.remote) attempt() | |
118 … | + // If we are in the browser, | |
119 … | + // and do not already have a remote set, automatically trigger the invite. | |
120 … | + if(process.title == 'browser' && !localStorage.remote) attempt() | |
105 | 121 … | |
106 | - return div | |
122 … | + return div | |
123 … | + } | |
124 … | + } | |
107 | 125 … | } |
108 | 126 … | |
109 | - | |
110 | - | |
111 | - | |
112 | - |
modules_basic/like.js | ||
---|---|---|
@@ -4,59 +4,75 @@ | ||
4 | 4 … | var pull = require('pull-stream') |
5 | 5 … | |
6 | 6 … | var plugs = require('../plugs') |
7 | 7 … | |
8 | -var message_confirm = plugs.first(exports.message_confirm = []) | |
9 | -var message_link = plugs.first(exports.message_link = []) | |
10 | -var sbot_links = plugs.first(exports.sbot_links = []) | |
8 … | +//var message_confirm = plugs.first(exports.message_confirm = []) | |
9 … | +//var message_link = plugs.first(exports.message_link = []) | |
10 … | +//var sbot_links = plugs.first(exports.sbot_links = []) | |
11 | 11 … | |
12 … | +exports.needs = { | |
13 … | + message_confirm: 'first', | |
14 … | + message_link: 'first', | |
15 … | + sbot_links: 'first' | |
16 … | +} | |
12 | 17 … | |
13 | -exports.message_content = | |
14 | -exports.message_content_mini = function (msg, sbot) { | |
15 | - if(msg.value.content.type !== 'vote') return | |
16 | - var link = msg.value.content.vote.link | |
17 | - return [ | |
18 | - msg.value.content.vote.value > 0 ? 'dug' : 'undug', | |
19 | - ' ', message_link(link) | |
20 | - ] | |
18 … | +exports.gives = { | |
19 … | + message_content: true, | |
20 … | + message_content_mini: true, | |
21 … | + message_meta: true, | |
22 … | + message_action: true | |
21 | 23 … | } |
22 | 24 … | |
23 | -exports.message_meta = function (msg, sbot) { | |
24 | - var digs = h('a') | |
25 … | +exports.create = function (api) { | |
26 … | + var exports = {} | |
25 | 27 … | |
26 | - var votes = [] | |
27 | - for(var k in CACHE) { | |
28 | - if(CACHE[k].content.type == 'vote' && | |
29 | - (CACHE[k].content.vote == msg.key || | |
30 | - CACHE[k].content.vote.link == msg.key | |
31 | - )) | |
32 | - votes.push({source: CACHE[k].author, dest: k, rel: 'vote'}) | |
28 … | + exports.message_content = | |
29 … | + exports.message_content_mini = function (msg, sbot) { | |
30 … | + if(msg.value.content.type !== 'vote') return | |
31 … | + var link = msg.value.content.vote.link | |
32 … | + return [ | |
33 … | + msg.value.content.vote.value > 0 ? 'dug' : 'undug', | |
34 … | + ' ', api.message_link(link) | |
35 … | + ] | |
33 | 36 … | } |
34 | 37 … | |
35 | - if(votes.length === 1) | |
36 | - digs.textContent = ' 1 Dig' | |
37 | - if(votes.length > 1) | |
38 | - digs.textContent = ' ' + votes.length + ' Digs' | |
38 … | + exports.message_meta = function (msg, sbot) { | |
39 … | + var digs = h('a') | |
39 | 40 … | |
40 | - return digs | |
41 | -} | |
41 … | + var votes = [] | |
42 … | + for(var k in CACHE) { | |
43 … | + if(CACHE[k].content.type == 'vote' && | |
44 … | + (CACHE[k].content.vote == msg.key || | |
45 … | + CACHE[k].content.vote.link == msg.key | |
46 … | + )) | |
47 … | + votes.push({source: CACHE[k].author, dest: k, rel: 'vote'}) | |
48 … | + } | |
42 | 49 … | |
43 | -exports.message_action = function (msg, sbot) { | |
44 | - if(msg.value.content.type !== 'vote') | |
45 | - return h('a.dig', {href: '#', onclick: function () { | |
46 | - var dig = { | |
47 | - type: 'vote', | |
48 | - vote: { link: msg.key, value: 1, expression: 'Dig' } | |
49 | - } | |
50 | - if(msg.value.content.recps) { | |
51 | - dig.recps = msg.value.content.recps.map(function (e) { | |
52 | - return e && typeof e !== 'string' ? e.link : e | |
53 | - }) | |
54 | - dig.private = true | |
55 | - } | |
56 | - //TODO: actually publish... | |
50 … | + if(votes.length === 1) | |
51 … | + digs.textContent = ' 1 Dig' | |
52 … | + if(votes.length > 1) | |
53 … | + digs.textContent = ' ' + votes.length + ' Digs' | |
57 | 54 … | |
58 | - message_confirm(dig) | |
59 | - }}, 'Dig') | |
55 … | + return digs | |
56 … | + } | |
60 | 57 … | |
58 … | + exports.message_action = function (msg, sbot) { | |
59 … | + if(msg.value.content.type !== 'vote') | |
60 … | + return h('a.dig', {href: '#', onclick: function () { | |
61 … | + var dig = { | |
62 … | + type: 'vote', | |
63 … | + vote: { link: msg.key, value: 1, expression: 'Dig' } | |
64 … | + } | |
65 … | + if(msg.value.content.recps) { | |
66 … | + dig.recps = msg.value.content.recps.map(function (e) { | |
67 … | + return e && typeof e !== 'string' ? e.link : e | |
68 … | + }) | |
69 … | + dig.private = true | |
70 … | + } | |
71 … | + //TODO: actually publish... | |
72 … | + | |
73 … | + api.message_confirm(dig) | |
74 … | + }}, 'Dig') | |
75 … | + | |
76 … | + } | |
77 … | + return exports | |
61 | 78 … | } |
62 | - |
modules_basic/markdown.js | ||
---|---|---|
@@ -1,40 +1,52 @@ | ||
1 | 1 … | var markdown = require('ssb-markdown') |
2 | 2 … | var h = require('hyperscript') |
3 | 3 … | var ref = require('ssb-ref') |
4 | 4 … | |
5 | -var plugs = require('../plugs') | |
6 | -var blob_url = plugs.first(exports.blob_url = []) | |
7 | -var emoji_url = plugs.first(exports.emoji_url = []) | |
5 … | +//var plugs = require('../plugs') | |
6 … | +//var blob_url = plugs.first(exports.blob_url = []) | |
7 … | +//var emoji_url = plugs.first(exports.emoji_url = []) | |
8 | 8 … | |
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">' | |
9 … | +exports.needs = { | |
10 … | + blob_url: 'first', | |
11 … | +// emoji_url: 'first' | |
16 | 12 … | } |
17 | 13 … | |
18 | -exports.markdown = function (content) { | |
19 | - if('string' === typeof content) | |
20 | - content = {text: content} | |
21 | - //handle patchwork style mentions. | |
22 | - var mentions = {} | |
23 | - if(Array.isArray(content.mentions)) | |
24 | - content.mentions.forEach(function (link) { | |
25 | - if(link.name) mentions["@"+link.name] = link.link | |
14 … | +exports.gives = 'markdown' | |
15 … | + | |
16 … | +exports.create = function (api) { | |
17 … | + | |
18 … | +//emoji is in extra, disable for a sec | |
19 … | + | |
20 … | +// function renderEmoji(emoji) { | |
21 … | +// var url = api.emoji_url(emoji) | |
22 … | +// if (!url) return ':' + emoji + ':' | |
23 … | +// return '<img src="' + encodeURI(url) + '"' | |
24 … | +// + ' alt=":' + escape(emoji) + ':"' | |
25 … | +// + ' title=":' + escape(emoji) + ':"' | |
26 … | +// + ' class="emoji">' | |
27 … | +// } | |
28 … | + | |
29 … | + return function (content) { | |
30 … | + if('string' === typeof content) | |
31 … | + content = {text: content} | |
32 … | + //handle patchwork style mentions. | |
33 … | + var mentions = {} | |
34 … | + if(Array.isArray(content.mentions)) | |
35 … | + content.mentions.forEach(function (link) { | |
36 … | + if(link.name) mentions["@"+link.name] = link.link | |
37 … | + }) | |
38 … | + | |
39 … | + var md = h('div.markdown') | |
40 … | + md.innerHTML = markdown.block(content.text, { | |
41 … | + // emoji: renderEmoji, | |
42 … | + toUrl: function (id) { | |
43 … | + if(ref.isBlob(id)) return api.blob_url(id) | |
44 … | + return '#'+(mentions[id]?mentions[id]:id) | |
45 … | + } | |
26 | 46 … | }) |
27 | 47 … | |
28 | - var md = h('div.markdown') | |
29 | - md.innerHTML = markdown.block(content.text, { | |
30 | - emoji: renderEmoji, | |
31 | - toUrl: function (id) { | |
32 | - if(ref.isBlob(id)) return blob_url(id) | |
33 | - return '#'+(mentions[id]?mentions[id]:id) | |
34 | - } | |
35 | - }) | |
48 … | + return md | |
36 | 49 … | |
37 | - return md | |
38 | - | |
50 … | + } | |
39 | 51 … | } |
40 | 52 … |
modules_basic/message-link.js | ||
---|---|---|
@@ -1,29 +1,35 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var ref = require('ssb-ref') |
3 | 3 … | |
4 | -var first = require('../plugs').first | |
5 | -var sbot_get = first(exports.sbot_get = []) | |
6 | -var message_name = first(exports.message_name = []) | |
4 … | +//var first = require('../plugs').first | |
5 … | +//var sbot_get = first(exports.sbot_get = []) | |
6 … | +//var message_name = first(exports.message_name = []) | |
7 | 7 … | |
8 | -exports.message_link = function (id) { | |
8 … | +exports.needs = { | |
9 … | + message_name: 'first' | |
10 … | +} | |
9 | 11 … | |
10 | - if('string' !== typeof id) | |
11 | - throw new Error('link must be to message id') | |
12 … | +exports.gives = 'message_link' | |
12 | 13 … | |
13 | - var link = h('a', {href: '#'+id}, id.substring(0, 10)+'...') | |
14 … | +exports.create = function (api) { | |
14 | 15 … | |
15 | - if(ref.isMsg(id)) | |
16 | - message_name(id, function (err, name) { | |
17 | - if(err) console.error(err) | |
18 | - else link.textContent = name | |
19 | - }) | |
16 … | + return function (id) { | |
20 | 17 … | |
21 | - return link | |
22 | -} | |
18 … | + if('string' !== typeof id) | |
19 … | + throw new Error('link must be to message id') | |
23 | 20 … | |
21 … | + var link = h('a', {href: '#'+id}, id.substring(0, 10)+'...') | |
24 | 22 … | |
23 … | + if(ref.isMsg(id)) | |
24 … | + api.message_name(id, function (err, name) { | |
25 … | + if(err) console.error(err) | |
26 … | + else link.textContent = name | |
27 … | + }) | |
25 | 28 … | |
29 … | + return link | |
30 … | + } | |
31 … | +} | |
26 | 32 … | |
27 | 33 … | |
28 | 34 … | |
29 | 35 … |
modules_basic/message-name.js | ||
---|---|---|
@@ -1,21 +1,26 @@ | ||
1 | 1 … | |
2 | -var sbot_get = require('../plugs').first(exports.sbot_get = []) | |
3 | - | |
4 | 2 … | function title (s) { |
5 | 3 … | var m = /^\n*([^\n]{0,40})/.exec(s) |
6 | 4 … | return m && (m[1].length == 40 ? m[1]+'...' : m[1]) |
7 | 5 … | } |
8 | 6 … | |
9 | -exports.message_name = function (id, cb) { | |
10 | - sbot_get(id, function (err, value) { | |
11 | - if(err && err.name == 'NotFoundError') | |
12 | - return cb(null, id.substring(0, 10)+'...(missing)') | |
13 | - if(value.content.type === 'post' && 'string' === typeof value.content.text) | |
14 | - return cb(null, title(value.content.text)) | |
15 | - else if('string' === typeof value.content.text) | |
16 | - return cb(null, value.content.type + ':'+title(value.content.text)) | |
17 | - else | |
18 | - return cb(null, id.substring(0, 10)+'...') | |
19 | - }) | |
7 … | +exports.needs = { sbot_get: 'first' } | |
8 … | +exports.gives = 'message_name' | |
9 … | + | |
10 … | +//TODO: rewrite as observable? | |
11 … | + | |
12 … | +exports.create = function (api) { | |
13 … | + return function (id, cb) { | |
14 … | + api.sbot_get(id, function (err, value) { | |
15 … | + if(err && err.name == 'NotFoundError') | |
16 … | + return cb(null, id.substring(0, 10)+'...(missing)') | |
17 … | + if(value.content.type === 'post' && 'string' === typeof value.content.text) | |
18 … | + return cb(null, title(value.content.text)) | |
19 … | + else if('string' === typeof value.content.text) | |
20 … | + return cb(null, value.content.type + ':'+title(value.content.text)) | |
21 … | + else | |
22 … | + return cb(null, id.substring(0, 10)+'...') | |
23 … | + }) | |
24 … | + } | |
20 | 25 … | } |
21 | 26 … |
modules_basic/message.js | ||
---|---|---|
@@ -1,109 +1,122 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | 4 … | |
5 | -var plugs = require('../plugs') | |
6 | -var message_content = plugs.first(exports.message_content = []) | |
7 | -var message_content_mini = plugs.first(exports.message_content_mini = []) | |
8 | -var avatar = plugs.first(exports.avatar = []) | |
9 | -var avatar_name = plugs.first(exports.avatar_name = []) | |
10 | -var avatar_link = plugs.first(exports.avatar_link = []) | |
11 | -var message_meta = plugs.map(exports.message_meta = []) | |
12 | -var message_action = plugs.map(exports.message_action = []) | |
13 | -var message_link = plugs.first(exports.message_link = []) | |
5 … | +//var plugs = require('../plugs') | |
6 … | +// | |
7 … | +//var message_content = plugs.first(exports.message_content = []) | |
8 … | +//var message_content_mini = plugs.first(exports.message_content_mini = []) | |
9 … | +// | |
10 … | +//var avatar = plugs.first(exports.avatar = []) | |
11 … | +//var avatar_name = plugs.first(exports.avatar_name = []) | |
12 … | +//var avatar_link = plugs.first(exports.avatar_link = []) | |
13 … | +//var message_meta = plugs.map(exports.message_meta = []) | |
14 … | +//var message_action = plugs.map(exports.message_action = []) | |
15 … | +//var message_link = plugs.first(exports.message_link = []) | |
16 … | +// | |
17 … | +//var sbot_links = plugs.first(exports.sbot_links = []) | |
14 | 18 … | |
15 | -var sbot_links = plugs.first(exports.sbot_links = []) | |
16 | - | |
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)) | |
24 | - ) | |
25 | - ) | |
26 | - div.setAttribute('tabindex', '0') | |
27 | - return div | |
19 … | +exports.needs = { | |
20 … | + message_content: 'first', | |
21 … | + message_content_mini: 'first', | |
22 … | + avatar: 'first', | |
23 … | + avatar_name: 'first', | |
24 … | + avatar_link: 'first', | |
25 … | + message_meta: 'map', | |
26 … | + message_action: 'map', | |
27 … | + message_link: 'first', | |
28 … | +// sbot_links: 'first' | |
28 | 29 … | } |
29 | 30 … | |
31 … | +exports.gives = 'message_render' | |
32 … | + | |
30 | 33 … | function message_content_mini_fallback(msg) { |
31 | 34 … | return h('code', msg.value.content.type) |
32 | 35 … | } |
33 | 36 … | |
34 | -exports.message_render = function (msg, sbot) { | |
35 | - var el = message_content_mini(msg) | |
36 | - if(el) return mini(msg, el) | |
37 … | +exports.create = function (api) { | |
37 | 38 … | |
38 | - var el = message_content(msg) | |
39 | - if(!el) return mini(msg, message_content_mini_fallback(msg)) | |
40 | - | |
41 | - var links = [] | |
42 | - for(var k in CACHE) { | |
43 | - var _msg = CACHE[k] | |
44 | - if(Array.isArray(_msg.content.mentions)) { | |
45 | - for(var i = 0; i < _msg.content.mentions.length; i++) | |
46 | - if(_msg.content.mentions[i].link == msg.key) | |
47 | - links.push(k) | |
48 | - } | |
39 … | + function mini(msg, el) { | |
40 … | + var div = h('div.message.message--mini', | |
41 … | + h('div.row', | |
42 … | + h('div', | |
43 … | + api.avatar_link(msg.value.author, api.avatar_name(msg.value.author)), | |
44 … | + h('span.message_content', el)), | |
45 … | + h('div.message_meta.row', api.message_meta(msg)) | |
46 … | + ) | |
47 … | + ) | |
48 … | + div.setAttribute('tabindex', '0') | |
49 … | + return div | |
49 | 50 … | } |
50 | 51 … | |
51 | - var backlinks = h('div.backlinks') | |
52 | - if(links.length) | |
53 | - backlinks.appendChild(h('label', 'backlinks:', | |
54 | - h('div', links.map(function (key) { | |
55 | - return message_link(key) | |
56 | - })) | |
57 | - )) | |
52 … | + return function (msg, sbot) { | |
53 … | + var el = api.message_content_mini(msg) | |
54 … | + if(el) return mini(msg, el) | |
58 | 55 … | |
56 … | + var el = api.message_content(msg) | |
57 … | + if(!el) return mini(msg, message_content_mini_fallback(msg)) | |
59 | 58 … | |
60 | -// pull( | |
61 | -// sbot_links({dest: msg.key, rel: 'mentions', keys: true}), | |
62 | -// pull.collect(function (err, links) { | |
63 | -// if(links.length) | |
64 | -// backlinks.appendChild(h('label', 'backlinks:', | |
65 | -// h('div', links.map(function (link) { | |
66 | -// return message_link(link.key) | |
67 | -// })) | |
68 | -// )) | |
69 | -// }) | |
70 | -// ) | |
71 | - | |
72 | - var msg = h('div.message', | |
73 | - h('div.title.row', | |
74 | - h('div.avatar', avatar(msg.value.author, 'thumbnail')), | |
75 | - h('div.message_meta.row', message_meta(msg)) | |
76 | - ), | |
77 | - h('div.message_content', el), | |
78 | - h('div.message_actions.row', | |
79 | - h('div.actions', message_action(msg), | |
80 | - h('a', {href: '#' + msg.key}, 'Reply') | |
81 | - ) | |
82 | - ), | |
83 | - backlinks, | |
84 | - {onkeydown: function (ev) { | |
85 | - //on enter, hit first meta. | |
86 | - if(ev.keyCode == 13) { | |
87 | - | |
88 | - // unless in an input | |
89 | - if (ev.target.nodeName === 'INPUT' | |
90 | - || ev.target.nodeName === 'TEXTAREA') return | |
91 | - | |
92 | - msg.querySelector('.enter').click() | |
59 … | + var links = [] | |
60 … | + for(var k in CACHE) { | |
61 … | + var _msg = CACHE[k] | |
62 … | + if(Array.isArray(_msg.content.mentions)) { | |
63 … | + for(var i = 0; i < _msg.content.mentions.length; i++) | |
64 … | + if(_msg.content.mentions[i].link == msg.key) | |
65 … | + links.push(k) | |
93 | 66 … | } |
94 | - }} | |
95 | - ) | |
67 … | + } | |
96 | 68 … | |
97 | - // ); hyperscript does not seem to set attributes correctly. | |
98 | - msg.setAttribute('tabindex', '0') | |
69 … | + var backlinks = h('div.backlinks') | |
70 … | + if(links.length) | |
71 … | + backlinks.appendChild(h('label', 'backlinks:', | |
72 … | + h('div', links.map(function (key) { | |
73 … | + return api.message_link(key) | |
74 … | + })) | |
75 … | + )) | |
99 | 76 … | |
100 | - return msg | |
101 | -} | |
102 | 77 … | |
78 … | + // pull( | |
79 … | + // sbot_links({dest: msg.key, rel: 'mentions', keys: true}), | |
80 … | + // pull.collect(function (err, links) { | |
81 … | + // if(links.length) | |
82 … | + // backlinks.appendChild(h('label', 'backlinks:', | |
83 … | + // h('div', links.map(function (link) { | |
84 … | + // return message_link(link.key) | |
85 … | + // })) | |
86 … | + // )) | |
87 … | + // }) | |
88 … | + // ) | |
103 | 89 … | |
90 … | + var msg = h('div.message', | |
91 … | + h('div.title.row', | |
92 … | + h('div.avatar', api.avatar(msg.value.author, 'thumbnail')), | |
93 … | + h('div.message_meta.row', api.message_meta(msg)) | |
94 … | + ), | |
95 … | + h('div.message_content', el), | |
96 … | + h('div.message_actions.row', | |
97 … | + h('div.actions', api.message_action(msg), | |
98 … | + h('a', {href: '#' + msg.key}, 'Reply') | |
99 … | + ) | |
100 … | + ), | |
101 … | + backlinks, | |
102 … | + {onkeydown: function (ev) { | |
103 … | + //on enter, hit first meta. | |
104 … | + if(ev.keyCode == 13) { | |
104 | 105 … | |
106 … | + // unless in an input | |
107 … | + if (ev.target.nodeName === 'INPUT' | |
108 … | + || ev.target.nodeName === 'TEXTAREA') return | |
105 | 109 … | |
110 … | + msg.querySelector('.enter').click() | |
111 … | + } | |
112 … | + }} | |
113 … | + ) | |
106 | 114 … | |
115 … | + // ); hyperscript does not seem to set attributes correctly. | |
116 … | + msg.setAttribute('tabindex', '0') | |
107 | 117 … | |
118 … | + return msg | |
119 … | + } | |
120 … | +} | |
108 | 121 … | |
109 | 122 … |
modules_basic/names.js | ||
---|---|---|
@@ -5,12 +5,23 @@ | ||
5 | 5 … | function all(stream, cb) { |
6 | 6 … | pull(stream, pull.collect(cb)) |
7 | 7 … | } |
8 | 8 … | |
9 | -var plugs = require('../plugs') | |
10 | -var sbot_links2 = plugs.first(exports.sbot_links2 = []) | |
11 | -var sbot_query = plugs.first(exports.sbot_query = []) | |
9 … | +//var plugs = require('../plugs') | |
10 … | +//var sbot_links2 = plugs.first(exports.sbot_links2 = []) | |
11 … | +//var sbot_query = plugs.first(exports.sbot_query = []) | |
12 … | +// | |
13 … | +exports.needs = { | |
14 … | + sbot_links2: 'first', | |
15 … | + sbot_query: 'first' | |
16 … | +} | |
12 | 17 … | |
18 … | +exports.gives = { | |
19 … | + connection_status: true, | |
20 … | + signifier: true, | |
21 … | + signified: true, | |
22 … | +} | |
23 … | + | |
13 | 24 … | /* |
14 | 25 … | filter(rel: ['mentions', prefix('@')]) | reduce(name: rel[1], value: count()) |
15 | 26 … | */ |
16 | 27 … | |
@@ -107,63 +118,66 @@ | ||
107 | 118 … | ts: "timestamp" |
108 | 119 … | }}, |
109 | 120 … | reduce |
110 | 121 … | ] |
122 … | +exports.create = function (api) { | |
111 | 123 … | |
124 … | + var exports = {} | |
125 … | + exports.connection_status = function (err) { | |
126 … | + if(!err) { | |
127 … | + pull( | |
128 … | + many([ | |
129 … | + api.sbot_links2({query: [filter, map, reduce]}), | |
130 … | + add_sigil(api.sbot_query({query: [filter2, map2, reduce]})), | |
131 … | + add_sigil(api.sbot_query({query: queryNamedGitRepos})) | |
132 … | + ]), | |
133 … | + //reducing also ensures order by the lookup properties | |
134 … | + //in this case: [name, id] | |
135 … | + mfr.reduce(merge), | |
136 … | + pull.collect(function (err, ary) { | |
137 … | + if(!err) { | |
138 … | + NAMES = names = ary | |
139 … | + ready = true | |
140 … | + while(waiting.length) waiting.shift()() | |
141 … | + } | |
142 … | + }) | |
143 … | + ) | |
112 | 144 … | |
113 | -exports.connection_status = function (err) { | |
114 | - if(!err) { | |
115 | - pull( | |
116 | - many([ | |
117 | - sbot_links2({query: [filter, map, reduce]}), | |
118 | - add_sigil(sbot_query({query: [filter2, map2, reduce]})), | |
119 | - add_sigil(sbot_query({query: queryNamedGitRepos})) | |
145 … | + pull(many([ | |
146 … | + api.sbot_links2({query: [filter, map], old: false}), | |
147 … | + add_sigil(api.sbot_query({query: [filter2, map2], old: false})), | |
148 … | + add_sigil(api.sbot_query({query: queryNamedGitRepos, old: false})) | |
120 | 149 … | ]), |
121 | - //reducing also ensures order by the lookup properties | |
122 | - //in this case: [name, id] | |
123 | - mfr.reduce(merge), | |
124 | - pull.collect(function (err, ary) { | |
125 | - if(!err) { | |
126 | - NAMES = names = ary | |
127 | - ready = true | |
128 | - while(waiting.length) waiting.shift()() | |
129 | - } | |
130 | - }) | |
131 | - ) | |
150 … | + pull.drain(update)) | |
151 … | + } | |
152 … | + } | |
132 | 153 … | |
133 | - pull(many([ | |
134 | - sbot_links2({query: [filter, map], old: false}), | |
135 | - add_sigil(sbot_query({query: [filter2, map2], old: false})), | |
136 | - add_sigil(sbot_query({query: queryNamedGitRepos, old: false})) | |
137 | - ]), | |
138 | - pull.drain(update)) | |
154 … | + function async(fn) { | |
155 … | + return function (value, cb) { | |
156 … | + function go () { cb(null, fn(value)) } | |
157 … | + if(ready) go() | |
158 … | + else waiting.push(go) | |
159 … | + } | |
139 | 160 … | } |
140 | -} | |
141 | 161 … | |
142 | -function async(fn) { | |
143 | - return function (value, cb) { | |
144 | - function go () { cb(null, fn(value)) } | |
145 | - if(ready) go() | |
146 | - else waiting.push(go) | |
162 … | + function rank(ary) { | |
163 … | + //sort by most used, or most recently used | |
164 … | + return ary.sort(function (a, b) { return b.rank - a.rank || b.ts - a.ts }) | |
147 | 165 … | } |
148 | -} | |
149 | 166 … | |
150 | -function rank(ary) { | |
151 | - //sort by most used, or most recently used | |
152 | - return ary.sort(function (a, b) { return b.rank - a.rank || b.ts - a.ts }) | |
153 | -} | |
167 … | + //we are just iterating over the entire array. | |
168 … | + //if this becomes a problem, maintain two arrays | |
169 … | + //one of each sort order, but do not duplicate the objects. | |
170 … | + //that should mean the space required is just 2x object references, | |
171 … | + //not 2x objects, and we can use binary search to find matches. | |
154 | 172 … | |
155 | -//we are just iterating over the entire array. | |
156 | -//if this becomes a problem, maintain two arrays | |
157 | -//one of each sort order, but do not duplicate the objects. | |
158 | -//that should mean the space required is just 2x object references, | |
159 | -//not 2x objects, and we can use binary search to find matches. | |
173 … | + exports.signifier = async(function (id) { | |
174 … | + return rank(names.filter(function (e) { return e.id == id})) | |
175 … | + }) | |
160 | 176 … | |
161 | -exports.signifier = async(function (id) { | |
162 | - return rank(names.filter(function (e) { return e.id == id})) | |
163 | -}) | |
177 … | + exports.signified = async(function (name) { | |
178 … | + var rx = new RegExp('^'+name) | |
179 … | + return rank(names.filter(function (e) { return rx.test(e.name) })) | |
180 … | + }) | |
164 | 181 … | |
165 | -exports.signified = async(function (name) { | |
166 | - var rx = new RegExp('^'+name) | |
167 | - return rank(names.filter(function (e) { return rx.test(e.name) })) | |
168 | -}) | |
169 | - | |
182 … | + return exports | |
183 … | +} |
modules_basic/post.js | ||
---|---|---|
@@ -4,23 +4,30 @@ | ||
4 | 4 … | var ref = require('ssb-ref') |
5 | 5 … | |
6 | 6 … | //render a message |
7 | 7 … | |
8 | -var plugs = require('../plugs') | |
9 | -var message_link = plugs.first(exports.message_link = []) | |
10 | -var markdown = plugs.first(exports.markdown = []) | |
8 … | +//var plugs = require('../plugs') | |
9 … | +//var message_link = plugs.first(exports.message_link = []) | |
10 … | +//var markdown = plugs.first(exports.markdown = []) | |
11 … | +// | |
11 | 12 … | |
12 | -exports.message_content = function (data) { | |
13 | - if(!data.value.content || !data.value.content.text) return | |
13 … | +exports.needs = { message_link: 'first', markdown: 'first' } | |
14 | 14 … | |
15 | - var root = data.value.content.root | |
16 | - var re = !root ? null : h('span', 're: ', message_link(root)) | |
15 … | +exports.gives = 'message_content' | |
17 | 16 … | |
18 | - return h('div', | |
19 | - re, | |
20 | - markdown(data.value.content) | |
21 | - ) | |
17 … | +exports.create = function (api) { | |
18 … | + return function (data) { | |
19 … | + if(!data.value.content || !data.value.content.text) return | |
22 | 20 … | |
21 … | + var root = data.value.content.root | |
22 … | + var re = !root ? null : h('span', 're: ', api.message_link(root)) | |
23 … | + | |
24 … | + return h('div', | |
25 … | + re, | |
26 … | + api.markdown(data.value.content) | |
27 … | + ) | |
28 … | + | |
29 … | + } | |
23 | 30 … | } |
24 | 31 … | |
25 | 32 … | |
26 | 33 … | |
@@ -33,5 +40,4 @@ | ||
33 | 40 … | |
34 | 41 … | |
35 | 42 … | |
36 | 43 … | |
37 | - |
modules_basic/private.js | ||
---|---|---|
@@ -1,105 +1,128 @@ | ||
1 … | +'use strict' | |
1 | 2 … | var h = require('hyperscript') |
2 | 3 … | var u = require('../util') |
3 | 4 … | var pull = require('pull-stream') |
4 | 5 … | var Scroller = require('pull-scroll') |
5 | 6 … | var ref = require('ssb-ref') |
6 | 7 … | |
7 | -var plugs = require('../plugs') | |
8 … | +//var plugs = require('../plugs') | |
9 … | +// | |
10 … | +//var message_render = plugs.first(exports.message_render = []) | |
11 … | +//var message_compose = plugs.first(exports.message_compose = []) | |
12 … | +//var message_unbox = plugs.first(exports.message_unbox = []) | |
13 … | +//var sbot_log = plugs.first(exports.sbot_log = []) | |
14 … | +//var sbot_whoami = plugs.first(exports.sbot_whoami = []) | |
15 … | +//var avatar_image_link = plugs.first(exports.avatar_image_link = []) | |
16 … | +//var emoji_url = plugs.first(exports.emoji_url = []) | |
8 | 17 … | |
9 | -var message_render = plugs.first(exports.message_render = []) | |
10 | -var message_compose = plugs.first(exports.message_compose = []) | |
11 | -var message_unbox = plugs.first(exports.message_unbox = []) | |
12 | -var sbot_log = plugs.first(exports.sbot_log = []) | |
13 | -var sbot_whoami = plugs.first(exports.sbot_whoami = []) | |
14 | -var avatar_image_link = plugs.first(exports.avatar_image_link = []) | |
15 | -var emoji_url = plugs.first(exports.emoji_url = []) | |
18 … | +function map(ary, iter) { | |
19 … | + if(Array.isArray(ary)) return ary.map(iter) | |
20 … | +} | |
16 | 21 … | |
17 | -function unbox () { | |
18 | - return pull( | |
19 | - pull.filter(function (msg) { | |
20 | - return 'string' == typeof msg.value.content | |
21 | - }), | |
22 | - pull.map(function (msg) { | |
23 | - return message_unbox(msg) | |
24 | - }), | |
25 | - pull.filter(Boolean) | |
26 | - ) | |
22 … | +exports.needs = { | |
23 … | + message_render: 'first', | |
24 … | + message_compose: 'first', | |
25 … | + message_unbox: 'first', | |
26 … | + sbot_log: 'first', | |
27 … | + sbot_whoami: 'first', | |
28 … | + avatar_image_link: 'first', | |
29 … | +// emoji_link: 'first' | |
27 | 30 … | } |
28 | 31 … | |
29 | -exports.builtin_tabs = function () { | |
30 | - return ['/private'] | |
32 … | +exports.gives = { | |
33 … | + builtin_tabs: true, | |
34 … | + screen_view: true, | |
35 … | + message_meta: true, | |
36 … | + message_content_mini: true | |
31 | 37 … | } |
32 | 38 … | |
33 | -exports.screen_view = function (path) { | |
34 | - if(path !== '/private') return | |
39 … | +exports.create = function (api) { | |
35 | 40 … | |
36 | - var div = h('div.column.scroller', | |
37 | - {style: {'overflow':'auto'}}) | |
41 … | + function unbox () { | |
42 … | + return pull( | |
43 … | + pull.filter(function (msg) { | |
44 … | + return 'string' == typeof msg.value.content | |
45 … | + }), | |
46 … | + pull.map(function (msg) { | |
47 … | + return api.message_unbox(msg) | |
48 … | + }), | |
49 … | + pull.filter(Boolean) | |
50 … | + ) | |
51 … | + } | |
38 | 52 … | |
39 | - // if local id is different from sbot id, sbot won't have indexes of | |
40 | - // private threads | |
41 | - var id = require('../keys').id | |
42 | - sbot_whoami(function (err, feed) { | |
43 | - if (err) return console.error(err) | |
44 | - if(id !== feed.id) | |
45 | - return div.appendChild(h('h4', | |
46 | - 'Private messages are not supported in the lite client.')) | |
53 … | + return { | |
54 … | + builtin_tabs: function () { | |
55 … | + return ['/private'] | |
56 … | + }, | |
47 | 57 … | |
48 | - var compose = message_compose( | |
49 | - {type: 'post', recps: [], private: true}, | |
50 | - { | |
51 | - prepublish: function (msg) { | |
52 | - msg.recps = [id].concat(msg.mentions).filter(function (e) { | |
53 | - return ref.isFeed('string' === typeof e ? e : e.link) | |
54 | - }) | |
55 | - if(!msg.recps.length) | |
56 | - throw new Error('cannot make private message without recipients - just mention the user in an at reply in the message you send') | |
57 | - return msg | |
58 | - }, | |
59 | - placeholder: 'Write a private message' | |
60 | - } | |
61 | - ) | |
58 … | + screen_view: function (path) { | |
59 … | + if(path !== '/private') return | |
62 | 60 … | |
63 | - var content = h('div.column.scroller__content') | |
64 | - div.appendChild(h('div.scroller__wrapper', compose, content)) | |
61 … | + var div = h('div.column.scroller', | |
62 … | + {style: {'overflow':'auto'}}) | |
65 | 63 … | |
66 | - pull( | |
67 | - u.next(sbot_log, {old: false, limit: 100}), | |
68 | - unbox(), | |
69 | - Scroller(div, content, message_render, true, false) | |
70 | - ) | |
64 … | + // if local id is different from sbot id, sbot won't have indexes of | |
65 … | + // private threads | |
66 … | + //TODO: put all private indexes client side. | |
67 … | + var id = require('../keys').id | |
68 … | + api.sbot_whoami(function (err, feed) { | |
69 … | + if (err) return console.error(err) | |
70 … | + if(id !== feed.id) | |
71 … | + return div.appendChild(h('h4', | |
72 … | + 'Private messages are not supported in the lite client.')) | |
71 | 73 … | |
72 | - pull( | |
73 | - u.next(sbot_log, {reverse: true, limit: 1000}), | |
74 | - unbox(), | |
75 | - Scroller(div, content, message_render, false, false, function (err) { | |
76 | - if(err) throw err | |
74 … | + var compose = api.message_compose( | |
75 … | + {type: 'post', recps: [], private: true}, | |
76 … | + { | |
77 … | + prepublish: function (msg) { | |
78 … | + msg.recps = [id].concat(msg.mentions).filter(function (e) { | |
79 … | + return ref.isFeed('string' === typeof e ? e : e.link) | |
80 … | + }) | |
81 … | + if(!msg.recps.length) | |
82 … | + throw new Error('cannot make private message without recipients - just mention the user in an at reply in the message you send') | |
83 … | + return msg | |
84 … | + }, | |
85 … | + placeholder: 'Write a private message' | |
86 … | + } | |
87 … | + ) | |
88 … | + | |
89 … | + var content = h('div.column.scroller__content') | |
90 … | + div.appendChild(h('div.scroller__wrapper', compose, content)) | |
91 … | + | |
92 … | + pull( | |
93 … | + u.next(api.sbot_log, {old: false, limit: 100}), | |
94 … | + unbox(), | |
95 … | + Scroller(div, content, api.message_render, true, false) | |
96 … | + ) | |
97 … | + | |
98 … | + pull( | |
99 … | + u.next(api.sbot_log, {reverse: true, limit: 1000}), | |
100 … | + unbox(), | |
101 … | + Scroller(div, content, api.message_render, false, false, function (err) { | |
102 … | + if(err) throw err | |
103 … | + }) | |
104 … | + ) | |
77 | 105 … | }) |
78 | - ) | |
79 | - }) | |
80 | 106 … | |
81 | - return div | |
82 | -} | |
107 … | + return div | |
108 … | + }, | |
83 | 109 … | |
84 | -function map(ary, iter) { | |
85 | - if(Array.isArray(ary)) return ary.map(iter) | |
86 | -} | |
110 … | + message_meta: function (msg) { | |
111 … | + if(msg.value.content.recps || msg.value.private) | |
112 … | + return h('span.row', 'PRIVATE', map(msg.value.content.recps, function (id) { | |
113 … | + return api.avatar_image_link('string' == typeof id ? id : id.link, 'thumbnail') | |
114 … | + })) | |
115 … | + }, | |
87 | 116 … | |
88 | -exports.message_meta = function (msg) { | |
89 | - if(msg.value.content.recps || msg.value.private) | |
90 | - return h('span.row', 'PRIVATE', map(msg.value.content.recps, function (id) { | |
91 | - return avatar_image_link('string' == typeof id ? id : id.link, 'thumbnail') | |
92 | - })) | |
93 | -} | |
117 … | + message_content_mini: function (msg, sbot) { | |
118 … | + if (typeof msg.value.content === 'string') { | |
119 … | + var icon = false //api.emoji_url('lock') | |
120 … | + return icon | |
121 … | + ? h('img', {className: 'emoji', src: icon}) | |
122 … | + : 'PRIVATE' | |
123 … | + } | |
124 … | + } | |
125 … | + } | |
94 | 126 … | |
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 | 127 … | } |
103 | 128 … | |
104 | - | |
105 | - |
modules_basic/pub.js | ||
---|---|---|
@@ -1,18 +1,29 @@ | ||
1 | 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 = []) | |
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.needs = { | |
7 … | + avatar_name: 'first', | |
8 … | + avatar_link: 'first' | |
9 … | +} | |
5 | 10 … | |
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 | - ] | |
11 … | +exports.gives = 'message_content' | |
12 … | + | |
13 … | +exports.create = function (api) { | |
14 … | + | |
15 … | + return function (msg, sbot) { | |
16 … | + var c = msg.value.content | |
17 … | + if (c.type === 'pub') { | |
18 … | + var address = c.address || {} | |
19 … | + return [ | |
20 … | + h('p', 'announced an address for ', | |
21 … | + api.avatar_link(address.key, api.avatar_name(address.key)), ':'), | |
22 … | + h('blockquote', | |
23 … | + h('code', address.host + ':' + address.port) | |
24 … | + ) | |
25 … | + ] | |
26 … | + } | |
17 | 27 … | } |
28 … | + | |
18 | 29 … | } |
modules_basic/public.js | ||
---|---|---|
@@ -2,39 +2,53 @@ | ||
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | 4 … | var Scroller = require('pull-scroll') |
5 | 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 = []) | |
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 | 10 … | |
11 | -exports.builtin_tabs = function () { | |
12 | - return ['/public'] | |
11 … | +exports.needs = { | |
12 … | + message_render: 'first', | |
13 … | + message_compose: 'first', | |
14 … | + sbot_log: 'first', | |
13 | 15 … | } |
14 | 16 … | |
15 | -exports.screen_view = function (path, sbot) { | |
16 | - if(path === '/public') { | |
17 … | +exports.gives = { | |
18 … | + builtin_tabs: true, screen_view: true | |
19 … | +} | |
17 | 20 … | |
18 | - var content = h('div.column.scroller__content') | |
19 | - var div = h('div.column.scroller', | |
20 | - {style: {'overflow':'auto'}}, | |
21 | - h('div.scroller__wrapper', | |
22 | - message_compose({type: 'post'}, {placeholder: 'Write a public message'}), | |
23 | - content | |
24 | - ) | |
25 | - ) | |
21 … | +exports.create = function (api) { | |
26 | 22 … | |
27 | - pull( | |
28 | - u.next(sbot_log, {old: false, limit: 100}), | |
29 | - Scroller(div, content, message_render, true, false) | |
30 | - ) | |
23 … | + return { | |
24 … | + builtin_tabs: function () { | |
25 … | + return ['/public'] | |
26 … | + }, | |
31 | 27 … | |
32 | - pull( | |
33 | - u.next(sbot_log, {reverse: true, limit: 100, live: false}), | |
34 | - Scroller(div, content, message_render, false, false) | |
35 | - ) | |
28 … | + screen_view: function (path, sbot) { | |
29 … | + if(path === '/public') { | |
36 | 30 … | |
37 | - return div | |
31 … | + var content = h('div.column.scroller__content') | |
32 … | + var div = h('div.column.scroller', | |
33 … | + {style: {'overflow':'auto'}}, | |
34 … | + h('div.scroller__wrapper', | |
35 … | + api.message_compose({type: 'post'}, {placeholder: 'Write a public message'}), | |
36 … | + content | |
37 … | + ) | |
38 … | + ) | |
39 … | + | |
40 … | + pull( | |
41 … | + u.next(api.sbot_log, {old: false, limit: 100}), | |
42 … | + Scroller(div, content, api.message_render, true, false) | |
43 … | + ) | |
44 … | + | |
45 … | + pull( | |
46 … | + u.next(api.sbot_log, {reverse: true, limit: 100, live: false}), | |
47 … | + Scroller(div, content, api.message_render, false, false) | |
48 … | + ) | |
49 … | + | |
50 … | + return div | |
51 … | + } | |
52 … | + } | |
38 | 53 … | } |
39 | 54 … | } |
40 | - |
modules_basic/relationships.js | ||
---|---|---|
@@ -1,8 +1,8 @@ | ||
1 | 1 … | var pull = require('pull-stream') |
2 | -var plugs = require('../plugs') | |
2 … | +//var plugs = require('../plugs') | |
3 | 3 … | |
4 | -var sbot_query = plugs.first(exports.sbot_query = []) | |
4 … | +//var sbot_query = plugs.first(exports.sbot_query = []) | |
5 | 5 … | |
6 | 6 … | //this is a bit crude, and doesn't actually show unfollows yet. |
7 | 7 … | |
8 | 8 … | function makeQuery (a, b) { |
@@ -18,33 +18,45 @@ | ||
18 | 18 … | }} |
19 | 19 … | } |
20 | 20 … | |
21 | 21 … | |
22 | -exports.follows = function (id, cb) { | |
23 | - return sbot_query({query: [ | |
24 | - makeQuery(id, {$prefix:"@"}), | |
25 | - {"$map": ['value', 'content', 'contact']} | |
26 | - ]}) | |
27 | -} | |
22 … | +exports.needs = { sbot_query: 'first' } | |
28 | 23 … | |
29 | -exports.followers = function (id) { | |
30 | - return sbot_query({query: [ | |
31 | - makeQuery({$prefix:"@"}, id), | |
32 | - {"$map": ['value', 'author']} | |
33 | - ]}) | |
24 … | +exports.gives = { | |
25 … | + follows: true, | |
26 … | + followers: true, | |
27 … | + follower_of: true | |
34 | 28 … | } |
35 | 29 … | |
36 | -exports.follower_of = function (source, dest, cb) { | |
37 | - pull( | |
38 | - sbot_query({query: [ | |
39 | - makeQuery(source, dest), | |
40 | - {$map: ['value', 'content', 'following']} | |
41 | - ]}), | |
42 | - pull.collect(function (err, ary) { | |
43 | - if(err) return cb(err) | |
44 | - else cb(null, ary.pop()) //will be true, or undefined/false | |
45 | - }) | |
46 | - ) | |
47 | -} | |
30 … | +exports.create = function (api) { | |
48 | 31 … | |
32 … | + return { | |
33 … | + follows: function (id, cb) { | |
34 … | + return api.sbot_query({query: [ | |
35 … | + makeQuery(id, {$prefix:"@"}), | |
36 … | + {"$map": ['value', 'content', 'contact']} | |
37 … | + ]}) | |
38 … | + }, | |
49 | 39 … | |
40 … | + followers: function (id) { | |
41 … | + return api.sbot_query({query: [ | |
42 … | + makeQuery({$prefix:"@"}, id), | |
43 … | + {"$map": ['value', 'author']} | |
44 … | + ]}) | |
45 … | + }, | |
50 | 46 … | |
47 … | + follower_of: function (source, dest, cb) { | |
48 … | + pull( | |
49 … | + api.sbot_query({query: [ | |
50 … | + makeQuery(source, dest), | |
51 … | + {$map: ['value', 'content', 'following']} | |
52 … | + ]}), | |
53 … | + pull.collect(function (err, ary) { | |
54 … | + if(err) return cb(err) | |
55 … | + else cb(null, ary.pop()) //will be true, or undefined/false | |
56 … | + }) | |
57 … | + ) | |
58 … | + } | |
59 … | + } | |
60 … | + | |
61 … | +} | |
62 … | + |
modules_basic/search-box.js | ||
---|---|---|
@@ -1,55 +1,78 @@ | ||
1 … | +'use strict' | |
2 … | +var cont = require('cont') | |
1 | 3 … | var h = require('hyperscript') |
2 | 4 … | var suggest = require('suggest-box') |
3 | 5 … | var pull = require('pull-stream') |
4 | -var plugs = require('../plugs') | |
5 | -var sbot_query = plugs.first(exports.sbot_query = []) | |
6 | -var sbot_links2 = plugs.first(exports.sbot_links2 = []) | |
7 | -var suggest_search = plugs.asyncConcat(exports.suggest_search = []) | |
8 | 6 … | |
7 … | +//var plugs = require('../plugs') | |
8 … | +//var sbot_query = plugs.first(exports.sbot_query = []) | |
9 … | +//var sbot_links2 = plugs.first(exports.sbot_links2 = []) | |
10 … | +//var suggest_search = plugs.asyncConcat(exports.suggest_search = []) | |
11 … | + | |
12 … | +exports.needs = { | |
13 … | + sbot_query: 'first', sbot_links2: 'first', | |
14 … | + suggest_search: 'map' //REWRITE | |
15 … | +} | |
16 … | + | |
9 | 17 … | var channels = [] |
10 | 18 … | |
19 … | +exports.gives = 'search_box' | |
11 | 20 … | |
12 | -exports.search_box = function (go) { | |
21 … | +exports.create = function (api) { | |
13 | 22 … | |
14 | - var suggestBox | |
15 | - var search = h('input.searchprompt', { | |
16 | - type: 'search', | |
17 | - placeholder: 'Commands', | |
18 | - onkeydown: function (ev) { | |
19 | - switch (ev.keyCode) { | |
20 | - case 13: // enter | |
21 | - if (suggestBox && suggestBox.active) { | |
22 | - suggestBox.complete() | |
23 | - ev.stopPropagation() | |
24 | - } | |
25 | - if (go(search.value.trim(), !ev.ctrlKey)) | |
23 … | + return function (go) { | |
24 … | + | |
25 … | + var suggestBox | |
26 … | + var search = h('input.searchprompt', { | |
27 … | + type: 'search', | |
28 … | + placeholder: 'Commands', | |
29 … | + onkeydown: function (ev) { | |
30 … | + switch (ev.keyCode) { | |
31 … | + case 13: // enter | |
32 … | + if (suggestBox && suggestBox.active) { | |
33 … | + suggestBox.complete() | |
34 … | + ev.stopPropagation() | |
35 … | + } | |
36 … | + if (go(search.value.trim(), !ev.ctrlKey)) | |
37 … | + search.blur() | |
38 … | + return | |
39 … | + case 27: // escape | |
40 … | + ev.preventDefault() | |
26 | 41 … | search.blur() |
27 | - return | |
28 | - case 27: // escape | |
29 | - ev.preventDefault() | |
30 | - search.blur() | |
31 | - return | |
42 … | + return | |
43 … | + } | |
32 | 44 … | } |
33 | - } | |
34 | - }) | |
45 … | + }) | |
35 | 46 … | |
36 | - search.activate = function (sigil, ev) { | |
37 | - search.focus() | |
38 | - ev.preventDefault() | |
39 | - if (search.value[0] === sigil) { | |
40 | - search.selectionStart = 1 | |
41 | - search.selectionEnd = search.value.length | |
42 | - } else { | |
43 | - search.value = sigil | |
47 … | + search.activate = function (sigil, ev) { | |
48 … | + search.focus() | |
49 … | + ev.preventDefault() | |
50 … | + if (search.value[0] === sigil) { | |
51 … | + search.selectionStart = 1 | |
52 … | + search.selectionEnd = search.value.length | |
53 … | + } else { | |
54 … | + search.value = sigil | |
55 … | + } | |
44 | 56 … | } |
45 | - } | |
46 | 57 … | |
47 | - var suggestions = {} | |
58 … | + var suggestions = {} | |
48 | 59 … | |
49 | - // delay until the element has a parent | |
50 | - setTimeout(function () { | |
51 | - suggestBox = suggest(search, suggest_search, {}) | |
52 | - }, 10) | |
60 … | + // delay until the element has a parent | |
61 … | + setTimeout(function () { | |
62 … | + suggestBox = suggest(search, function (word, cb) { | |
63 … | + cont.para(api.suggest_search(word)) | |
64 … | + (function (err, ary) { | |
65 … | + if(err) return cb(err) | |
53 | 66 … | |
54 | - return search | |
67 … | + cb(null, ary.filter(Boolean).reduce(function (a, b) { | |
68 … | + return a.concat(b) | |
69 … | + }, [])) | |
70 … | + }) | |
71 … | + }, {}) | |
72 … | + }, 10) | |
73 … | + | |
74 … | + return search | |
75 … | + } | |
76 … | + | |
55 | 77 … | } |
78 … | + |
modules_basic/setup.js | ||
---|---|---|
@@ -1,16 +1,25 @@ | ||
1 | 1 … | |
2 | 2 … | var h = require('hyperscript') |
3 | 3 … | var pull = require('pull-stream') |
4 | 4 … | |
5 | -var plugs = require('../plugs') | |
5 … | +//var plugs = require('../plugs') | |
6 … | +// | |
7 … | +//var avatar_edit = plugs.first(exports.avatar_edit = []) | |
8 … | +//var invite_parse = plugs.first(exports.invite_parse = []) | |
9 … | +//var invite_accept = plugs.first(exports.invite_accept = []) | |
10 … | +//var sbot_progress = plugs.first(exports.sbot_progress = []) | |
11 … | +//var sbot_query = plugs.first(exports.sbot_query = []) | |
12 … | +//var avatar = plugs.first(exports.avatar = []) | |
6 | 13 … | |
7 | -var avatar_edit = plugs.first(exports.avatar_edit = []) | |
8 | -var invite_parse = plugs.first(exports.invite_parse = []) | |
9 | -var invite_accept = plugs.first(exports.invite_accept = []) | |
10 | -var sbot_progress = plugs.first(exports.sbot_progress = []) | |
11 | -var sbot_query = plugs.first(exports.sbot_query = []) | |
12 | -var avatar = plugs.first(exports.avatar = []) | |
14 … | +exports.needs = { | |
15 … | + avatar: 'first', | |
16 … | + avatar_edit: 'first', | |
17 … | + invite_parse: 'first', | |
18 … | + invite_accept: 'first', | |
19 … | + sbot_progress: 'first', | |
20 … | + sbot_query: 'first' | |
21 … | +} | |
13 | 22 … | |
14 | 23 … | //maybe this could show the pubs, or |
15 | 24 … | //if someone locally follows you, |
16 | 25 … | //it could show the second degree pubs? |
@@ -27,119 +36,125 @@ | ||
27 | 36 … | }} |
28 | 37 … | }}] |
29 | 38 … | } |
30 | 39 … | |
31 | -//test whether we are connected to the ssb network. | |
32 | -exports.setup_is_fresh_install = function (cb) { | |
33 | - //test by checking whether you have any friends following you? | |
34 | - pull( | |
35 | - sbot_query({query: followers_query(id), limit: 1, live: false}), | |
36 | - pull.collect(function (err, ary) { | |
37 | - cb(err, !!ary.length) | |
38 | - }) | |
39 | - ) | |
40 | -} | |
40 … | +exports.create = function (api) { | |
41 | 41 … | |
42 | -function invite_form () { | |
43 | - var accept = h('button', 'enter code', {disabled: true, onclick: function () { | |
44 | - invite_accept(input.value, function (msg) { | |
45 | - status.textContent = msg | |
46 | - }, function (err) { | |
47 | - if(err) { | |
48 | - accept.textContent = 'error:'+(err.message || err.stack || error.type) | |
49 | - console.error(err) | |
42 … | + var exports = {} | |
43 … | + | |
44 … | + //test whether we are connected to the ssb network. | |
45 … | + exports.setup_is_fresh_install = function (cb) { | |
46 … | + //test by checking whether you have any friends following you? | |
47 … | + pull( | |
48 … | + api.sbot_query({query: followers_query(id), limit: 1, live: false}), | |
49 … | + pull.collect(function (err, ary) { | |
50 … | + cb(err, !!ary.length) | |
51 … | + }) | |
52 … | + ) | |
53 … | + } | |
54 … | + | |
55 … | + function invite_form () { | |
56 … | + var accept = h('button', 'enter code', {disabled: true, onclick: function () { | |
57 … | + api.invite_accept(input.value, function (msg) { | |
58 … | + status.textContent = msg | |
59 … | + }, function (err) { | |
60 … | + if(err) { | |
61 … | + accept.textContent = 'error:'+(err.message || err.stack || error.type) | |
62 … | + console.error(err) | |
63 … | + } | |
64 … | + else { | |
65 … | + input.value = '' | |
66 … | + accept.textContent = 'success!' | |
67 … | + } | |
68 … | + }) | |
69 … | + }}) | |
70 … | + | |
71 … | + function parseInput () { | |
72 … | + if(!input.value) { | |
73 … | + accept.disabled = true | |
74 … | + accept.textContent = 'enter code' | |
50 | 75 … | } |
76 … | + else if(!invite_parse(input.value)) { | |
77 … | + accept.disabled = true | |
78 … | + accept.textContent = 'invalid code' | |
79 … | + } | |
51 | 80 … | else { |
52 | - input.value = '' | |
53 | - accept.textContent = 'success!' | |
81 … | + accept.disabled = false | |
82 … | + accept.textContent = 'accept' | |
54 | 83 … | } |
55 | - }) | |
56 | - }}) | |
84 … | + } | |
57 | 85 … | |
58 | - function parseInput () { | |
59 | - if(!input.value) { | |
60 | - accept.disabled = true | |
61 | - accept.textContent = 'enter code' | |
62 | - } | |
63 | - else if(!invite_parse(input.value)) { | |
64 | - accept.disabled = true | |
65 | - accept.textContent = 'invalid code' | |
66 | - } | |
67 | - else { | |
68 | - accept.disabled = false | |
69 | - accept.textContent = 'accept' | |
70 | - } | |
86 … | + var input = h('input.wide', {placeholder: 'invite code', oninput: parseInput, onchange: parseInput}) | |
87 … | + | |
88 … | + return h('div.invite-form.row', input, accept) | |
71 | 89 … | } |
72 | 90 … | |
73 | - var input = h('input.wide', {placeholder: 'invite code', oninput: parseInput, onchange: parseInput}) | |
91 … | + exports.progress_bar = function () { | |
92 … | + var liquid = h('div.hyperprogress__liquid', '.') | |
93 … | + var bar = h('div.hyperprogress__bar', liquid) | |
94 … | + liquid.style.width = '0%' | |
74 | 95 … | |
75 | - return h('div.invite-form.row', input, accept) | |
76 | -} | |
96 … | + pull( | |
97 … | + api.sbot_progress(), | |
98 … | + pull.drain(function (e) { | |
99 … | + liquid.style.width = Math.round((e.progress/e.total)*100)+'%' | |
100 … | + }) | |
101 … | + ) | |
77 | 102 … | |
78 | -exports.progress_bar = function () { | |
79 | - var liquid = h('div.hyperprogress__liquid', '.') | |
80 | - var bar = h('div.hyperprogress__bar', liquid) | |
81 | - liquid.style.width = '0%' | |
103 … | + return bar | |
104 … | + } | |
82 | 105 … | |
83 | - pull( | |
84 | - sbot_progress(), | |
85 | - pull.drain(function (e) { | |
86 | - liquid.style.width = Math.round((e.progress/e.total)*100)+'%' | |
87 | - }) | |
88 | - ) | |
106 … | + //show the first 5 followers, and how they join you to the network. | |
107 … | + //so this will show if a local peer follows you. | |
89 | 108 … | |
90 | - return bar | |
91 | -} | |
109 … | + //when you join the network, I want this to show as people follow you. | |
110 … | + //that could be when a pub accepts the invite, or when a local peer accepts. | |
92 | 111 … | |
93 | -//show the first 5 followers, and how they join you to the network. | |
94 | -//so this will show if a local peer follows you. | |
112 … | + exports.setup_joined_network = function (id) { | |
113 … | + var followers = h('div.column') | |
114 … | + var label = h('label', 'not connected to a network') | |
115 … | + var joined = h('div.setup__joined', label, followers) | |
95 | 116 … | |
96 | -//when you join the network, I want this to show as people follow you. | |
97 | -//that could be when a pub accepts the invite, or when a local peer accepts. | |
117 … | + pull( | |
118 … | + api.sbot_query({query: followers_query(id), limit: 5, live: true, sync: false}), | |
119 … | + pull.drain(function (follower) { | |
120 … | + if(follower.sync) return | |
121 … | + label.textContent = 'connected to network via...' | |
122 … | + followers.appendChild( | |
123 … | + api.avatar(follower.value.author, 'thumbnail') | |
124 … | + ) | |
125 … | + }) | |
126 … | + ) | |
98 | 127 … | |
99 | -exports.setup_joined_network = function (id) { | |
100 | - var followers = h('div.column') | |
101 | - var label = h('label', 'not connected to a network') | |
102 | - var joined = h('div.setup__joined', label,followers) | |
128 … | + return joined | |
129 … | + } | |
103 | 130 … | |
104 | - pull( | |
105 | - sbot_query({query: followers_query(id), limit: 5, live: true, sync: false}), | |
106 | - pull.drain(function (follower) { | |
107 | - if(follower.sync) return | |
108 | - label.textContent = 'connected to network via...' | |
109 | - followers.appendChild( | |
110 | - avatar(follower.value.author, 'thumbnail') | |
111 | - ) | |
112 | - }) | |
113 | - ) | |
131 … | + exports.screen_view = function (path) { | |
114 | 132 … | |
115 | - return joined | |
116 | -} | |
133 … | + if(path !== '/setup') return | |
117 | 134 … | |
118 | -exports.screen_view = function (path) { | |
135 … | + var id = require('../keys').id | |
119 | 136 … | |
120 | - if(path !== '/setup') return | |
137 … | + //set up an avatar | |
121 | 138 … | |
122 | - var id = require('../keys').id | |
123 | 139 … | |
124 | - //set up an avatar | |
140 … | + var status = h('span') | |
141 … | + var invite = h('input', {placeholder: 'invite code'}) | |
142 … | + return h('div.scroller', h('div.scroller__wrapper', | |
143 … | + h('h1', 'welcome to patchbay!'), | |
144 … | + h('div', | |
145 … | + 'please choose avatar image and name', | |
146 … | + api.avatar_edit(id) | |
147 … | + ), | |
148 … | + h('h2', 'join network'), | |
149 … | + invite_form(), | |
150 … | + //show avatars of anyone on the same local network. | |
151 … | + //show realtime changes in your followers, especially for local. | |
125 | 152 … | |
153 … | + exports.progress_bar(), | |
154 … | + exports.setup_joined_network(require('../keys').id) | |
155 … | + )) | |
156 … | + } | |
126 | 157 … | |
127 | - var status = h('span') | |
128 | - var invite = h('input', {placeholder: 'invite code'}) | |
129 | - return h('div.scroller', h('div.scroller__wrapper', | |
130 | - h('h1', 'welcome to patchbay!'), | |
131 | - h('div', | |
132 | - 'please choose avatar image and name', | |
133 | - avatar_edit(id) | |
134 | - ), | |
135 | - h('h2', 'join network'), | |
136 | - invite_form(), | |
137 | - //show avatars of anyone on the same local network. | |
138 | - //show realtime changes in your followers, especially for local. | |
158 … | + return exports | |
139 | 159 … | |
140 | - exports.progress_bar(), | |
141 | - exports.setup_joined_network(require('../keys').id) | |
142 | - )) | |
143 | 160 … | } |
144 | - | |
145 | - |
modules_basic/suggest-mentions.js | ||
---|---|---|
@@ -2,64 +2,71 @@ | ||
2 | 2 … | function isImage (filename) { |
3 | 3 … | return /\.(gif|jpg|png|svg)$/i.test(filename) |
4 | 4 … | } |
5 | 5 … | |
6 | -var sbot_links2 = require('../plugs').first(exports.sbot_links2 = []) | |
7 | -var blob_url = require('../plugs').first(exports.blob_url = []) | |
8 | -var signified = require('../plugs').first(exports.signified = []) | |
9 | -var builtin_tabs = require('../plugs').map(exports.builtin_tabs = []) | |
6 … | +//var sbot_links2 = require('../plugs').first(exports.sbot_links2 = []) | |
7 … | +//var blob_url = require('../plugs').first(exports.blob_url = []) | |
8 … | +//var signified = require('../plugs').first(exports.signified = []) | |
9 … | +//var builtin_tabs = require('../plugs').map(exports.builtin_tabs = []) | |
10 | 10 … | |
11 | -exports.suggest_mentions = function (word, cb) { | |
12 | - if(!/^[%&@]\w/.test(word)) return cb() | |
13 | - | |
14 | - | |
15 | - signified(word, function (err, names) { | |
16 | - if(err) cb(err) | |
17 | - else cb(null, names.map(function (e) { | |
18 | - return { | |
19 | - title: e.name + ': ' + e.id.substring(0,10)+' ('+e.rank+')', | |
20 | - value: '['+e.name+']('+e.id+')', | |
21 | - rank: e.rank, | |
22 | - //TODO: avatar images... | |
23 | - } | |
24 | - })) | |
25 | - }) | |
11 … | +exports.needs = { | |
12 … | + sbot_links2: 'first', | |
13 … | + blob_url: 'first', | |
14 … | + signified: 'first', | |
15 … | + builtin_tabs: 'map' | |
26 | 16 … | } |
27 | 17 … | |
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 | - }) | |
40 | - | |
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() | |
18 … | +exports.gives = { | |
19 … | + suggest_mentions: true, | |
20 … | + suggest_search: true | |
52 | 21 … | } |
53 | 22 … | |
23 … | +exports.create = function (api) { | |
54 | 24 … | |
25 … | + return { | |
26 … | + suggest_mentions: function (word) { | |
27 … | + return function (cb) { | |
28 … | + if(!/^[%&@]\w/.test(word)) return cb() | |
55 | 29 … | |
30 … | + api.signified(word, function (err, names) { | |
31 … | + if(err) cb(err) | |
32 … | + else cb(null, names.map(function (e) { | |
33 … | + return { | |
34 … | + title: e.name + ': ' + e.id.substring(0,10)+' ('+e.rank+')', | |
35 … | + value: '['+e.name+']('+e.id+')', | |
36 … | + rank: e.rank, | |
37 … | + //TODO: avatar images... | |
38 … | + } | |
39 … | + })) | |
40 … | + }) | |
41 … | + } | |
42 … | + }, | |
56 | 43 … | |
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 | 57 … | |
58 | - | |
59 | - | |
60 | - | |
61 | - | |
62 | - | |
63 | - | |
64 | - | |
65 | - | |
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) { | |
63 … | + return { | |
64 … | + title: name, | |
65 … | + value: name, | |
66 … | + } | |
67 … | + })) | |
68 … | + } else cb() | |
69 … | + } | |
70 … | + } | |
71 … | + } | |
72 … | +} |
modules_basic/thread.js | ||
---|---|---|
@@ -20,106 +20,119 @@ | ||
20 | 20 … | }) |
21 | 21 … | } |
22 | 22 … | } |
23 | 23 … | |
24 | -var plugs = require('../plugs') | |
24 … | +//var plugs = require('../plugs') | |
25 … | +// | |
26 … | +//var message_render = plugs.first(exports.message_render = []) | |
27 … | +//var message_name = plugs.first(exports.message_name = []) | |
28 … | +//var message_compose = plugs.first(exports.message_compose = []) | |
29 … | +//var message_unbox = plugs.first(exports.message_unbox = []) | |
30 … | +// | |
31 … | +//var sbot_get = plugs.first(exports.sbot_get = []) | |
32 … | +//var sbot_links = plugs.first(exports.sbot_links = []) | |
25 | 33 … | |
26 | -var message_render = plugs.first(exports.message_render = []) | |
27 | -var message_name = plugs.first(exports.message_name = []) | |
28 | -var message_compose = plugs.first(exports.message_compose = []) | |
29 | -var message_unbox = plugs.first(exports.message_unbox = []) | |
34 … | +exports.needs = { | |
35 … | + message_render: 'first', | |
36 … | + message_name: 'first', | |
37 … | + message_compose: 'first', | |
38 … | + message_unbox: 'first', | |
39 … | + sbot_get: 'first', | |
40 … | + sbot_links: 'first' | |
41 … | +} | |
30 | 42 … | |
31 | -var sbot_get = plugs.first(exports.sbot_get = []) | |
32 | -var sbot_links = plugs.first(exports.sbot_links = []) | |
43 … | +exports.gives = 'screen_view' | |
33 | 44 … | |
34 | -function getThread (root, cb) { | |
35 | - //in this case, it's inconvienent that panel only takes | |
36 | - //a stream. maybe it would be better to accept an array? | |
37 | 45 … | |
38 | - sbot_get(root, function (err, value) { | |
39 | - if (err) return cb(err) | |
40 | - var msg = {key: root, value: value} | |
41 | -// if(value.content.root) return getThread(value.content.root, cb) | |
46 … | +exports.create = function (api) { | |
42 | 47 … | |
43 | - pull( | |
44 | - sbot_links({rel: 'root', dest: root, values: true, keys: true}), | |
45 | - pull.collect(function (err, ary) { | |
46 | - if(err) return cb(err) | |
47 | - ary.unshift(msg) | |
48 | - cb(null, ary) | |
49 | - }) | |
50 | - ) | |
51 | - }) | |
48 … | + function getThread (root, cb) { | |
49 … | + //in this case, it's inconvienent that panel only takes | |
50 … | + //a stream. maybe it would be better to accept an array? | |
52 | 51 … | |
53 | -} | |
52 … | + api.sbot_get(root, function (err, value) { | |
53 … | + if (err) return cb(err) | |
54 … | + var msg = {key: root, value: value} | |
55 … | + // if(value.content.root) return getThread(value.content.root, cb) | |
54 | 56 … | |
55 | -exports.screen_view = function (id) { | |
56 | - if(ref.isMsg(id)) { | |
57 | - var meta = { | |
58 | - type: 'post', | |
59 | - root: id, | |
60 | - branch: id //mutated when thread is loaded. | |
61 | - } | |
57 … | + pull( | |
58 … | + api.sbot_links({rel: 'root', dest: root, values: true, keys: true}), | |
59 … | + pull.collect(function (err, ary) { | |
60 … | + if(err) return cb(err) | |
61 … | + ary.unshift(msg) | |
62 … | + cb(null, ary) | |
63 … | + }) | |
64 … | + ) | |
65 … | + }) | |
62 | 66 … | |
63 | - var content = h('div.column.scroller__content') | |
64 | - var div = h('div.column.scroller', | |
65 | - {style: {'overflow-y': 'auto'}}, | |
66 | - h('div.scroller__wrapper', | |
67 | - content, | |
68 | - message_compose(meta, {shrink: false, placeholder: 'Write a reply'}) | |
67 … | + } | |
68 … | + | |
69 … | + return function (id) { | |
70 … | + if(ref.isMsg(id)) { | |
71 … | + var meta = { | |
72 … | + type: 'post', | |
73 … | + root: id, | |
74 … | + branch: id //mutated when thread is loaded. | |
75 … | + } | |
76 … | + | |
77 … | + var content = h('div.column.scroller__content') | |
78 … | + var div = h('div.column.scroller', | |
79 … | + {style: {'overflow-y': 'auto'}}, | |
80 … | + h('div.scroller__wrapper', | |
81 … | + content, | |
82 … | + api.message_compose(meta, {shrink: false, placeholder: 'Write a reply'}) | |
83 … | + ) | |
69 | 84 … | ) |
70 | - ) | |
71 | 85 … | |
72 | - message_name(id, function (err, name) { | |
73 | - div.title = name | |
74 | - }) | |
86 … | + api.message_name(id, function (err, name) { | |
87 … | + div.title = name | |
88 … | + }) | |
75 | 89 … | |
76 | - pull( | |
77 | - sbot_links({ | |
78 | - rel: 'root', dest: id, keys: true, old: false | |
79 | - }), | |
80 | - pull.drain(function (msg) { | |
81 | - loadThread() //redraw thread | |
82 | - }, function () {} ) | |
83 | - ) | |
90 … | + pull( | |
91 … | + api.sbot_links({ | |
92 … | + rel: 'root', dest: id, keys: true, old: false | |
93 … | + }), | |
94 … | + pull.drain(function (msg) { | |
95 … | + loadThread() //redraw thread | |
96 … | + }, function () {} ) | |
97 … | + ) | |
84 | 98 … | |
85 | 99 … | |
86 | - function loadThread () { | |
87 | - getThread(id, function (err, thread) { | |
88 | - //would probably be better keep an id for each message element | |
89 | - //(i.e. message key) and then update it if necessary. | |
90 | - //also, it may have moved (say, if you received a missing message) | |
91 | - content.innerHTML = '' | |
92 | - if(err) return content.appendChild(h('pre', err.stack)) | |
100 … | + function loadThread () { | |
101 … | + getThread(id, function (err, thread) { | |
102 … | + //would probably be better keep an id for each message element | |
103 … | + //(i.e. message key) and then update it if necessary. | |
104 … | + //also, it may have moved (say, if you received a missing message) | |
105 … | + content.innerHTML = '' | |
106 … | + if(err) return content.appendChild(h('pre', err.stack)) | |
93 | 107 … | |
94 | - //decrypt | |
95 | - thread = thread.map(function (msg) { | |
96 | - return 'string' === typeof msg.value.content ? message_unbox(msg) : msg | |
97 | - }) | |
108 … | + //decrypt | |
109 … | + thread = thread.map(function (msg) { | |
110 … | + return 'string' === typeof msg.value.content ? api.message_unbox(msg) : msg | |
111 … | + }) | |
98 | 112 … | |
99 | - if(err) return content.appendChild(h('pre', err.stack)) | |
100 | - sort(thread).map(message_render).filter(Boolean).forEach(function (el) { | |
101 | - content.appendChild(el) | |
113 … | + if(err) return content.appendChild(h('pre', err.stack)) | |
114 … | + sort(thread).map(api.message_render).filter(Boolean).forEach(function (el) { | |
115 … | + content.appendChild(el) | |
116 … | + }) | |
117 … | + | |
118 … | + var branches = sort.heads(thread) | |
119 … | + meta.branch = branches.length > 1 ? branches : branches[0] | |
120 … | + meta.root = thread[0].value.content.root || thread[0].key | |
121 … | + meta.channel = thread[0].value.content.channel | |
122 … | + | |
123 … | + var recps = thread[0].value.content.recps | |
124 … | + var private = thread[0].value.private | |
125 … | + if(private) { | |
126 … | + if(recps) | |
127 … | + meta.recps = recps | |
128 … | + else | |
129 … | + meta.recps = [thread[0].value.author, self_id] | |
130 … | + } | |
102 | 131 … | }) |
132 … | + } | |
103 | 133 … | |
104 | - var branches = sort.heads(thread) | |
105 | - meta.branch = branches.length > 1 ? branches : branches[0] | |
106 | - meta.root = thread[0].value.content.root || thread[0].key | |
107 | - meta.channel = thread[0].value.content.channel | |
108 | - | |
109 | - var recps = thread[0].value.content.recps | |
110 | - var private = thread[0].value.private | |
111 | - if(private) { | |
112 | - if(recps) | |
113 | - meta.recps = recps | |
114 | - else | |
115 | - meta.recps = [thread[0].value.author, self_id] | |
116 | - } | |
117 | - }) | |
134 … | + loadThread() | |
135 … | + return div | |
118 | 136 … | } |
119 | - | |
120 | - loadThread() | |
121 | - return div | |
122 | 137 … | } |
123 | 138 … | } |
124 | - | |
125 | - |
modules_basic/timestamp.js | ||
---|---|---|
@@ -1,21 +1,28 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var human = require('human-time') |
3 | 3 … | |
4 | -function updateTimestampEl(el) { | |
5 | - el.firstChild.nodeValue = human(new Date(el.timestamp)) | |
6 | - return el | |
7 | -} | |
4 … | +exports.needs = {} | |
8 | 5 … | |
9 | -setInterval(function () { | |
10 | - var els = [].slice.call(document.querySelectorAll('.timestamp')) | |
11 | - els.forEach(updateTimestampEl) | |
12 | -}, 60e3) | |
6 … | +exports.gives = 'message_meta' | |
13 | 7 … | |
14 | -exports.message_meta = function (msg) { | |
15 | - return updateTimestampEl(h('a.enter.timestamp', { | |
16 | - href: '#'+msg.key, | |
17 | - timestamp: msg.value.timestamp, | |
18 | - title: new Date(msg.value.timestamp) | |
19 | - }, '')) | |
8 … | +exports.create = function () { | |
9 … | + | |
10 … | + function updateTimestampEl(el) { | |
11 … | + el.firstChild.nodeValue = human(new Date(el.timestamp)) | |
12 … | + return el | |
13 … | + } | |
14 … | + | |
15 … | + setInterval(function () { | |
16 … | + var els = [].slice.call(document.querySelectorAll('.timestamp')) | |
17 … | + els.forEach(updateTimestampEl) | |
18 … | + }, 60e3) | |
19 … | + | |
20 … | + return function (msg) { | |
21 … | + return updateTimestampEl(h('a.enter.timestamp', { | |
22 … | + href: '#'+msg.key, | |
23 … | + timestamp: msg.value.timestamp, | |
24 … | + title: new Date(msg.value.timestamp) | |
25 … | + }, '')) | |
26 … | + } | |
27 … | + | |
20 | 28 … | } |
21 | - |
modules_core/app.js | ||
---|---|---|
@@ -1,68 +1,42 @@ | ||
1 | 1 … | var plugs = require('../plugs') |
2 | 2 … | var h = require('hyperscript') |
3 | 3 … | |
4 | -var screen_view = plugs.first(exports.screen_view = []) | |
4 … | +module.exports = { | |
5 … | + needs: {screen_view: 'first'}, | |
6 … | + gives: 'app', | |
7 … | + create: function (api) { | |
8 … | + return function () { | |
9 … | + document.head.appendChild(h('style', require('../style.css.json'))) | |
5 | 10 … | |
11 … | + window.addEventListener('error', window.onError = function (e) { | |
12 … | + document.body.appendChild(h('div.error', | |
13 … | + h('h1', e.message), | |
14 … | + h('big', h('code', e.filename + ':' + e.lineno)), | |
15 … | + h('pre', e.error ? (e.error.stack || e.error.toString()) : e.toString()))) | |
16 … | + }) | |
6 | 17 … | |
7 | -exports.app = function () { | |
8 | - document.head.appendChild(h('style', require('../style.css.json'))) | |
18 … | + function hash() { | |
19 … | + return window.location.hash.substring(1) | |
20 … | + } | |
9 | 21 … | |
10 | - window.addEventListener('error', window.onError = function (e) { | |
11 | - document.body.appendChild(h('div.error', | |
12 | - h('h1', e.message), | |
13 | - h('big', h('code', e.filename + ':' + e.lineno)), | |
14 | - h('pre', e.error ? (e.error.stack || e.error.toString()) : e.toString()))) | |
15 | - }) | |
22 … | + console.log(hash() || 'tabs') | |
23 … | + var view = api.screen_view(hash() || 'tabs') | |
16 | 24 … | |
17 | - function hash() { | |
18 | - return window.location.hash.substring(1) | |
19 | - } | |
25 … | + var screen = h('div.screen.column', view) | |
20 | 26 … | |
21 | - var view = screen_view(hash() || 'tabs') | |
27 … | + window.onhashchange = function (ev) { | |
28 … | + var _view = view | |
29 … | + view = api.screen_view(hash() || 'tabs') | |
22 | 30 … | |
23 | - var screen = h('div.screen.column', view) | |
31 … | + if(_view) screen.replaceChild(view, _view) | |
32 … | + else document.body.appendChild(view) | |
33 … | + } | |
24 | 34 … | |
25 | - window.onhashchange = function (ev) { | |
26 | - var _view = view | |
27 | - view = screen_view(hash() || 'tabs') | |
35 … | + document.body.appendChild(screen) | |
28 | 36 … | |
29 | - if(_view) screen.replaceChild(view, _view) | |
30 | - else document.body.appendChild(view) | |
37 … | + return screen | |
38 … | + } | |
31 | 39 … | } |
32 | - | |
33 | - document.body.appendChild(screen) | |
34 | - | |
35 | - return screen | |
36 | - | |
37 | 40 … | } |
38 | 41 … | |
39 | 42 … | |
40 | - | |
41 | - | |
42 | - | |
43 | - | |
44 | - | |
45 | - | |
46 | - | |
47 | - | |
48 | - | |
49 | - | |
50 | - | |
51 | - | |
52 | - | |
53 | - | |
54 | - | |
55 | - | |
56 | - | |
57 | - | |
58 | - | |
59 | - | |
60 | - | |
61 | - | |
62 | - | |
63 | - | |
64 | - | |
65 | - | |
66 | - | |
67 | - | |
68 | - |
modules_core/blob-url.js | ||
---|---|---|
@@ -1,9 +1,13 @@ | ||
1 | 1 … | var config = require('../config') |
2 | 2 … | |
3 | -exports.blob_url = function (link) { | |
4 | - if('string' == typeof link.link) | |
5 | - link = link.link | |
6 | - return config().blobsUrl + '/'+link | |
3 … | +module.exports = { | |
4 … | + gives: 'blob_url', | |
5 … | + create: function () { | |
6 … | + return function (link) { | |
7 … | + if('string' == typeof link.link) | |
8 … | + link = link.link | |
9 … | + return config().blobsUrl + '/'+link | |
10 … | + } | |
11 … | + } | |
7 | 12 … | } |
8 | 13 … | |
9 | - |
modules_core/crypto.js | ||
---|---|---|
@@ -16,33 +16,45 @@ | ||
16 | 16 … | } |
17 | 17 … | } |
18 | 18 … | |
19 | 19 … | |
20 | -var sbot_publish = require('../plugs').first(exports.sbot_publish = []) | |
20 … | +module.exports = { | |
21 | 21 … | |
22 | -exports.message_unbox = function (msg) { | |
23 | - if(msg.value) { | |
24 | - var value = unbox_value(msg.value) | |
25 | - if(value) | |
26 | - return { | |
27 | - key: msg.key, value: value, timestamp: msg.timestamp | |
22 … | + needs: {sbot_publish: 'first'}, | |
23 … | + gives: { | |
24 … | + message_unbox: true, message_box: true, publish: true | |
25 … | + }, | |
26 … | + create: function (api) { | |
27 … | + | |
28 … | + var exports = {} | |
29 … | + exports.message_unbox = function (msg) { | |
30 … | + if(msg.value) { | |
31 … | + var value = unbox_value(msg.value) | |
32 … | + if(value) | |
33 … | + return { | |
34 … | + key: msg.key, value: value, timestamp: msg.timestamp | |
35 … | + } | |
36 … | + } | |
37 … | + else | |
38 … | + return unbox_value(msg) | |
28 | 39 … | } |
29 | - } | |
30 | - else | |
31 | - return unbox_value(msg) | |
32 | -} | |
33 | 40 … | |
34 | -exports.message_box = function (content) { | |
35 | - return ssbKeys.box(content, content.recps.map(function (e) { | |
36 | - return ref.isFeed(e) ? e : e.link | |
37 | - })) | |
38 | -} | |
41 … | + exports.message_box = function (content) { | |
42 … | + return ssbKeys.box(content, content.recps.map(function (e) { | |
43 … | + return ref.isFeed(e) ? e : e.link | |
44 … | + })) | |
45 … | + } | |
39 | 46 … | |
40 | -exports.publish = function (content, id) { | |
41 | - if(content.recps) | |
42 | - content = exports.message_box(content) | |
43 | - sbot_publish(content, function (err, msg) { | |
44 | - if(err) throw err | |
45 | - console.log('PUBLISHED', msg) | |
46 | - }) | |
47 … | + exports.publish = function (content, cb) { | |
48 … | + if(content.recps) | |
49 … | + content = exports.message_box(content) | |
50 … | + api.sbot_publish(content, function (err, msg) { | |
51 … | + if(err) throw err | |
52 … | + console.log('PUBLISHED', msg) | |
53 … | + if(cb) cb(err, msg) | |
54 … | + }) | |
55 … | + } | |
56 … | + | |
57 … | + return exports | |
58 … | + } | |
47 | 59 … | } |
48 | 60 … |
modules_core/file-input.js | ||
---|---|---|
@@ -7,31 +7,36 @@ | ||
7 | 7 … | var plugs = require('../plugs') |
8 | 8 … | |
9 | 9 … | var add = plugs.first(exports.sbot_blobs_add = []) |
10 | 10 … | |
11 | -exports.file_input = function FileInput(onAdded) { | |
11 … | +module.exports = { | |
12 … | + needs: {sbot_blobs_add: 'first'}, | |
13 … | + gives: 'file_input', | |
14 … | + create: function () { | |
15 … | + return function FileInput(onAdded) { | |
16 … | + return h('input', { type: 'file', | |
17 … | + onchange: function (ev) { | |
18 … | + var file = ev.target.files[0] | |
19 … | + if (!file) return | |
20 … | + var reader = new FileReader() | |
21 … | + reader.onload = function () { | |
22 … | + pull( | |
23 … | + pull.values(split(new Buffer(reader.result), 64*1024)), | |
24 … | + add(function (err, blob) { | |
25 … | + if(err) return console.error(err) | |
26 … | + onAdded({ | |
27 … | + link: blob, | |
28 … | + name: file.name, | |
29 … | + size: reader.result.length || reader.result.byteLength, | |
30 … | + type: mime(file.name) | |
31 … | + }) | |
12 | 32 … | |
13 | - return h('input', { type: 'file', | |
14 | - onchange: function (ev) { | |
15 | - var file = ev.target.files[0] | |
16 | - if (!file) return | |
17 | - var reader = new FileReader() | |
18 | - reader.onload = function () { | |
19 | - pull( | |
20 | - pull.values(split(new Buffer(reader.result), 64*1024)), | |
21 | - add(function (err, blob) { | |
22 | - if(err) return console.error(err) | |
23 | - onAdded({ | |
24 | - link: blob, | |
25 | - name: file.name, | |
26 | - size: reader.result.length || reader.result.byteLength, | |
27 | - type: mime(file.name) | |
28 | - }) | |
29 | - | |
30 | - }) | |
31 | - ) | |
32 | - } | |
33 | - reader.readAsArrayBuffer(file) | |
33 … | + }) | |
34 … | + ) | |
35 … | + } | |
36 … | + reader.readAsArrayBuffer(file) | |
37 … | + } | |
38 … | + }) | |
34 | 39 … | } |
35 | - }) | |
40 … | + } | |
36 | 41 … | } |
37 | 42 … |
modules_core/index.js | ||
---|---|---|
@@ -1,6 +1,6 @@ | ||
1 | 1 … | module.exports = { |
2 | - "_screen_view.js": require('./_screen_view.js'), | |
2 … | +// "_screen_view.js": require('./_screen_view.js'), | |
3 | 3 … | "app.js": require('./app.js'), |
4 | 4 … | "blob-url.js": require('./blob-url.js'), |
5 | 5 … | "crypto.js": require('./crypto.js'), |
6 | 6 … | "file-input.js": require('./file-input.js'), |
@@ -8,4 +8,5 @@ | ||
8 | 8 … | "message-confirm.js": require('./message-confirm.js'), |
9 | 9 … | "tabs.js": require('./tabs.js'), |
10 | 10 … | "sbot.js": require('./sbot.js') |
11 | 11 … | } |
12 … | + |
modules_core/menu.js | ||
---|---|---|
@@ -1,31 +1,45 @@ | ||
1 | 1 … | var plugs = require('../plugs') |
2 | 2 … | var h = require('hyperscript') |
3 | 3 … | |
4 | -var menu_items = plugs.map(exports.menu_items = []) | |
4 … | +module.exports = { | |
5 … | + needs: {menu_items: 'map'}, | |
6 … | + gives: {connection_status: true, menu: true}, | |
7 … | + create: function (api) { | |
5 | 8 … | |
6 | -var status = h('div.status.error') //start off disconnected | |
7 | - var list = h('div.menu.column', {style: 'display: none;'}) | |
9 … | + var menu_items = api.menu_items //plugs.map(exports.menu_items = []) | |
8 | 10 … | |
9 | -var menu = h('div.column', status, list , { | |
10 | - onmouseover: function (e) { | |
11 | - list.style.display = 'flex' | |
12 | - }, onmouseout: function () { | |
13 | - list.style.display = 'none' | |
14 | - } | |
15 | -}) | |
11 … | + var status = h('div.status.error') //start off disconnected | |
12 … | + var list = h('div.menu.column', {style: 'display: none;'}) | |
16 | 13 … | |
17 | -exports.connection_status = function (err) { | |
18 | - if(err) status.classList.add('error') | |
19 | - else status.classList.remove('error') | |
20 | -} | |
14 … | + var menu = h('div.column', status, list , { | |
15 … | + onmouseover: function (e) { | |
16 … | + list.style.display = 'flex' | |
17 … | + }, onmouseout: function () { | |
18 … | + list.style.display = 'none' | |
19 … | + } | |
20 … | + }) | |
21 | 21 … | |
22 | -exports.menu = function () { | |
23 | - menu_items().forEach(function (el) { | |
24 | - list.appendChild(el) | |
25 | - }) | |
22 … | + setTimeout(function () { | |
23 … | + menu_items().forEach(function (el) { | |
24 … | + if(el) | |
25 … | + list.appendChild(el) | |
26 … | + }) | |
27 … | + }, 0) | |
26 | 28 … | |
27 | - return menu | |
29 … | + return { | |
30 … | + connection_status: function (err) { | |
31 … | + if(err) status.classList.add('error') | |
32 … | + else status.classList.remove('error') | |
33 … | + }, | |
34 … | + menu: function () { | |
35 … | + return menu | |
36 … | + } | |
37 … | + } | |
38 … | + } | |
28 | 39 … | } |
29 | 40 … | |
30 | 41 … | |
31 | 42 … | |
43 … | + | |
44 … | + | |
45 … | + |
modules_core/message-confirm.js | ||
---|---|---|
@@ -5,57 +5,65 @@ | ||
5 | 5 … | //publish or add |
6 | 6 … | |
7 | 7 … | var plugs = require('../plugs') |
8 | 8 … | |
9 | -var publish = plugs.first(exports.sbot_publish = []) | |
10 | -var message_content = plugs.first(exports.message_content = []) | |
11 | -var avatar = plugs.first(exports.avatar = []) | |
12 | -var message_meta = plugs.map(exports.message_meta = []) | |
9 … | +exports.needs = { | |
10 … | + publish: 'first', message_content: 'first', avatar: 'first', | |
11 … | + message_meta: 'map' | |
12 … | +} | |
13 | 13 … | |
14 | -exports.message_confirm = function (content, cb) { | |
14 … | +exports.gives = 'message_confirm' | |
15 | 15 … | |
16 | - cb = cb || function () {} | |
16 … | +//var publish = plugs.first(exports.sbot_publish = []) | |
17 … | +//var message_content = plugs.first(exports.message_content = []) | |
18 … | +//var avatar = plugs.first(exports.avatar = []) | |
19 … | +//var message_meta = plugs.map(exports.message_meta = []) | |
20 … | +// | |
21 … | +exports.create = function (api) { | |
22 … | + return function (content, cb) { | |
17 | 23 … | |
18 | - var lb = lightbox() | |
19 | - document.body.appendChild(lb) | |
24 … | + cb = cb || function () {} | |
20 | 25 … | |
21 | - var msg = { | |
22 | - key: "DRAFT", | |
23 | - value: { | |
24 | - author: self_id, | |
25 | - previous: null, | |
26 | - sequence: null, | |
27 | - timestamp: Date.now(), | |
28 | - content: content | |
26 … | + var lb = lightbox() | |
27 … | + document.body.appendChild(lb) | |
28 … | + | |
29 … | + var msg = { | |
30 … | + key: "DRAFT", | |
31 … | + value: { | |
32 … | + author: self_id, | |
33 … | + previous: null, | |
34 … | + sequence: null, | |
35 … | + timestamp: Date.now(), | |
36 … | + content: content | |
37 … | + } | |
29 | 38 … | } |
30 | - } | |
31 | 39 … | |
32 | - var okay = h('button', 'okay', {onclick: function () { | |
33 | - lb.remove() | |
34 | - publish(content, cb) | |
35 | - }}) | |
40 … | + var okay = h('button', 'okay', {onclick: function () { | |
41 … | + lb.remove() | |
42 … | + api.publish(content, cb) | |
43 … | + }}) | |
36 | 44 … | |
37 | - var cancel = h('button', 'Cancel', {onclick: function () { | |
38 | - lb.remove() | |
39 | - cb(null) | |
40 | - }}) | |
45 … | + var cancel = h('button', 'Cancel', {onclick: function () { | |
46 … | + lb.remove() | |
47 … | + cb(null) | |
48 … | + }}) | |
41 | 49 … | |
42 | - okay.addEventListener('keydown', function (ev) { | |
43 | - if(ev.keyCode === 27) cancel.click() //escape | |
44 | - }) | |
50 … | + okay.addEventListener('keydown', function (ev) { | |
51 … | + if(ev.keyCode === 27) cancel.click() //escape | |
52 … | + }) | |
45 | 53 … | |
46 | - lb.show(h('div.column.message-confirm', | |
47 | - h('div.message', | |
48 | - h('div.title.row', | |
49 | - h('div.avatar', avatar(msg.value.author, 'thumbnail')), | |
50 | - h('div.message_meta.row', message_meta(msg)) | |
54 … | + lb.show(h('div.column.message-confirm', | |
55 … | + h('div.message', | |
56 … | + h('div.title.row', | |
57 … | + h('div.avatar', api.avatar(msg.value.author, 'thumbnail')), | |
58 … | + h('div.message_meta.row', api.message_meta(msg)) | |
59 … | + ), | |
60 … | + h('div.message_content', api.message_content(msg) | |
61 … | + || h('pre', JSON.stringify(msg, null, 2))) | |
51 | 62 … | ), |
52 | - h('div.message_content', message_content(msg) | |
53 | - || h('pre', JSON.stringify(msg, null, 2))) | |
54 | - ), | |
55 | - h('div.row.message-confirm__controls', okay, cancel) | |
56 | - )) | |
63 … | + h('div.row.message-confirm__controls', okay, cancel) | |
64 … | + )) | |
57 | 65 … | |
58 | - okay.focus() | |
59 | - | |
66 … | + okay.focus() | |
67 … | + } | |
60 | 68 … | } |
61 | 69 … |
modules_core/sbot.js | ||
---|---|---|
@@ -30,128 +30,160 @@ | ||
30 | 30 … | var createFeed = require('ssb-feed') |
31 | 31 … | var keys = require('../keys') |
32 | 32 … | var ssbKeys = require('ssb-keys') |
33 | 33 … | |
34 | - | |
35 | 34 … | var cache = CACHE = {} |
36 | 35 … | |
37 | -var opts = createConfig() | |
38 | -var sbot = null | |
39 | -var connection_status = [] | |
36 … | +module.exports = { | |
37 … | + needs: { | |
38 … | + connection_status: 'map' | |
39 … | + }, | |
40 … | + gives: { | |
41 … | +// connection_status: true, | |
42 … | + sbot_blobs_add: true, | |
43 … | + sbot_links: true, | |
44 … | + sbot_links2: true, | |
45 … | + sbot_query: true, | |
46 … | + sbot_get: true, | |
47 … | + sbot_log: true, | |
48 … | + sbot_user_feed: true, | |
49 … | + sbot_gossip_peers: true, | |
50 … | + sbot_gossip_connect: true, | |
51 … | + sbot_progress: true, | |
52 … | + sbot_publish: true, | |
53 … | + sbot_whoami: true | |
54 … | + }, | |
40 | 55 … | |
41 | -var rec = Reconnect(function (isConn) { | |
42 | - function notify (value) { | |
43 | - console.log('connection_status', value, connection_status) | |
44 | - isConn(value); connection_status.forEach(function (fn) { fn(value) }) | |
45 | - } | |
56 … | +//module.exports = { | |
57 … | + create: function (api) { | |
46 | 58 … | |
47 | - createClient(keys, { | |
48 | - manifest: require('../manifest.json'), | |
49 | - remote: require('../config')().remote | |
50 | - }, function (err, _sbot) { | |
51 | - if(err) | |
52 | - return notify(err) | |
59 … | + var opts = createConfig() | |
60 … | + var sbot = null | |
61 … | + var connection_status = [] | |
53 | 62 … | |
54 | - sbot = _sbot | |
55 | - sbot.on('closed', function () { | |
56 | - sbot = null | |
57 | - notify(new Error('closed')) | |
58 | - }) | |
63 … | + var rec = Reconnect(function (isConn) { | |
64 … | + function notify (value) { | |
65 … | + isConn(value); api.connection_status(value) //.forEach(function (fn) { fn(value) }) | |
66 … | + } | |
59 | 67 … | |
60 | - notify() | |
61 | - }) | |
62 | -}) | |
68 … | + createClient(keys, { | |
69 … | + manifest: require('../manifest.json'), | |
70 … | + remote: require('../config')().remote | |
71 … | + }, function (err, _sbot) { | |
72 … | + if(err) | |
73 … | + return notify(err) | |
63 | 74 … | |
64 | -var internal = { | |
65 | - getLatest: rec.async(function (id, cb) { | |
66 | - sbot.getLatest(id, cb) | |
67 | - }), | |
68 | - add: rec.async(function (msg, cb) { | |
69 | - sbot.add(msg, cb) | |
70 | - }) | |
71 | -} | |
75 … | + sbot = _sbot | |
76 … | + sbot.on('closed', function () { | |
77 … | + sbot = null | |
78 … | + notify(new Error('closed')) | |
79 … | + }) | |
72 | 80 … | |
73 | -var feed = createFeed(internal, keys, {remote: true}) | |
81 … | + notify() | |
82 … | + }) | |
83 … | + }) | |
74 | 84 … | |
75 | -module.exports = { | |
76 | - connection_status: connection_status, | |
77 | - sbot_blobs_add: rec.sink(function (cb) { | |
78 | - return pull( | |
79 | - Hash(function (err, id) { | |
80 | - if(err) return cb(err) | |
81 | - //completely UGLY hack to tell when the blob has been sucessfully written... | |
82 | - var start = Date.now(), n = 5 | |
83 | - ;(function next () { | |
84 | - setTimeout(function () { | |
85 | - sbot.blobs.has(id, function (err, has) { | |
86 | - if(has) return cb(null, id) | |
87 | - if(n--) next() | |
88 | - else cb(new Error('write failed')) | |
89 | - }) | |
90 | - }, Date.now() - start) | |
91 | - })() | |
85 … | + var internal = { | |
86 … | + getLatest: rec.async(function (id, cb) { | |
87 … | + sbot.getLatest(id, cb) | |
92 | 88 … | }), |
93 | - sbot.blobs.add() | |
94 | - ) | |
95 | - }), | |
96 | - sbot_links: rec.source(function (query) { | |
97 | - return sbot.links(query) | |
98 | - }), | |
99 | - sbot_links2: rec.source(function (query) { | |
100 | - return sbot.links2.read(query) | |
101 | - }), | |
102 | - sbot_query: rec.source(function (query) { | |
103 | - return sbot.query.read(query) | |
104 | - }), | |
105 | - sbot_log: rec.source(function (opts) { | |
106 | - return pull( | |
107 | - sbot.createLogStream(opts), | |
108 | - pull.through(function (e) { | |
109 | - CACHE[e.key] = CACHE[e.key] || e.value | |
89 … | + add: rec.async(function (msg, cb) { | |
90 … | + sbot.add(msg, cb) | |
110 | 91 … | }) |
111 | - ) | |
112 | - }), | |
113 | - sbot_user_feed: rec.source(function (opts) { | |
114 | - return sbot.createUserStream(opts) | |
115 | - }), | |
116 | - sbot_get: rec.async(function (key, cb) { | |
117 | - if(CACHE[key]) cb(null, CACHE[key]) | |
118 | - else sbot.get(key, function (err, value) { | |
119 | - if(err) return cb(err) | |
120 | - cb(null, CACHE[key] = value) | |
121 | - }) | |
122 | - }), | |
123 | - sbot_gossip_peers: rec.async(function (cb) { | |
124 | - sbot.gossip.peers(cb) | |
125 | - }), | |
126 | - //liteclient won't have permissions for this | |
127 | - sbot_gossip_connect: rec.async(function (opts, cb) { | |
128 | - sbot.gossip.connect(opts, cb) | |
129 | - }), | |
130 | - sbot_progress: rec.source(function () { | |
131 | - return sbot.replicate.changes() | |
132 | - }), | |
133 | - sbot_publish: rec.async(function (content, cb) { | |
134 | - if(content.recps) | |
135 | - content = ssbKeys.box(content, content.recps.map(function (e) { | |
136 | - return ref.isFeed(e) ? e : e.link | |
137 | - })) | |
138 | - else if(content.mentions) | |
139 | - content.mentions.forEach(function (mention) { | |
140 | - if(ref.isBlob(mention.link)) { | |
141 | - sbot.blobs.push(mention.link, function (err) { | |
142 | - if(err) console.error(err) | |
92 … | + } | |
93 … | + | |
94 … | + var feed = createFeed(internal, keys, {remote: true}) | |
95 … | + | |
96 … | + return { | |
97 … | + connection_status: connection_status, | |
98 … | + sbot_blobs_add: rec.sink(function (cb) { | |
99 … | + return pull( | |
100 … | + Hash(function (err, id) { | |
101 … | + if(err) return cb(err) | |
102 … | + //completely UGLY hack to tell when the blob has been sucessfully written... | |
103 … | + var start = Date.now(), n = 5 | |
104 … | + ;(function next () { | |
105 … | + setTimeout(function () { | |
106 … | + sbot.blobs.has(id, function (err, has) { | |
107 … | + if(has) return cb(null, id) | |
108 … | + if(n--) next() | |
109 … | + else cb(new Error('write failed')) | |
110 … | + }) | |
111 … | + }, Date.now() - start) | |
112 … | + })() | |
113 … | + }), | |
114 … | + sbot.blobs.add() | |
115 … | + ) | |
116 … | + }), | |
117 … | + sbot_links: rec.source(function (query) { | |
118 … | + return sbot.links(query) | |
119 … | + }), | |
120 … | + sbot_links2: rec.source(function (query) { | |
121 … | + return sbot.links2.read(query) | |
122 … | + }), | |
123 … | + sbot_query: rec.source(function (query) { | |
124 … | + return sbot.query.read(query) | |
125 … | + }), | |
126 … | + sbot_log: rec.source(function (opts) { | |
127 … | + return pull( | |
128 … | + sbot.createLogStream(opts), | |
129 … | + pull.through(function (e) { | |
130 … | + CACHE[e.key] = CACHE[e.key] || e.value | |
143 | 131 … | }) |
144 | - } | |
132 … | + ) | |
133 … | + }), | |
134 … | + sbot_user_feed: rec.source(function (opts) { | |
135 … | + return sbot.createUserStream(opts) | |
136 … | + }), | |
137 … | + sbot_get: rec.async(function (key, cb) { | |
138 … | + if('function' !== typeof cb) | |
139 … | + throw new Error('cb must be function') | |
140 … | + if(CACHE[key]) cb(null, CACHE[key]) | |
141 … | + else sbot.get(key, function (err, value) { | |
142 … | + if(err) return cb(err) | |
143 … | + cb(null, CACHE[key] = value) | |
144 … | + }) | |
145 … | + }), | |
146 … | + sbot_gossip_peers: rec.async(function (cb) { | |
147 … | + sbot.gossip.peers(cb) | |
148 … | + }), | |
149 … | + //liteclient won't have permissions for this | |
150 … | + sbot_gossip_connect: rec.async(function (opts, cb) { | |
151 … | + sbot.gossip.connect(opts, cb) | |
152 … | + }), | |
153 … | + sbot_progress: rec.source(function () { | |
154 … | + return sbot.replicate.changes() | |
155 … | + }), | |
156 … | + sbot_publish: rec.async(function (content, cb) { | |
157 … | + if(content.recps) | |
158 … | + content = ssbKeys.box(content, content.recps.map(function (e) { | |
159 … | + return ref.isFeed(e) ? e : e.link | |
160 … | + })) | |
161 … | + else if(content.mentions) | |
162 … | + content.mentions.forEach(function (mention) { | |
163 … | + if(ref.isBlob(mention.link)) { | |
164 … | + sbot.blobs.push(mention.link, function (err) { | |
165 … | + if(err) console.error(err) | |
166 … | + }) | |
167 … | + } | |
168 … | + }) | |
169 … | + | |
170 … | + feed.add(content, function (err, msg) { | |
171 … | + if(err) console.error(err) | |
172 … | + else if(!cb) console.log(msg) | |
173 … | + cb && cb(err, msg) | |
174 … | + }) | |
175 … | + }), | |
176 … | + sbot_whoami: rec.async(function (cb) { | |
177 … | + sbot.whoami(cb) | |
145 | 178 … | }) |
146 | - | |
147 | - feed.add(content, function (err, msg) { | |
148 | - if(err) console.error(err) | |
149 | - else if(!cb) console.log(msg) | |
150 | - cb && cb(err, msg) | |
151 | - }) | |
152 | - }), | |
153 | - sbot_whoami: rec.async(function (cb) { | |
154 | - sbot.whoami(cb) | |
155 | - }) | |
179 … | + } | |
180 … | + } | |
156 | 181 … | } |
157 | 182 … | |
183 … | + | |
184 … | + | |
185 … | + | |
186 … | + | |
187 … | + | |
188 … | + | |
189 … | + |
modules_core/tabs.js | ||
---|---|---|
@@ -10,214 +10,210 @@ | ||
10 | 10 … | if(el.tagName !== 'A') return ancestor(el.parentElement) |
11 | 11 … | return el |
12 | 12 … | } |
13 | 13 … | |
14 | -var plugs = require('../plugs') | |
15 | -var screen_view = plugs.first(exports._screen_view = []) | |
16 | -var search_box = plugs.first(exports.search_box = []) | |
17 | -var menu = plugs.first(exports.menu = []) | |
14 … | +//var plugs = require('../plugs') | |
15 … | +//var screen_view = plugs.first(exports._screen_view = []) | |
16 … | +//var search_box = plugs.first(exports.search_box = []) | |
17 … | +//var menu = plugs.first(exports.menu = []) | |
18 | 18 … | |
19 | -exports.message_render = [] | |
19 … | +exports.needs = {screen_view: 'first', search_box: 'first', menu: 'first'} | |
20 | 20 … | |
21 | -exports.screen_view = function (path) { | |
22 | - if(path !== 'tabs') | |
23 | - return | |
21 … | +exports.gives = 'screen_view' | |
24 | 22 … | |
25 | - function setSelected (indexes) { | |
26 | - var ids = indexes.map(function (index) { | |
27 | - return tabs.get(index).id | |
28 | - }) | |
29 | - if(ids.length > 1) | |
30 | - search.value = 'split('+ids.join(',')+')' | |
31 | - else | |
32 | - search.value = ids[0] | |
33 | - } | |
23 … | +exports.create = function (api) { | |
24 … | + return function (path) { | |
25 … | + if(path !== 'tabs') | |
26 … | + return | |
34 | 27 … | |
35 | - var search | |
36 | - var tabs = Tabs(setSelected) | |
37 | - | |
38 | - search = search_box(function (path, change) { | |
39 | - | |
40 | - if(tabs.has(path)) { | |
41 | - tabs.select(path) | |
42 | - return true | |
28 … | + function setSelected (indexes) { | |
29 … | + var ids = indexes.map(function (index) { | |
30 … | + return tabs.get(index).id | |
31 … | + }) | |
32 … | + if(search) | |
33 … | + if(ids.length > 1) | |
34 … | + search.value = 'split('+ids.join(',')+')' | |
35 … | + else | |
36 … | + search.value = ids[0] | |
43 | 37 … | } |
44 | - var el = screen_view(path) | |
45 | 38 … | |
46 | - if(el) { | |
47 | - if(!el.title) el.title = path | |
48 | - el.scroll = keyscroll(el.querySelector('.scroller__content')) | |
49 | - tabs.add(el, change) | |
50 | -// localStorage.openTabs = JSON.stringify(tabs.tabs) | |
51 | - return change | |
52 | - } | |
53 | - }) | |
39 … | + var search | |
40 … | + var tabs = Tabs(setSelected) | |
54 | 41 … | |
55 | - //reposition hypertabs menu to inside a container... | |
56 | - tabs.insertBefore(h('div.header.row', | |
57 | - h('div.header__tabs.row', tabs.firstChild), //tabs | |
58 | - h('div.header__search.row.end', h('div', search), menu()) | |
59 | - ), tabs.firstChild) | |
60 | -// tabs.insertBefore(search, tabs.firstChild.nextSibling) | |
42 … | + search = api.search_box(function (path, change) { | |
61 | 43 … | |
62 | - var saved = [] | |
63 | -// try { saved = JSON.parse(localStorage.openTabs) } | |
64 | -// catch (_) { } | |
44 … | + if(tabs.has(path)) { | |
45 … | + tabs.select(path) | |
46 … | + return true | |
47 … | + } | |
48 … | + var el = api.screen_view(path) | |
65 | 49 … | |
66 | - if(!saved || saved.length < 3) | |
67 | - saved = ['/public', '/private', '/notifications'] | |
50 … | + if(el) { | |
51 … | + if(!el.title) el.title = path | |
52 … | + el.scroll = keyscroll(el.querySelector('.scroller__content')) | |
53 … | + tabs.add(el, change) | |
54 … | + // localStorage.openTabs = JSON.stringify(tabs.tabs) | |
55 … | + return change | |
56 … | + } | |
57 … | + }) | |
68 | 58 … | |
69 | - saved.forEach(function (path) { | |
70 | - var el = screen_view(path) | |
71 | - if(!el) return | |
72 | - el.id = el.id || path | |
73 | - if (!el) return | |
74 | - el.scroll = keyscroll(el.querySelector('.scroller__content')) | |
75 | - if(el) tabs.add(el, false, false) | |
76 | - }) | |
59 … | + //reposition hypertabs menu to inside a container... | |
60 … | + tabs.insertBefore(h('div.header.row', | |
61 … | + h('div.header__tabs.row', tabs.firstChild), //tabs | |
62 … | + h('div.header__search.row.end', h('div', search), api.menu()) | |
63 … | + ), tabs.firstChild) | |
64 … | + // tabs.insertBefore(search, tabs.firstChild.nextSibling) | |
77 | 65 … | |
78 | - tabs.select(0) | |
66 … | + var saved = [] | |
67 … | + // try { saved = JSON.parse(localStorage.openTabs) } | |
68 … | + // catch (_) { } | |
79 | 69 … | |
80 | - //handle link clicks | |
81 | - window.onclick = function (ev) { | |
82 | - var link = ancestor(ev.target) | |
83 | - if(!link) return | |
84 | - var path = link.hash.substring(1) | |
70 … | + if(!saved || saved.length < 3) | |
71 … | + saved = ['/public', '/private', '/notifications', '/data'] | |
85 | 72 … | |
86 | - ev.preventDefault() | |
87 | - ev.stopPropagation() | |
88 | - | |
89 | - //let the application handle this link | |
90 | - if (link.getAttribute('href') === '#') return | |
91 | - | |
92 | - //open external links. | |
93 | - //this ought to be made into something more runcible | |
94 | - if(open.isExternal(link.href)) return open(link.href) | |
95 | - | |
96 | - if(tabs.has(path)) | |
97 | - return tabs.select(path, !ev.ctrlKey, !!ev.shiftKey) | |
98 | - | |
99 | - var el = screen_view(path) | |
100 | - if(el) { | |
73 … | + saved.forEach(function (path) { | |
74 … | + var el = api.screen_view(path) | |
75 … | + if(!el) return | |
101 | 76 … | el.id = el.id || path |
77 … | + if (!el) return | |
102 | 78 … | el.scroll = keyscroll(el.querySelector('.scroller__content')) |
103 | - tabs.add(el, !ev.ctrlKey, !!ev.shiftKey) | |
104 | -// localStorage.openTabs = JSON.stringify(tabs.tabs) | |
105 | - } | |
79 … | + if(el) tabs.add(el, false, false) | |
80 … | + }) | |
106 | 81 … | |
107 | - return false | |
108 | - } | |
82 … | + tabs.select(0) | |
109 | 83 … | |
110 | - window.addEventListener('keydown', function (ev) { | |
111 | - if (ev.target.nodeName === 'INPUT' || ev.target.nodeName === 'TEXTAREA') | |
112 | - return | |
113 | - switch(ev.keyCode) { | |
84 … | + //handle link clicks | |
85 … | + window.onclick = function (ev) { | |
86 … | + var link = ancestor(ev.target) | |
87 … | + if(!link) return | |
88 … | + var path = link.hash.substring(1) | |
114 | 89 … | |
115 | - // scroll through tabs | |
116 | - case 72: // h | |
117 | - return tabs.selectRelative(-1) | |
118 | - case 76: // l | |
119 | - return tabs.selectRelative(1) | |
90 … | + ev.preventDefault() | |
91 … | + ev.stopPropagation() | |
120 | 92 … | |
121 | - // scroll through messages | |
122 | - case 74: // j | |
123 | - return tabs.get(tabs.selected[0]).scroll(1) | |
124 | - case 75: // k | |
125 | - return tabs.get(tabs.selected[0]).scroll(-1) | |
93 … | + //let the application handle this link | |
94 … | + if (link.getAttribute('href') === '#') return | |
126 | 95 … | |
127 | - // close a tab | |
128 | - case 88: // x | |
129 | - if (tabs.selected) { | |
130 | - var sel = tabs.selected | |
131 | - var i = sel.reduce(function (a, b) { return Math.min(a, b) }) | |
132 | - tabs.remove(sel) | |
133 | - tabs.select(Math.max(i-1, 0)) | |
134 | - } | |
135 | - return | |
96 … | + //open external links. | |
97 … | + //this ought to be made into something more runcible | |
98 … | + if(open.isExternal(link.href)) return open(link.href) | |
136 | 99 … | |
137 | - // activate the search field | |
138 | - case 191: // / | |
139 | - if (ev.shiftKey) | |
140 | - search.activate('?', ev) | |
141 | - else | |
142 | - search.activate('/', ev) | |
143 | - return | |
100 … | + if(tabs.has(path)) | |
101 … | + return tabs.select(path, !ev.ctrlKey, !!ev.shiftKey) | |
144 | 102 … | |
145 | - // navigate to a feed | |
146 | - case 50: // 2 | |
147 | - if (ev.shiftKey) | |
148 | - search.activate('@', ev) | |
149 | - return | |
103 … | + var el = api.screen_view(path) | |
104 … | + if(el) { | |
105 … | + el.id = el.id || path | |
106 … | + el.scroll = keyscroll(el.querySelector('.scroller__content')) | |
107 … | + tabs.add(el, !ev.ctrlKey, !!ev.shiftKey) | |
108 … | + // localStorage.openTabs = JSON.stringify(tabs.tabs) | |
109 … | + } | |
150 | 110 … | |
151 | - // navigate to a channel | |
152 | - case 51: // 3 | |
153 | - if (ev.shiftKey) | |
154 | - search.activate('#', ev) | |
155 | - return | |
111 … | + return false | |
112 … | + } | |
156 | 113 … | |
157 | - // navigate to a message | |
158 | - case 53: // 5 | |
159 | - if (ev.shiftKey) | |
160 | - search.activate('%', ev) | |
114 … | + window.addEventListener('keydown', function (ev) { | |
115 … | + if (ev.target.nodeName === 'INPUT' || ev.target.nodeName === 'TEXTAREA') | |
161 | 116 … | return |
162 | - } | |
163 | - }) | |
117 … | + switch(ev.keyCode) { | |
164 | 118 … | |
165 | - // errors tab | |
166 | - var errorsContent = h('div.column.scroller__content') | |
167 | - var errors = h('div.column.scroller', { | |
168 | - id: 'errors', | |
169 | - style: {'overflow':'auto'} | |
170 | - }, h('div.scroller__wrapper', | |
171 | - errorsContent | |
172 | - ) | |
173 | - ) | |
119 … | + // scroll through tabs | |
120 … | + case 72: // h | |
121 … | + return tabs.selectRelative(-1) | |
122 … | + case 76: // l | |
123 … | + return tabs.selectRelative(1) | |
174 | 124 … | |
175 | - // remove loader error handler | |
176 | - if (window.onError) { | |
177 | - window.removeEventListener('error', window.onError) | |
178 | - delete window.onError | |
179 | - } | |
125 … | + // scroll through messages | |
126 … | + case 74: // j | |
127 … | + return tabs.get(tabs.selected[0]).scroll(1) | |
128 … | + case 75: // k | |
129 … | + return tabs.get(tabs.selected[0]).scroll(-1) | |
180 | 130 … | |
181 | - // put errors in a tab | |
182 | - window.addEventListener('error', function (ev) { | |
183 | - var err = ev.error || ev | |
184 | - if(!tabs.has('errors')) | |
185 | - tabs.add(errors, false) | |
186 | - var el = h('div.message', | |
187 | - h('strong', err.message), | |
188 | - h('pre', err.stack)) | |
189 | - if (errorsContent.firstChild) | |
190 | - errorsContent.insertBefore(el, errorsContent.firstChild) | |
191 | - else | |
192 | - errorsContent.appendChild(el) | |
193 | - }) | |
131 … | + // close a tab | |
132 … | + case 88: // x | |
133 … | + if (tabs.selected) { | |
134 … | + var sel = tabs.selected | |
135 … | + var i = sel.reduce(function (a, b) { return Math.min(a, b) }) | |
136 … | + tabs.remove(sel) | |
137 … | + tabs.select(Math.max(i-1, 0)) | |
138 … | + } | |
139 … | + return | |
194 | 140 … | |
195 | - if (process.versions.electron) { | |
196 | - window.addEventListener('contextmenu', function (ev) { | |
197 | - ev.preventDefault() | |
198 | - var remote = require('electron').remote | |
199 | - var Menu = remote.Menu | |
200 | - var MenuItem = remote.MenuItem | |
201 | - var menu = new Menu() | |
202 | - menu.append(new MenuItem({ | |
203 | - label: 'Inspect Element', | |
204 | - click: function () { | |
205 | - remote.getCurrentWindow().inspectElement(ev.x, ev.y) | |
206 | - } | |
207 | - })) | |
208 | - menu.popup(remote.getCurrentWindow()) | |
209 | - }) | |
210 | - } | |
141 … | + // activate the search field | |
142 … | + case 191: // / | |
143 … | + if (ev.shiftKey) | |
144 … | + search.activate('?', ev) | |
145 … | + else | |
146 … | + search.activate('/', ev) | |
147 … | + return | |
211 | 148 … | |
212 | - return tabs | |
213 | -} | |
149 … | + // navigate to a feed | |
150 … | + case 50: // 2 | |
151 … | + if (ev.shiftKey) | |
152 … | + search.activate('@', ev) | |
153 … | + return | |
214 | 154 … | |
155 … | + // navigate to a channel | |
156 … | + case 51: // 3 | |
157 … | + if (ev.shiftKey) | |
158 … | + search.activate('#', ev) | |
159 … | + return | |
215 | 160 … | |
161 … | + // navigate to a message | |
162 … | + case 53: // 5 | |
163 … | + if (ev.shiftKey) | |
164 … | + search.activate('%', ev) | |
165 … | + return | |
166 … | + } | |
167 … | + }) | |
216 | 168 … | |
169 … | + // errors tab | |
170 … | + var errorsContent = h('div.column.scroller__content') | |
171 … | + var errors = h('div.column.scroller', { | |
172 … | + id: 'errors', | |
173 … | + style: {'overflow':'auto'} | |
174 … | + }, h('div.scroller__wrapper', | |
175 … | + errorsContent | |
176 … | + ) | |
177 … | + ) | |
217 | 178 … | |
179 … | + // remove loader error handler | |
180 … | + if (window.onError) { | |
181 … | + window.removeEventListener('error', window.onError) | |
182 … | + delete window.onError | |
183 … | + } | |
218 | 184 … | |
185 … | + // put errors in a tab | |
186 … | + window.addEventListener('error', function (ev) { | |
187 … | + var err = ev.error || ev | |
188 … | + if(!tabs.has('errors')) | |
189 … | + tabs.add(errors, false) | |
190 … | + var el = h('div.message', | |
191 … | + h('strong', err.message), | |
192 … | + h('pre', err.stack)) | |
193 … | + if (errorsContent.firstChild) | |
194 … | + errorsContent.insertBefore(el, errorsContent.firstChild) | |
195 … | + else | |
196 … | + errorsContent.appendChild(el) | |
197 … | + }) | |
219 | 198 … | |
199 … | + if (process.versions.electron) { | |
200 … | + window.addEventListener('contextmenu', function (ev) { | |
201 … | + ev.preventDefault() | |
202 … | + var remote = require('electron').remote | |
203 … | + var Menu = remote.Menu | |
204 … | + var MenuItem = remote.MenuItem | |
205 … | + var menu = new Menu() | |
206 … | + menu.append(new MenuItem({ | |
207 … | + label: 'Inspect Element', | |
208 … | + click: function () { | |
209 … | + remote.getCurrentWindow().inspectElement(ev.x, ev.y) | |
210 … | + } | |
211 … | + })) | |
212 … | + menu.popup(remote.getCurrentWindow()) | |
213 … | + }) | |
214 … | + } | |
220 | 215 … | |
216 … | + return tabs | |
217 … | + } | |
221 | 218 … | |
222 | - | |
223 | - | |
219 … | +} |
modules_extra/audio-mp3.js | ||
---|---|---|
@@ -4,25 +4,36 @@ | ||
4 | 4 … | var ref = require('ssb-ref'); |
5 | 5 … | |
6 | 6 … | //render a message |
7 | 7 … | |
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 … | +} | |
13 | 20 … | |
14 | -exports.message_content = function(msg, sbot) { | |
21 … | +exports.gives = 'message_content' | |
22 … | + | |
23 … | +exports.create = function (api) { | |
24 … | + | |
25 … | + return function(msg) { | |
15 | 26 … | if (msg.value.content.type !== 'audio-mp3') |
16 | 27 … | return; |
17 | 28 … | |
18 | 29 … | var v = msg.value.content; |
19 | 30 … | return h('div', |
20 | 31 … | h('h2', "(" + v.Track + ") " + v.Title), |
21 | - // h('img', { "src" : blob_url(v.cover) }), | |
32 … | + // h('img', { "src" : api.blob_url(v.cover) }), | |
22 | 33 … | h('audio', { |
23 | 34 … | "controls" : true, |
24 | - "src" : blob_url(v.link) | |
35 … | + "src" : api.blob_url(v.link) | |
25 | 36 … | })) |
26 | 37 … | // h('dl', |
27 | 38 … | // Object.keys(v).map(function(k) { |
28 | 39 … | // return [ |
@@ -45,7 +56,7 @@ | ||
45 | 56 … | |
46 | 57 … | // "Title": "clouds", |
47 | 58 … | // "Track": "2", |
48 | 59 … | // "Width": "0", |
49 | - | |
60 … | + } | |
50 | 61 … | } |
51 | 62 … |
modules_extra/blob.js | ||
---|---|---|
@@ -1,23 +1,27 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var ref = require('ssb-ref') |
3 | 3 … | |
4 | -var plugs = require('../plugs') | |
5 | -var blob_url = plugs.first(exports.blob_url = []) | |
4 … | +exports.gives = 'screen_view' | |
6 | 5 … | |
7 | -exports.screen_view = function (path) { | |
8 | - if(ref.isBlob(path)) return blob_view(path) | |
6 … | +exports.needs = { | |
7 … | + blob_url: 'first' | |
9 | 8 … | } |
10 | 9 … | |
11 | -function blob_view(id) { | |
12 | - return h('iframe', { | |
13 | - src: blob_url(id), | |
14 | - sandbox: '', | |
15 | - style: { | |
16 | - position: 'absolute', | |
17 | - width: '100%', | |
18 | - height: '100%', | |
19 | - border: 0, | |
20 | - } | |
21 | - }) | |
10 … | +exports.create = function (api) { | |
11 … | + return function (path) { | |
12 … | + if(ref.isBlob(path)) return blob_view(path) | |
13 … | + } | |
14 … | + | |
15 … | + function blob_view(id) { | |
16 … | + return h('iframe', { | |
17 … | + src: api.blob_url(id), | |
18 … | + sandbox: '', | |
19 … | + style: { | |
20 … | + position: 'absolute', | |
21 … | + width: '100%', | |
22 … | + height: '100%', | |
23 … | + border: 0, | |
24 … | + } | |
25 … | + }) | |
26 … | + } | |
22 | 27 … | } |
23 | - |
modules_extra/channel.js | ||
---|---|---|
@@ -1,104 +1,123 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | 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 | -var sbot_query = plugs.first(exports.sbot_query = []) | |
11 | 5 … | var mfr = require('map-filter-reduce') |
12 | 6 … | |
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', | |
17 | 18 … | } |
18 | 19 … | |
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 … | +} | |
22 | 24 … | |
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) { | |
31 | 26 … | |
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 | |
37 | 28 … | |
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 … | + }} | |
43 | 35 … | |
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) | |
50 | 45 … | |
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 … | + ) | |
54 | 54 … | |
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 … | + } | |
56 | 60 … | |
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 … | + ) | |
63 | 66 … | |
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 … | + ) | |
66 | 73 … | |
67 | - channels = [] | |
74 … | + return div | |
75 … | + } | |
76 … | + }, | |
68 | 77 … | |
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 | |
76 | 80 … | |
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 = [] | |
90 | 82 … | |
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 … | + } | |
102 | 120 … | } |
103 | - })) | |
121 … | + } | |
104 | 122 … | } |
123 … | + |
modules_extra/dns.js | ||
---|---|---|
@@ -7,22 +7,27 @@ | ||
7 | 7 … | function idLink(id) { |
8 | 8 … | return h('a', {href: '#'+id}, id.substring(0, 10)+'…') |
9 | 9 … | } |
10 | 10 … | |
11 | -exports.message_content = function (msg, sbot) { | |
12 | - var c = msg.value.content | |
11 … | +exports.gives = 'message_content' | |
13 | 12 … | |
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 … | + } | |
27 | 31 … | } |
32 … | + | |
28 | 33 … | } |
modules_extra/emoji.js | ||
---|---|---|
@@ -1,14 +1,22 @@ | ||
1 | 1 … | var emojis = require('emoji-named-characters') |
2 | 2 … | var emojiNames = Object.keys(emojis) |
3 | 3 … | |
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 … | +// | |
6 | 7 … | |
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 … | + } | |
9 | 21 … | } |
10 | 22 … | |
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.js | ||
---|---|---|
@@ -2,40 +2,53 @@ | ||
2 | 2 … | var u = require('../util') |
3 | 3 … | var pull = require('pull-stream') |
4 | 4 … | var Scroller = require('pull-scroll') |
5 | 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 = []) | |
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 | 10 … | |
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' | |
13 | 15 … | } |
14 | 16 … | |
15 | -exports.screen_view = function (path, sbot) { | |
16 | - if(path === '/git-ssb') { | |
17 … | +exports.gives = { | |
18 … | + menu_items: true, screen_view: true | |
19 … | +} | |
17 | 20 … | |
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 … | + }, | |
23 | 26 … | |
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') { | |
28 | 29 … | |
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 … | + ) | |
37 | 35 … | |
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 … | + } | |
39 | 53 … | } |
40 | 54 … | } |
41 | - |
modules_extra/git.js | ||
---|---|---|
@@ -1,491 +1,519 @@ | ||
1 … | +'use strict' | |
1 | 2 … | var h = require('hyperscript') |
2 | 3 … | var pull = require('pull-stream') |
3 | 4 … | var paramap = require('pull-paramap') |
4 | 5 … | var cat = require('pull-cat') |
5 | 6 … | var human = require('human-time') |
6 | 7 … | var combobox = require('hypercombo') |
7 | 8 … | |
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 = []) | |
15 | 9 … | var getAvatar = require('ssb-avatar') |
16 | -var avatar_name = plugs.first(exports.avatar_name = []) | |
17 | -var markdown = plugs.first(exports.markdown = []) | |
18 | 10 … | var KVGraph = require('kvgraph') |
19 | 11 … | var mergeRepo = require('ssb-git/merge') |
20 | 12 … | |
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 = []) | |
22 | 22 … | |
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' | |
25 | 32 … | } |
26 | 33 … | |
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 | |
59 | 38 … | } |
60 | 39 … | |
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 | -} | |
76 | 40 … | |
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 | |
87 | 42 … | |
88 | -function repoLink(id) { | |
89 | - return h('a', {href: '#'+id}, repoText(id)) | |
43 … | +function shortRefName(ref) { | |
44 … | + return ref.replace(/^refs\/(heads|tags)\//, '') | |
90 | 45 … | } |
91 | 46 … | |
92 | -function repoName(id) { | |
93 | - return h('ins', repoText(id)) | |
94 | -} | |
47 … | +exports.create = function (api) { | |
95 | 48 … | |
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 | |
214 | 52 … | pull( |
215 | - sbot_links({ | |
53 … | + api.sbot_links({ | |
216 | 54 … | reverse: true, |
55 … | + // source: msg.value.author, | |
217 | 56 … | dest: msg.key, |
218 | - rel: 'project', | |
57 … | + rel: 'repo', | |
219 | 58 … | values: true |
220 | 59 … | }), |
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 | - }), | |
228 | 60 … | 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 … | + } | |
243 | 64 … | }, 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 | |
245 | 69 … | }) |
246 | 70 … | ) |
247 | 71 … | |
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 … | + } | |
257 | 95 … | }) |
258 | 96 … | ) |
97 … | + } | |
259 | 98 … | |
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 | |
261 | 108 … | } |
262 | 109 … | |
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)) | |
294 | 112 … | } |
295 | 113 … | |
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)) | |
301 | 116 … | } |
302 | 117 … | |
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 … | + }) | |
308 | 135 … | ) |
309 | 136 … | } |
310 | 137 … | |
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 … | + ) | |
318 | 196 … | ) |
197 … | + return form | |
319 | 198 … | } |
320 | -} | |
321 | 199 … | |
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 … | + })) | |
330 | 219 … | }) |
331 | - return el | |
332 | 220 … | } |
333 | -} | |
334 | 221 … | |
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 … | + ]) | |
340 | 233 … | } |
341 | -} | |
342 | 234 … | |
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 ', api.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 … | + ) | |
358 | 291 … | ) |
359 | - ) | |
360 | - return form | |
361 | -} | |
292 … | + return form | |
293 … | + } | |
362 | 294 … | |
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}, api.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 | |
379 | 409 … | } |
380 | - return h('option', {value: branch}, label) | |
381 | - })) | |
382 | - }) | |
383 | -} | |
384 | 410 … | |
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 … | + } | |
397 | 443 … | |
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 … | + api.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() | |
415 | 501 … | }) |
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 | |
452 | 514 … | } |
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' | |
487 | 515 … | } |
488 | - return a | |
489 | 516 … | } |
490 | 517 … | } |
491 | 518 … | |
519 … | + |
modules_extra/meta-image.js | ||
---|---|---|
@@ -4,22 +4,26 @@ | ||
4 | 4 … | var ref = require('ssb-ref'); |
5 | 5 … | |
6 | 6 … | //render a message |
7 | 7 … | |
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' | |
13 | 16 … | |
14 | -exports.message_content = function(msg, sbot) { | |
17 … | +exports.create = function (api) { | |
18 … | + return function(msg, sbot) { | |
15 | 19 … | if (msg.value.content.type !== 'meta-image') |
16 | 20 … | return; |
17 | 21 … | |
18 | 22 … | var v = msg.value.content; |
19 | 23 … | return h('div', |
20 | 24 … | // h('h2', "(" + v.Track + ") " + v.Title), |
21 | - h('img', { "src" : blob_url(v.link) })) | |
25 … | + h('img', { "src" : api.blob_url(v.link) })) | |
22 | 26 … | |
23 | 27 … | // h('dl', |
24 | 28 … | // Object.keys(v).map(function(k) { |
25 | 29 … | // return [ |
@@ -43,6 +47,6 @@ | ||
43 | 47 … | // "Title": "clouds", |
44 | 48 … | // "Track": "2", |
45 | 49 … | // "Width": "0", |
46 | 50 … | |
51 … | + } | |
47 | 52 … | } |
48 | - |
modules_extra/music-release-cc.js | ||
---|---|---|
@@ -4,36 +4,42 @@ | ||
4 | 4 … | var ref = require('ssb-ref'); |
5 | 5 … | |
6 | 6 … | //render a message |
7 | 7 … | |
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 … | +// | |
13 | 14 … | |
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' | |
17 | 17 … | |
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 … | + } | |
36 | 42 … | } |
37 | 43 … | |
38 | 44 … | // copied from like.js |
39 | 45 … | |
@@ -77,4 +83,5 @@ | ||
77 | 83 … | // }}, 'yup') |
78 | 84 … | |
79 | 85 … | // } |
80 | 86 … | |
87 … | + |
modules_extra/music-release.js | ||
---|---|---|
@@ -4,38 +4,43 @@ | ||
4 | 4 … | var ref = require('ssb-ref'); |
5 | 5 … | |
6 | 6 … | //render a message |
7 | 7 … | |
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' | |
12 | 14 … | |
13 | -exports.message_content = function(msg, sbot) { | |
14 | - if (msg.value.content.type !== 'music-release') | |
15 | - return; | |
15 … | +exports.create = function () { | |
16 | 16 … | |
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; | |
23 | 20 … | |
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", | |
26 | 27 … | |
27 | - h("dt", "Identifier"), | |
28 | - h("dd", v.Identifier), | |
28 … | + h("dt", "Creator"), | |
29 … | + h("dd", v.Creator), | |
29 | 30 … | |
30 | - h("dt", "Published"), | |
31 | - h("dd", v.Publicdate), | |
31 … | + h("dt", "Identifier"), | |
32 … | + h("dd", v.Identifier), | |
32 | 33 … | |
33 | - h("dt", "Runtime"), | |
34 | - h("dd", v.Runtime), | |
34 … | + h("dt", "Published"), | |
35 … | + h("dd", v.Publicdate), | |
35 | 36 … | |
36 | - h("dt", "Source"), | |
37 | - h("dd", v.Source), | |
37 … | + h("dt", "Runtime"), | |
38 … | + h("dd", v.Runtime), | |
38 | 39 … | |
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 … | + } | |
41 | 46 … | } |
modules_extra/network.js | ||
---|---|---|
@@ -1,11 +1,23 @@ | ||
1 | 1 … | var isVisible = require('is-visible').isVisible |
2 | 2 … | var h = require('hyperscript') |
3 | -var plugs = require('../plugs') | |
4 | 3 … | |
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 … | + | |
8 | 20 … | //sbot_gossip_connect |
9 | 21 … | //sbot_gossip_add |
10 | 22 … | |
11 | 23 … | var human = require('human-time') |
@@ -13,16 +25,8 @@ | ||
13 | 25 … | function legacyToMultiServer(addr) { |
14 | 26 … | return 'net:'+addr.host + ':'+addr.port + '~shs:'+addr.key.substring(1).replace('.ed25519','') |
15 | 27 … | } |
16 | 28 … | |
17 | -exports.menu_items = function () { | |
18 | - return h('a', {href: '#/network'}, '/network') | |
19 | -} | |
20 | - | |
21 | -exports.builtin_tabs = function () { | |
22 | - return ['/network'] | |
23 | -} | |
24 | - | |
25 | 29 … | //types of peers |
26 | 30 … | |
27 | 31 … | |
28 | 32 … | //on the same wifi network |
@@ -64,8 +68,12 @@ | ||
64 | 68 … | : 'other' //should never happen |
65 | 69 … | ) |
66 | 70 … | } |
67 | 71 … | |
72 … | +function origin (e) { | |
73 … | + return e.source === 'local' ? 0 : 1 | |
74 … | +} | |
75 … | + | |
68 | 76 … | var states = { |
69 | 77 … | connected: 3, |
70 | 78 … | connecting: 2 |
71 | 79 … | } |
@@ -91,62 +99,78 @@ | ||
91 | 99 … | else |
92 | 100 … | return round(s)+'ms' |
93 | 101 … | } |
94 | 102 … | |
95 | -exports.screen_view = function (path) { | |
96 | 103 … | |
97 | - if(path !== '/network') return | |
98 | 104 … | |
99 | - var ol = h('ul.network') | |
105 … | +exports.create = function (api) { | |
100 | 106 … | |
101 | - ;(function poll () { | |
107 … | + return { | |
108 … | + menu_items: function () { | |
109 … | + return h('a', {href: '#/network'}, '/network') | |
110 … | + }, | |
102 | 111 … | |
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) | |
112 … | + builtin_tabs: function () { | |
113 … | + return ['/network'] | |
114 … | + }, | |
107 | 115 … | |
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 | - }) | |
116 … | + screen_view: function (path) { | |
143 | 117 … | |
144 | - setTimeout(poll, 5000) | |
145 | - }) | |
118 … | + if(path !== '/network') return | |
146 | 119 … | |
147 | - })() | |
120 … | + var ol = h('ul.network') | |
148 | 121 … | |
149 | - return h('div.column.scroll-y', ol) | |
122 … | + ;(function poll () { | |
123 … | + | |
124 … | + //if this tab isn't open, don't update. | |
125 … | + //todo: make a better way to do this... | |
126 … | + if(!isVisible(ol)) | |
127 … | + return setTimeout(poll, 1000) | |
128 … | + | |
129 … | + api.sbot_gossip_peers(function (err, list) { | |
130 … | + ol.innerHTML = '' | |
131 … | + list.sort(function (a, b) { | |
132 … | + return ( | |
133 … | + (states[b.state] || 0) - (states[a.state] || 0) | |
134 … | + || origin(b) - origin(a) | |
135 … | + || types[getType(b)] - types[getType(a)] | |
136 … | + || b.stateChange - a.stateChange | |
137 … | + ) | |
138 … | + }).forEach(function (peer) { | |
139 … | + ol.appendChild(h('div', | |
140 … | + api.avatar(peer.key, 'thumbnail'), | |
141 … | + h('div', | |
142 … | + peer.state || 'not connected', | |
143 … | + ' ', | |
144 … | + getType(peer), | |
145 … | + ' ', | |
146 … | + //TODO: show nicer details, with labels. etc. | |
147 … | + (peer.ping && peer.ping.rtt) ? duration(peer.ping.rtt.mean) : '', | |
148 … | + ' ', | |
149 … | + (peer.ping && peer.ping.skew) ? duration(peer.ping.skew.mean) : '', | |
150 … | + h('label', | |
151 … | + {title: new Date(peer.stateChange).toString()}, | |
152 … | + peer.stateChange && ('(' + human(new Date(peer.stateChange))) + ')') | |
153 … | + ), | |
154 … | + 'source:'+peer.source, | |
155 … | + h('pre', legacyToMultiServer(peer)), | |
156 … | + h('button', 'connect', {onclick: function () { | |
157 … | + api.sbot_gossip_connect(peer, function (err) { | |
158 … | + if(err) console.error(err) | |
159 … | + else console.log('connected to', peer) | |
160 … | + }) | |
161 … | + }}) | |
162 … | + ) | |
163 … | + ) | |
164 … | + }) | |
165 … | + | |
166 … | + setTimeout(poll, 5000) | |
167 … | + }) | |
168 … | + | |
169 … | + })() | |
170 … | + | |
171 … | + return h('div.column.scroll-y', ol) | |
172 … | + } | |
173 … | + } | |
150 | 174 … | } |
151 | 175 … | |
152 | 176 … |
modules_extra/notifications.js | ||
---|---|---|
@@ -1,4 +1,5 @@ | ||
1 … | +'use strict' | |
1 | 2 … | var h = require('hyperscript') |
2 | 3 … | var u = require('../util') |
3 | 4 … | var pull = require('pull-stream') |
4 | 5 … | var Scroller = require('pull-scroll') |
@@ -6,150 +7,164 @@ | ||
6 | 7 … | var plugs = require('../plugs') |
7 | 8 … | var cont = require('cont') |
8 | 9 … | var ref = require('ssb-ref') |
9 | 10 … | |
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 = []) | |
15 | 16 … | |
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' | |
24 | 23 … | } |
25 | 24 … | |
26 | -exports.builtin_tabs = function () { | |
27 | - return ['/notifications'] | |
25 … | + | |
26 … | +exports.gives = { | |
27 … | + builtin_tabs: true, | |
28 … | + screen_view: true | |
28 | 29 … | } |
29 | 30 … | |
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 … | + ) | |
34 | 40 … | } |
35 | 41 … | |
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) { | |
48 | 43 … | |
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 … | + } | |
59 | 47 … | |
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 … | + api.sbot_get(id, function (err, msg) { | |
53 … | + if (err && err.name == 'NotFoundError') cb(null, false) | |
54 … | + else if (err) cb(err) | |
55 … | + else if (msg.content.type === 'issue' || msg.content.type === 'pull-request') | |
56 … | + isOurMsg(msg.content.repo || msg.content.project, cb) | |
57 … | + else cb(err, msg.author in ourIds) | |
58 … | + }) | |
59 … | + } | |
64 | 60 … | |
65 | - if (c.mentions && Array.isArray(c.mentions) && c.mentions.some(linksToUs)) | |
66 | - return cb(null, msg) | |
61 … | + function isAnyOurMessage(msg, ids, cb) { | |
62 … | + cont.para(ids.map(function (id) { | |
63 … | + return function (cb) { isOurMsg(id, cb) } | |
64 … | + })) | |
65 … | + (function (err, results) { | |
66 … | + if (err) cb(err) | |
67 … | + else if (results.some(Boolean)) cb(null, msg) | |
68 … | + else cb() | |
69 … | + }) | |
70 … | + } | |
67 | 71 … | |
68 | - if (msg.private) | |
69 | - return cb(null, msg) | |
72 … | + return paramap(function (msg, cb) { | |
73 … | + var c = msg.value && msg.value.content | |
74 … | + if (!c || typeof c !== 'object') return cb() | |
75 … | + if (msg.value.author in ourIds) return cb() | |
70 | 76 … | |
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() | |
77 … | + if (c.mentions && Array.isArray(c.mentions) && c.mentions.some(linksToUs)) | |
78 … | + return cb(null, msg) | |
76 | 79 … | |
77 | - case 'contact': | |
78 | - return cb(null, c.contact in ourIds ? msg : null) | |
80 … | + if (msg.private) | |
81 … | + return cb(null, msg) | |
79 | 82 … | |
80 | - case 'vote': | |
81 | - if (c.vote && c.vote.link) | |
82 | - return isOurMsg(c.vote.link, function (err, isOurs) { | |
83 | - cb(err, isOurs ? msg : null) | |
84 | - }) | |
83 … | + switch (c.type) { | |
84 … | + case 'post': | |
85 … | + if (c.branch || c.root) | |
86 … | + return isAnyOurMessage(msg, [].concat(c.branch, c.root), cb) | |
85 | 87 … | else return cb() |
86 | 88 … | |
87 | - case 'issue': | |
88 | - case 'pull-request': | |
89 | - return isOurMsg(c.project || c.repo, function (err, isOurs) { | |
90 | - cb(err, isOurs ? msg : null) | |
91 | - }) | |
89 … | + case 'contact': | |
90 … | + return cb(null, c.contact in ourIds ? msg : null) | |
92 | 91 … | |
93 | - case 'issue-edit': | |
94 | - return isAnyOurMessage(msg, [c.issue].concat(c.issues), cb) | |
92 … | + case 'vote': | |
93 … | + if (c.vote && c.vote.link) | |
94 … | + return isOurMsg(c.vote.link, function (err, isOurs) { | |
95 … | + cb(err, isOurs ? msg : null) | |
96 … | + }) | |
97 … | + else return cb() | |
95 | 98 … | |
96 | - default: | |
97 | - cb() | |
98 | - } | |
99 | - }, 4) | |
100 | -} | |
99 … | + case 'issue': | |
100 … | + case 'pull-request': | |
101 … | + return isOurMsg(c.project || c.repo, function (err, isOurs) { | |
102 … | + cb(err, isOurs ? msg : null) | |
103 … | + }) | |
101 | 104 … | |
102 | -function getFirstMessage(feedId, cb) { | |
103 | - sbot_user_feed({id: feedId, gte: 0, limit: 1})(null, cb) | |
104 | -} | |
105 … | + case 'issue-edit': | |
106 … | + return isAnyOurMessage(msg, [c.issue].concat(c.issues), cb) | |
105 | 107 … | |
106 | -exports.screen_view = function (path) { | |
107 | - if(path === '/notifications') { | |
108 | - var ids = {} | |
109 | - var oldest | |
110 | - | |
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 | |
108 … | + default: | |
109 … | + cb() | |
117 | 110 … | } |
118 | - }) | |
111 … | + }, 4) | |
112 … | + } | |
119 | 113 … | |
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 | - ) | |
114 … | + function getFirstMessage(feedId, cb) { | |
115 … | + api.sbot_user_feed({id: feedId, gte: 0, limit: 1})(null, cb) | |
116 … | + } | |
127 | 117 … | |
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 | - ) | |
118 … | + return { | |
119 … | + builtin_tabs: function () { | |
120 … | + return ['/notifications'] | |
121 … | + }, | |
135 | 122 … | |
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 | - ) | |
123 … | + screen_view: function (path) { | |
124 … | + if(path === '/notifications') { | |
125 … | + var ids = {} | |
126 … | + var oldest | |
147 | 127 … | |
148 | - return div | |
149 | - } | |
150 | -} | |
128 … | + var id = require('../keys').id | |
129 … | + ids[id] = true | |
130 … | + getFirstMessage(id, function (err, msg) { | |
131 … | + if (err) return console.error(err) | |
132 … | + if (!oldest || msg.value.timestamp < oldest) { | |
133 … | + oldest = msg.value.timestamp | |
134 … | + } | |
135 … | + }) | |
151 | 136 … | |
137 … | + var content = h('div.column.scroller__content') | |
138 … | + var div = h('div.column.scroller', | |
139 … | + {style: {'overflow':'auto'}}, | |
140 … | + h('div.scroller__wrapper', | |
141 … | + content | |
142 … | + ) | |
143 … | + ) | |
152 | 144 … | |
145 … | + pull( | |
146 … | + u.next(api.sbot_log, {old: false, limit: 100}), | |
147 … | + unbox(), | |
148 … | + notifications(ids), | |
149 … | + pull.filter(), | |
150 … | + Scroller(div, content, api.message_render, true, false) | |
151 … | + ) | |
153 | 152 … | |
153 … | + pull( | |
154 … | + u.next(api.sbot_log, {reverse: true, limit: 100, live: false}), | |
155 … | + unbox(), | |
156 … | + notifications(ids), | |
157 … | + pull.filter(), | |
158 … | + pull.take(function (msg) { | |
159 … | + // abort stream after we pass the oldest messages of our feeds | |
160 … | + return !oldest ? true : msg.value.timestamp > oldest | |
161 … | + }), | |
162 … | + Scroller(div, content, api.message_render, false, false) | |
163 … | + ) | |
154 | 164 … | |
165 … | + return div | |
166 … | + } | |
167 … | + } | |
168 … | + } | |
169 … | +} | |
155 | 170 … |
modules_extra/query.js | ||
---|---|---|
@@ -1,60 +1,66 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | var pull = require('pull-stream') |
3 | 3 … | var HJSON = require('hjson') |
4 | 4 … | |
5 | -var sbot_query = require('../plugs').first(exports.sbot_query = []) | |
5 … | +//var sbot_query = require('../plugs').first(exports.sbot_query = []) | |
6 | 6 … | |
7 | -exports.menu_items = function () { | |
8 | - return h('a', {href:'#/query'}, '/query') | |
9 | -} | |
7 … | +exports.needs = { sbot_query: 'first' } | |
10 | 8 … | |
11 | -exports.builtin_tabs = function () { | |
12 | - return ['/query'] | |
9 … | +exports.gives = { | |
10 … | + menu_items: true, | |
11 … | + builtin_tabs: true, | |
12 … | + screen_view: true | |
13 | 13 … | } |
14 | 14 … | |
15 | -exports.screen_view = function (path) { | |
16 | - if(path != '/query') return | |
17 | - var output, status, editor, stream, query | |
15 … | +exports.create = function (api) { | |
18 | 16 … | |
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 … | + }, | |
27 | 21 … | |
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 | |
31 | 42 … | |
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() | |
36 | 47 … | |
37 | - console.log(query) | |
48 … | + console.log(query) | |
38 | 49 … | |
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;'}) | |
48 | 63 … | ) |
49 | - }}), | |
50 | - status = h('div.query__status'), | |
51 | - output = h('div.column.query__output', {style: 'overflow-y: scroll;'}) | |
52 | - ) | |
64 … | + } | |
65 … | + } | |
53 | 66 … | } |
54 | - | |
55 | - | |
56 | - | |
57 | - | |
58 | - | |
59 | - | |
60 | - |
modules_extra/raw.js | ||
---|---|---|
@@ -3,50 +3,53 @@ | ||
3 | 3 … | var pull = require('pull-stream') |
4 | 4 … | var Scroller = require('pull-scroll') |
5 | 5 … | |
6 | 6 … | 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 = []) | |
9 | 9 … | |
10 | 10 … | // from ssb-ref |
11 | 11 … | var refRegex = /((?:@|%|&)[A-Za-z0-9\/+]{43}=\.[\w\d]+)/g |
12 | 12 … | |
13 | -exports.linkify = function (text) { | |
13 … | +exports.gives = 'message_meta' | |
14 … | + | |
15 … | +function linkify (text) { | |
14 | 16 … | var arr = text.split(refRegex) |
15 | 17 … | for (var i = 1; i < arr.length; i += 2) { |
16 | 18 … | arr[i] = h('a', {href: '#' + arr[i]}, arr[i]) |
17 | 19 … | } |
18 | 20 … | return arr |
19 | 21 … | } |
20 | 22 … | |
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 … | + } | |
47 | 51 … | } |
48 | - } | |
49 | - }) | |
52 … | + }) | |
53 … | + } | |
50 | 54 … | } |
51 | 55 … | |
52 | - |
modules_extra/search.js | ||
---|---|---|
@@ -3,11 +3,19 @@ | ||
3 | 3 … | var pull = require('pull-stream') |
4 | 4 … | var Scroller = require('pull-scroll') |
5 | 5 … | var TextNodeSearcher = require('text-node-searcher') |
6 | 6 … | |
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 … | + | |
10 | 18 … | var whitespace = /\s+/ |
11 | 19 … | |
12 | 20 … | function andSearch(terms, inputs) { |
13 | 21 … | for(var i = 0; i < terms.length; i++) { |
@@ -45,61 +53,56 @@ | ||
45 | 53 … | searcher.highlight() |
46 | 54 … | return el |
47 | 55 … | } |
48 | 56 … | |
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) { | |
53 | 58 … | |
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) | |
55 | 63 … | |
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 … | + ) | |
63 | 74 … | ) |
64 | - ) | |
65 | 75 … | |
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 … | + } | |
73 | 83 … | |
74 | 84 … | |
75 | 85 … | |
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 … | + } | |
81 | 91 … | |
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 … | + ) | |
87 | 97 … | |
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 … | + ) | |
93 | 103 … | |
94 | - return div | |
104 … | + return div | |
105 … | + } | |
95 | 106 … | } |
107 … | + | |
96 | 108 … | } |
97 | - | |
98 | - | |
99 | - | |
100 | - | |
101 | - | |
102 | - | |
103 | - | |
104 | - | |
105 | - |
modules_extra/split.js | ||
---|---|---|
@@ -1,17 +1,27 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | |
3 | -var screen_view = | |
4 | - require('../plugs').first(exports._screen_view = []) | |
3 … | +//var screen_view = | |
4 … | +// require('../plugs').first(exports._screen_view = []) | |
5 | 5 … | |
6 | -exports.screen_view = function (path) { | |
7 | - var m = /^split\s*\((.*)\)$/.exec(path) | |
8 | - if(!m) | |
9 | - return | |
10 | 6 … | |
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' | |
16 | 9 … | } |
17 | 10 … | |
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.js | ||
---|---|---|
@@ -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 = []) | |
4 | 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 + ':' | |
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 … | + })) | |
17 | 29 … | } |
18 | - })) | |
30 … | + } | |
31 … | + | |
19 | 32 … | } |
modules_extra/versions.js | ||
---|---|---|
@@ -1,40 +1,50 @@ | ||
1 | 1 … | var h = require('hyperscript') |
2 | 2 … | |
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 | |
5 | 7 … | } |
6 | 8 … | |
7 | -exports.builtin_tabs = function () { | |
8 | - return ['/versions'] | |
9 | -} | |
9 … | +exports.create = function () { | |
10 | 10 … | |
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 … | + }, | |
13 | 15 … | |
14 | - if('undefined' === typeof WebBoot) | |
15 | - return h('h1', 'must run with web-boot enabled enviroment') | |
16 … | + builtin_tabs: function () { | |
17 … | + return ['/versions'] | |
18 … | + }, | |
16 | 19 … | |
17 | - var content = h('div.column') | |
20 … | + screen_view: function (path) { | |
21 … | + if(path !== '/versions') return | |
18 | 22 … | |
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') | |
35 | 25 … | |
36 | - }) | |
26 … | + var content = h('div.column') | |
37 | 27 … | |
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 … | + } | |
39 | 50 … | } |
40 | - |
package.json | ||
---|---|---|
@@ -1,26 +1,26 @@ | ||
1 | 1 … | { |
2 | 2 … | "name": "patchbay", |
3 | 3 … | "description": "a pluggable patchwork", |
4 | - "version": "5.5.0", | |
4 … | + "version": "6.0.1", | |
5 | 5 … | "homepage": "https://github.com/dominictarr/patchbay", |
6 | 6 … | "repository": { |
7 | 7 … | "type": "git", |
8 | 8 … | "url": "git://github.com/dominictarr/patchbay.git" |
9 | 9 … | }, |
10 | 10 … | "dependencies": { |
11 | 11 … | "cont": "^1.0.3", |
12 | 12 … | "dataurl-": "^0.1.0", |
13 | - "depject": "^2.0.0", | |
13 … | + "depject": "^3.0.0", | |
14 | 14 … | "hjson": "^2.0.3", |
15 | 15 … | "human-time": "0.0.1", |
16 | 16 … | "hypercombo": "0.1.0", |
17 | 17 … | "hypercrop": "^1.0.1", |
18 | 18 … | "hyperfile": "^1.1.0", |
19 | 19 … | "hyperlightbox": "^0.1.3", |
20 | 20 … | "hyperprogress": "0.1.0", |
21 | 21 … | "hyperscript": "^1.4.7", |
22 | - "hypertabs": "^2.2.0", | |
22 … | + "hypertabs": "^3.0.0", | |
23 | 23 … | "is-visible": "^2.0.4", |
24 | 24 … | "kvgraph": "^0.1.0", |
25 | 25 … | "map-filter-reduce": "^3.0.1", |
26 | 26 … | "mime-types": "^2.1.11", |
@@ -36,10 +36,10 @@ | ||
36 | 36 … | "pull-stream": "^3.4.5", |
37 | 37 … | "scuttlebot": "^8.7.2", |
38 | 38 … | "simple-mime": "^0.1.0", |
39 | 39 … | "split-buffer": "^1.0.0", |
40 … | + "ssb-avatar": "^0.2.0", | |
40 | 41 … | "ssb-blobs": "^0.1.7", |
41 | - "ssb-avatar": "^0.2.0", | |
42 | 42 … | "ssb-client": "^4.0.3", |
43 | 43 … | "ssb-config": "^2.1.1", |
44 | 44 … | "ssb-feed": "^2.2.1", |
45 | 45 … | "ssb-git": "^0.4.1", |
Built with git-ssb-web