Commit 8cf292c13507a00dd6f025dfa662409737ba7dea
rewrite using depject/v2
Dominic Tarr committed on 12/3/2016, 6:00:37 PMParent: 86745d2ae3eb9733681d16c4e9cfabeeef30b588
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 … |
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,122 @@ | ||
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 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(suggest_mentions.map(function (e) { return e(name) })) | |
141 … | + (function (err, ary) { | |
142 … | + cb(null, ary.reduce(function (a, b) { | |
143 … | + return a.concat(b) | |
144 … | + })) | |
145 … | + }) | |
146 … | + }, {}) | |
127 | 147 … | |
128 | - return composer | |
148 … | + return composer | |
129 | 149 … | |
150 … | + } | |
151 … | + | |
130 | 152 … | } |
131 | 153 … | |
132 | - |
modules_basic/feed.js | ||
---|---|---|
@@ -3,54 +3,63 @@ | ||
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 … | + api.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 … | + Scroller(div, content, api.message_render, false, false) | |
57 … | + ) | |
53 | 58 … | |
59 … | + return div | |
54 | 60 … | |
61 … | + } | |
62 … | + } | |
55 | 63 … | |
64 … | +} | |
56 | 65 … |
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,74 @@ | ||
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 … | } |
45 … | + }) | |
46 … | + | |
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 … | + } | |
33 | 56 … | } |
34 | - }) | |
35 | 57 … | |
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 | |
44 | - } | |
58 … | + var suggestions = {} | |
59 … | + | |
60 … | + // delay until the element has a parent | |
61 … | + setTimeout(function () { | |
62 … | + suggestBox = suggest(search, function (word, cb) { | |
63 … | + cont.para(api.suggest_search.map(function (e) { | |
64 … | + return function (cb) { e(word, cb) } | |
65 … | + }))(cb) | |
66 … | + }, {}) | |
67 … | + }, 10) | |
68 … | + | |
69 … | + return search | |
45 | 70 … | } |
46 | 71 … | |
47 | - var suggestions = {} | |
72 … | +} | |
48 | 73 … | |
49 | - // delay until the element has a parent | |
50 | - setTimeout(function () { | |
51 | - suggestBox = suggest(search, suggest_search, {}) | |
52 | - }, 10) | |
53 | 74 … | |
54 | - return search | |
55 | -} |
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,69 @@ | ||
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 … | + bultin_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, cb) { | |
45 … | + if(/^[@%]\w/.test(query)) { | |
46 … | + api.signified(query, function (_, names) { | |
47 … | + cb(null, names.map(function (e) { | |
48 … | + return { | |
49 … | + title: e.name + ':'+e.id.substring(0, 10), | |
50 … | + value: e.id, | |
51 … | + subtitle: e.rank, | |
52 … | + rank: e.rank | |
53 … | + } | |
54 … | + })) | |
55 … | + }) | |
57 | 56 … | |
58 | - | |
59 | - | |
60 | - | |
61 | - | |
62 | - | |
63 | - | |
64 | - | |
65 | - | |
57 … | + } else if(/^\//.test(query)) { | |
58 … | + var tabs = [].concat.apply([], builtin_tabs()) | |
59 … | + cb(null, tabs.filter(function (name) { | |
60 … | + return name.substr(0, query.length) === query | |
61 … | + }).map(function (name) { | |
62 … | + return { | |
63 … | + title: name, | |
64 … | + value: name, | |
65 … | + } | |
66 … | + })) | |
67 … | + } else cb() | |
68 … | + } | |
69 … | + } | |
70 … | +} |
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 ? 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,44 @@ | ||
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, id) { | |
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 … | + }) | |
54 … | + } | |
55 … | + | |
56 … | + return exports | |
57 … | + } | |
47 | 58 … | } |
48 | 59 … |
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,39 @@ | ||
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' | |
11 … | + var status = h('div.status.error') //start off disconnected | |
12 … | + var list = h('div.menu.column', {style: 'display: none;'}) | |
13 … | + | |
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 … | + | |
22 … | + return { | |
23 … | + connection_status: function (err) { | |
24 … | + if(err) status.classList.add('error') | |
25 … | + else status.classList.remove('error') | |
26 … | + }, | |
27 … | + menu: function () { | |
28 … | + menu_items().forEach(function (el) { | |
29 … | + if(el) | |
30 … | + list.appendChild(el) | |
31 … | + }) | |
32 … | + } | |
33 … | + } | |
14 | 34 … | } |
15 | -}) | |
16 | - | |
17 | -exports.connection_status = function (err) { | |
18 | - if(err) status.classList.add('error') | |
19 | - else status.classList.remove('error') | |
20 | 35 … | } |
21 | 36 … | |
22 | -exports.menu = function () { | |
23 | - menu_items().forEach(function (el) { | |
24 | - list.appendChild(el) | |
25 | - }) | |
26 | 37 … | |
27 | - return menu | |
28 | -} | |
29 | 38 … | |
30 | 39 … | |
31 | - |
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,158 @@ | ||
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 … | + console.log('connection_status', value, connection_status) | |
66 … | + isConn(value); api.connection_status(value) //.forEach(function (fn) { fn(value) }) | |
67 … | + } | |
59 | 68 … | |
60 | - notify() | |
61 | - }) | |
62 | -}) | |
69 … | + createClient(keys, { | |
70 … | + manifest: require('../manifest.json'), | |
71 … | + remote: require('../config')().remote | |
72 … | + }, function (err, _sbot) { | |
73 … | + if(err) | |
74 … | + return notify(err) | |
75 … | + console.log("SboT CONNECT", _sbot) | |
63 | 76 … | |
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 | -} | |
77 … | + sbot = _sbot | |
78 … | + sbot.on('closed', function () { | |
79 … | + sbot = null | |
80 … | + notify(new Error('closed')) | |
81 … | + }) | |
72 | 82 … | |
73 | -var feed = createFeed(internal, keys, {remote: true}) | |
83 … | + notify() | |
84 … | + }) | |
85 … | + }) | |
74 | 86 … | |
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 | - })() | |
87 … | + var internal = { | |
88 … | + getLatest: rec.async(function (id, cb) { | |
89 … | + sbot.getLatest(id, cb) | |
92 | 90 … | }), |
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 | |
91 … | + add: rec.async(function (msg, cb) { | |
92 … | + sbot.add(msg, cb) | |
110 | 93 … | }) |
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) | |
94 … | + } | |
95 … | + | |
96 … | + var feed = createFeed(internal, keys, {remote: true}) | |
97 … | + console.log('create SBOT') | |
98 … | + return { | |
99 … | + connection_status: connection_status, | |
100 … | + sbot_blobs_add: rec.sink(function (cb) { | |
101 … | + return pull( | |
102 … | + Hash(function (err, id) { | |
103 … | + if(err) return cb(err) | |
104 … | + //completely UGLY hack to tell when the blob has been sucessfully written... | |
105 … | + var start = Date.now(), n = 5 | |
106 … | + ;(function next () { | |
107 … | + setTimeout(function () { | |
108 … | + sbot.blobs.has(id, function (err, has) { | |
109 … | + if(has) return cb(null, id) | |
110 … | + if(n--) next() | |
111 … | + else cb(new Error('write failed')) | |
112 … | + }) | |
113 … | + }, Date.now() - start) | |
114 … | + })() | |
115 … | + }), | |
116 … | + sbot.blobs.add() | |
117 … | + ) | |
118 … | + }), | |
119 … | + sbot_links: rec.source(function (query) { | |
120 … | + return sbot.links(query) | |
121 … | + }), | |
122 … | + sbot_links2: rec.source(function (query) { | |
123 … | + return sbot.links2.read(query) | |
124 … | + }), | |
125 … | + sbot_query: rec.source(function (query) { | |
126 … | + return sbot.query.read(query) | |
127 … | + }), | |
128 … | + sbot_log: rec.source(function (opts) { | |
129 … | + console.log('sbot_log', opts) | |
130 … | + return pull( | |
131 … | + sbot.createLogStream(opts), | |
132 … | + pull.through(function (e) { | |
133 … | + CACHE[e.key] = CACHE[e.key] || e.value | |
143 | 134 … | }) |
144 | - } | |
135 … | + ) | |
136 … | + }), | |
137 … | + sbot_user_feed: rec.source(function (opts) { | |
138 … | + return sbot.createUserStream(opts) | |
139 … | + }), | |
140 … | + sbot_get: rec.async(function (key, cb) { | |
141 … | + if('function' !== typeof cb) | |
142 … | + throw new Error('cb must be function') | |
143 … | + if(CACHE[key]) cb(null, CACHE[key]) | |
144 … | + else sbot.get(key, function (err, value) { | |
145 … | + if(err) return cb(err) | |
146 … | + cb(null, CACHE[key] = value) | |
147 … | + }) | |
148 … | + }), | |
149 … | + sbot_gossip_peers: rec.async(function (cb) { | |
150 … | + sbot.gossip.peers(cb) | |
151 … | + }), | |
152 … | + //liteclient won't have permissions for this | |
153 … | + sbot_gossip_connect: rec.async(function (opts, cb) { | |
154 … | + sbot.gossip.connect(opts, cb) | |
155 … | + }), | |
156 … | + sbot_progress: rec.source(function () { | |
157 … | + return sbot.replicate.changes() | |
158 … | + }), | |
159 … | + sbot_publish: rec.async(function (content, cb) { | |
160 … | + if(content.recps) | |
161 … | + content = ssbKeys.box(content, content.recps.map(function (e) { | |
162 … | + return ref.isFeed(e) ? e : e.link | |
163 … | + })) | |
164 … | + else if(content.mentions) | |
165 … | + content.mentions.forEach(function (mention) { | |
166 … | + if(ref.isBlob(mention.link)) { | |
167 … | + sbot.blobs.push(mention.link, function (err) { | |
168 … | + if(err) console.error(err) | |
169 … | + }) | |
170 … | + } | |
171 … | + }) | |
172 … | + | |
173 … | + feed.add(content, function (err, msg) { | |
174 … | + if(err) console.error(err) | |
175 … | + else if(!cb) console.log(msg) | |
176 … | + cb && cb(err, msg) | |
177 … | + }) | |
178 … | + }), | |
179 … | + sbot_whoami: rec.async(function (cb) { | |
180 … | + sbot.whoami(cb) | |
145 | 181 … | }) |
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 | - }) | |
182 … | + } | |
183 … | + } | |
156 | 184 … | } |
157 | 185 … | |
186 … | + | |
187 … | + |
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 … | +} |
Built with git-ssb-web