Commit 41ed6a5aa572f6de601bab35fc108a955657c074
Merge pull request #64 from ssbc/about_refactor
A step toward modular CSS (and so more modular components).mix irving authored on 1/4/2017, 9:46:54 PM
GitHub committed on 1/4/2017, 9:46:54 PM
Parent: 5cb4510e7266ce92c57a4468efce4479ec64d714
Parent: 7470f29e565172555b9c2e102a58e88dd52a2d6a
Files changed
.gitignore | changed |
index.js | changed |
modules_basic/about.js | changed |
modules_basic/index.js | changed |
modules_basic/message.js | changed |
modules_basic/post.js | changed |
modules_basic/thread.js | changed |
modules_basic/timestamp.js | changed |
modules_basic/about.mcss | added |
modules_basic/message-author.js | added |
modules_basic/message-author.mcss | added |
modules_basic/message-backlinks.js | added |
modules_basic/message-backlinks.mcss | added |
modules_basic/message.mcss | added |
modules_basic/reply.js | added |
modules_basic/timestamp.mcss | added |
modules_core/app.js | changed |
modules_core/index.js | changed |
modules_core/style-mixins.js | added |
modules_core/styles.js | added |
modules_extra/git.js | changed |
modules_extra/raw.js | changed |
package.json | changed |
scripts/create-index.js | deleted |
scripts/style.js | deleted |
style.css | changed |
h.js | added |
.gitignore | ||
---|---|---|
@@ -2,5 +2,4 @@ | ||
2 | 2 … | npm-debug.log |
3 | 3 … | .npmignore |
4 | 4 … | build |
5 | 5 … | modules/_index.js |
6 | -style.css.json |
index.js | ||
---|---|---|
@@ -1,4 +1,7 @@ | ||
1 … | +// polyfills | |
2 … | +require('setimmediate') | |
3 … | + | |
1 | 4 … | require('depject')( |
2 | 5 … | // from more specialized to more general |
3 | 6 … | require('./modules_extra'), |
4 | 7 … | require('./modules_basic'), |
modules_basic/about.js | ||
---|---|---|
@@ -1,48 +1,100 @@ | ||
1 … | +const fs = require('fs') | |
2 … | +const h = require('../h') | |
3 … | +const when = require('@mmckegg/mutant/when') | |
1 | 4 … | |
2 | -var h = require('hyperscript') | |
3 | - | |
4 | -function idLink (id) { | |
5 | - return h('a', {href:'#'+id}, id) | |
5 … | +exports.needs = { | |
6 … | + blob_url: 'first', | |
7 … | + markdown: 'first' | |
6 | 8 … | } |
7 | 9 … | |
8 | -function asLink (ln) { | |
9 | - return 'string' === typeof ln ? ln : ln.link | |
10 … | +exports.gives = { | |
11 … | + mcss: true, | |
12 … | + message_content: true, | |
13 … | + message_content_mini: true | |
10 | 14 … | } |
11 | 15 … | |
12 | -//var blob_url = require('../plugs').first(exports.blob_url = []) | |
16 … | +exports.create = function (api) { | |
17 … | + return { | |
18 … | + message_content, | |
19 … | + message_content_mini, | |
20 … | + mcss: () => fs.readFileSync(__filename.replace(/js$/, 'mcss'), 'utf8') | |
21 … | + } | |
13 | 22 … | |
14 | -exports.needs = { | |
15 | - blob_url: 'first' | |
16 | -} | |
23 … | + function message_content (msg) { | |
24 … | + if (msg.value.content.type !== 'about') return | |
17 | 25 … | |
18 | -exports.gives = 'message_content' | |
26 … | + var { content: about, author: authorId } = msg.value | |
27 … | + var { about: aboutId, name, image, description } = about | |
19 | 28 … | |
20 | -exports.create = function (api) { | |
29 … | + if (!aboutId) return null | |
21 | 30 … | |
22 | - return function (msg) { | |
23 | - if(msg.value.content.type !== 'about') return | |
31 … | + return h('About', [ | |
32 … | + Name({ aboutId, authorId, name }), | |
33 … | + Image({ aboutId, authorId, image }), | |
34 … | + Description({ aboutId, authorId, description }) | |
35 … | + ]) | |
36 … | + } | |
24 | 37 … | |
25 | - if(!msg.value.content.image && !msg.value.content.name) | |
26 | - return | |
38 … | + function message_content_mini (msg) { | |
39 … | + if (msg.value.content.type !== 'about') return | |
27 | 40 … | |
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 | - ) | |
41 | - ) | |
41 … | + var { content: about, author: authorId } = msg.value | |
42 … | + var { about: aboutId, name, image, description } = about | |
42 | 43 … | |
44 … | + if (!aboutId) return null | |
45 … | + if (image || description) return null | |
46 … | + | |
47 … | + return h('About', Name({ aboutId, authorId, name })) | |
43 | 48 … | } |
44 | 49 … | |
45 | -} | |
46 | 50 … | |
51 … | + function Name ({ aboutId, authorId, name }) { | |
52 … | + if (!name) return null | |
53 … | + return h('section -name', [ | |
54 … | + h('header', when(authorId === aboutId, | |
55 … | + 'self-identifies as', | |
56 … | + ['identifies ', targetLink(aboutId), ' as'] | |
57 … | + )), | |
58 … | + h('section', h( | |
59 … | + 'a -name', | |
60 … | + { href: `#${aboutId}` }, | |
61 … | + name | |
62 … | + )) | |
63 … | + ]) | |
64 … | + } | |
47 | 65 … | |
66 … | + function Image ({ aboutId, authorId, image }) { | |
67 … | + if (!image) return null | |
68 … | + return h('section -image', [ | |
69 … | + h('header', when(authorId === aboutId, | |
70 … | + 'self-portrays as', | |
71 … | + ['portrays ', targetLink(aboutId), ' as'] | |
72 … | + )), | |
73 … | + h('section', h( | |
74 … | + 'a -image', | |
75 … | + { href: `#${aboutId}` }, | |
76 … | + h('img', { src: api.blob_url(image) }) | |
77 … | + )) | |
78 … | + ]) | |
79 … | + } | |
48 | 80 … | |
81 … | + function Description ({ aboutId, authorId, description }) { | |
82 … | + if (!description) return null | |
83 … | + return h('section -description', [ | |
84 … | + h('header', when(authorId === aboutId, | |
85 … | + 'self-describes as', | |
86 … | + ['describes ', targetLink(aboutId), ' as'] | |
87 … | + )), | |
88 … | + h('section', api.markdown(description)) | |
89 … | + ]) | |
90 … | + } | |
91 … | +} | |
92 … | + | |
93 … | +function targetLink (aboutId) { | |
94 … | + const content = aboutId.slice(0, 9) + '...' | |
95 … | + return h( | |
96 … | + 'a -target', | |
97 … | + { href: `#${aboutId}` }, | |
98 … | + content | |
99 … | + ) | |
100 … | +} |
modules_basic/index.js | ||
---|---|---|
@@ -11,8 +11,10 @@ | ||
11 | 11 … | "follow.js": require('./follow.js'), |
12 | 12 … | "invite.js": require('./invite.js'), |
13 | 13 … | "like.js": require('./like.js'), |
14 | 14 … | "markdown.js": require('./markdown.js'), |
15 … | + "message-author.js": require('./message-author.js'), | |
16 … | + "message-backlinks.js": require('./message-backlinks.js'), | |
15 | 17 … | "message-link.js": require('./message-link.js'), |
16 | 18 … | "message-name.js": require('./message-name.js'), |
17 | 19 … | "message.js": require('./message.js'), |
18 | 20 … | "names.js": require('./names.js'), |
@@ -20,8 +22,9 @@ | ||
20 | 22 … | "private.js": require('./private.js'), |
21 | 23 … | "pub.js": require('./pub.js'), |
22 | 24 … | "public.js": require('./public.js'), |
23 | 25 … | "relationships.js": require('./relationships.js'), |
26 … | + "reply.js": require('./reply.js'), | |
24 | 27 … | "search-box.js": require('./search-box.js'), |
25 | 28 … | "setup.js": require('./setup'), |
26 | 29 … | "suggest-mentions.js": require('./suggest-mentions.js'), |
27 | 30 … | "thread.js": require('./thread.js'), |
modules_basic/message.js | |||
---|---|---|---|
@@ -1,122 +1,86 @@ | |||
1 | -var h = require('hyperscript') | ||
2 | -var u = require('../util') | ||
3 | -var pull = require('pull-stream') | ||
1 … | +const fs = require('fs') | ||
2 … | +const pull = require('pull-stream') | ||
3 … | +const u = require('../util') | ||
4 … | +const h = require('../h') | ||
4 | 5 … | ||
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 = []) | ||
18 | - | ||
19 | 6 … | exports.needs = { | |
20 | - message_content: 'first', | ||
21 | - message_content_mini: 'first', | ||
22 | - avatar: 'first', | ||
23 | 7 … | avatar_name: 'first', | |
24 | 8 … | avatar_link: 'first', | |
25 | - message_meta: 'map', | ||
26 | 9 … | message_action: 'map', | |
10 … | + message_author: 'first', | ||
11 … | + message_backlinks: 'first', | ||
12 … | + message_content: 'first', | ||
13 … | + message_content_mini: 'first', | ||
14 … | + message_title: 'first', | ||
27 | 15 … | message_link: 'first', | |
28 | -// sbot_links: 'first' | ||
16 … | + message_meta: 'map', | ||
29 | 17 … | } | |
30 | 18 … | ||
31 | -exports.gives = 'message_render' | ||
32 | - | ||
33 | -function message_content_mini_fallback(msg) { | ||
34 | - return h('code', msg.value.content.type) | ||
19 … | +exports.gives = { | ||
20 … | + message_render: true, | ||
21 … | + mcss: true | ||
35 | 22 … | } | |
36 | 23 … | ||
37 | 24 … | exports.create = function (api) { | |
38 | - | ||
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 | ||
25 … | + return { | ||
26 … | + message_render, | ||
27 … | + mcss: () => fs.readFileSync(__filename.replace(/js$/, 'mcss'), 'utf8') | ||
50 | 28 … | } | |
51 | 29 … | ||
52 | - return function (msg, sbot) { | ||
53 | - var el = api.message_content_mini(msg) | ||
54 | - if(el) return mini(msg, el) | ||
30 … | + function message_render (msg, sbot) { | ||
31 … | + var content = api.message_content_mini(msg) | ||
32 … | + if (content) return mini(msg, content) | ||
55 | 33 … | ||
56 | - var el = api.message_content(msg) | ||
57 | - if(!el) return mini(msg, message_content_mini_fallback(msg)) | ||
34 … | + content = api.message_content(msg) | ||
35 … | + if (!content) return mini(msg, message_content_mini_fallback(msg)) | ||
58 | 36 … | ||
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) | ||
37 … | + return h('Message', { | ||
38 … | + 'ev-keydown': navigateToMessageOnEnter, | ||
39 … | + attributes: { | ||
40 … | + tabindex: '0' | ||
66 | 41 … | } | |
67 | - } | ||
42 … | + }, [ | ||
43 … | + h('header.author', api.message_author(msg)), | ||
44 … | + h('section.title', api.message_title(msg)), | ||
45 … | + h('section.meta', api.message_meta(msg)), | ||
46 … | + h('section.content', content), | ||
47 … | + h('section.action', api.message_action(msg)), | ||
48 … | + h('footer.backlinks', api.message_backlinks(msg)) | ||
49 … | + ]) | ||
68 | 50 … | ||
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 | - )) | ||
51 … | + function navigateToMessageOnEnter (ev) { | ||
52 … | + // on enter, hit first meta. | ||
53 … | + if(ev.keyCode == 13) { | ||
76 | 54 … | ||
55 … | + // unless in an input | ||
56 … | + if (ev.target.nodeName === 'INPUT' | ||
57 … | + || ev.target.nodeName === 'TEXTAREA') return | ||
77 | 58 … | ||
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 | - // ) | ||
59 … | + // HACK! (mw) | ||
60 … | + // there's no exported api to open a new tab. :/ | ||
61 … | + // it's only done in `app.js` module in an`onhashchange` handler. | ||
62 … | + // sooooooo yeah this shit for now :) | ||
63 … | + var wtf = h('a', { href: `#${msg.key}` }) | ||
64 … | + msgEl.appendChild(wtf) | ||
65 … | + wtf.click() | ||
66 … | + } | ||
67 … | + } | ||
68 … | + } | ||
89 | 69 … | ||
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) { | ||
105 | - | ||
106 | - // unless in an input | ||
107 | - if (ev.target.nodeName === 'INPUT' | ||
108 | - || ev.target.nodeName === 'TEXTAREA') return | ||
109 | - | ||
110 | - msg.querySelector('.enter').click() | ||
111 | - } | ||
112 | - }} | ||
113 | - ) | ||
114 | - | ||
115 | - // ); hyperscript does not seem to set attributes correctly. | ||
116 | - msg.setAttribute('tabindex', '0') | ||
117 | - | ||
118 | - return msg | ||
70 … | + function mini(msg, el) { | ||
71 … | + return h('Message -mini', { | ||
72 … | + attributes: { | ||
73 … | + tabindex: '0' | ||
74 … | + } | ||
75 … | + }, [ | ||
76 … | + h('header.author', api.message_author(msg, { size: 'mini' })), | ||
77 … | + h('section.meta', api.message_meta(msg)), | ||
78 … | + h('section.content', el) | ||
79 … | + ]) | ||
119 | 80 … | } | |
120 | 81 … | } | |
121 | 82 … | ||
122 | 83 … | ||
84 … | +function message_content_mini_fallback(msg) { | ||
85 … | + return h('code', msg.value.content.type) | ||
86 … | +} |
modules_basic/post.js | ||
---|---|---|
@@ -11,22 +11,30 @@ | ||
11 | 11 … | // |
12 | 12 … | |
13 | 13 … | exports.needs = { message_link: 'first', markdown: 'first' } |
14 | 14 … | |
15 | -exports.gives = 'message_content' | |
15 … | +exports.gives = { | |
16 … | + message_content: true, | |
17 … | + message_title: true | |
18 … | +} | |
16 | 19 … | |
17 | 20 … | exports.create = function (api) { |
18 | - return function (data) { | |
21 … | + return { | |
22 … | + message_content, | |
23 … | + message_title | |
24 … | + } | |
25 … | + | |
26 … | + function message_content (data) { | |
19 | 27 … | if(!data.value.content || !data.value.content.text) return |
20 | 28 … | |
21 | - var root = data.value.content.root | |
22 | - var re = !root ? null : h('span', 're: ', api.message_link(root)) | |
23 | - | |
24 | 29 … | return h('div', |
25 | - re, | |
26 | 30 … | api.markdown(data.value.content) |
27 | 31 … | ) |
32 … | + } | |
28 | 33 … | |
34 … | + function message_title (data) { | |
35 … | + var root = data.value.content && data.value.content.root | |
36 … | + return !root ? null : h('span', 're: ', api.message_link(root)) | |
29 | 37 … | } |
30 | 38 … | } |
31 | 39 … | |
32 | 40 … |
modules_basic/thread.js | ||
---|---|---|
@@ -120,10 +120,10 @@ | ||
120 | 120 … | meta.root = thread[0].value.content.root || thread[0].key |
121 | 121 … | meta.channel = thread[0].value.content.channel |
122 | 122 … | |
123 | 123 … | var recps = thread[0].value.content.recps |
124 | - var private = thread[0].value.private | |
125 | - if(private) { | |
124 … | + var priv = thread[0].value['private'] | |
125 … | + if(priv) { | |
126 | 126 … | if(recps) |
127 | 127 … | meta.recps = recps |
128 | 128 … | else |
129 | 129 … | meta.recps = [thread[0].value.author, self_id] |
modules_basic/timestamp.js | ||
---|---|---|
@@ -1,28 +1,46 @@ | ||
1 | -var h = require('hyperscript') | |
2 | -var human = require('human-time') | |
1 … | +const fs = require('fs') | |
2 … | +const h = require('../h') | |
3 … | +const human = require('human-time') | |
3 | 4 … | |
4 | 5 … | exports.needs = {} |
5 | 6 … | |
6 | -exports.gives = 'message_meta' | |
7 … | +exports.gives = { | |
8 … | + timestamp: true, | |
9 … | + mcss: true | |
10 … | +} | |
7 | 11 … | |
8 | 12 … | exports.create = function () { |
9 | - | |
10 | - function updateTimestampEl(el) { | |
11 | - el.firstChild.nodeValue = human(new Date(el.timestamp)) | |
12 | - return el | |
13 | - } | |
14 | - | |
15 | 13 … | setInterval(function () { |
16 | - var els = [].slice.call(document.querySelectorAll('.timestamp')) | |
14 … | + var els = [].slice.call(document.querySelectorAll('.Timestamp')) | |
17 | 15 … | els.forEach(updateTimestampEl) |
18 | 16 … | }, 60e3) |
19 | 17 … | |
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 | - }, '')) | |
18 … | + return { | |
19 … | + timestamp, | |
20 … | + mcss: () => fs.readFileSync(__filename.replace(/js$/, 'mcss'), 'utf8') | |
26 | 21 … | } |
27 | 22 … | |
23 … | + function updateTimestampEl (el) { | |
24 … | + var timestamp = Number(el.getAttribute('data-timestamp')) | |
25 … | + var display = human(new Date(timestamp)).replace(/minutes/, 'mins') | |
26 … | + el.querySelector('a').firstChild.nodeValue = display | |
27 … | + return el | |
28 … | + } | |
29 … | + | |
30 … | + function timestamp (msg) { | |
31 … | + var { key, value } = msg | |
32 … | + var { timestamp } = value | |
33 … | + var el = h('Timestamp', { | |
34 … | + attributes: { | |
35 … | + 'data-timestamp': timestamp | |
36 … | + } | |
37 … | + }, [ | |
38 … | + h('a', { | |
39 … | + href: `#${key}`, | |
40 … | + title: new Date(timestamp) | |
41 … | + }, '') | |
42 … | + ]) | |
43 … | + updateTimestampEl(el) | |
44 … | + return el | |
45 … | + } | |
28 | 46 … | } |
modules_basic/about.mcss | ||
---|---|---|
@@ -1,0 +1,53 @@ | ||
1 … | +About { | |
2 … | + display: flex | |
3 … | + flex-wrap: wrap | |
4 … | + | |
5 … | + section { | |
6 … | + header { | |
7 … | + a { | |
8 … | + -target { | |
9 … | + | |
10 … | + } | |
11 … | + -name { | |
12 … | + | |
13 … | + } | |
14 … | + -image { | |
15 … | + | |
16 … | + } | |
17 … | + } | |
18 … | + } | |
19 … | + | |
20 … | + -name { | |
21 … | + display: flex | |
22 … | + | |
23 … | + header { | |
24 … | + | |
25 … | + } | |
26 … | + | |
27 … | + section { | |
28 … | + margin-left: .25rem | |
29 … | + } | |
30 … | + } | |
31 … | + | |
32 … | + -image { | |
33 … | + header { | |
34 … | + | |
35 … | + } | |
36 … | + | |
37 … | + section { | |
38 … | + | |
39 … | + } | |
40 … | + } | |
41 … | + | |
42 … | + -description { | |
43 … | + header { | |
44 … | + | |
45 … | + } | |
46 … | + | |
47 … | + section { | |
48 … | + padding-left: 1em; | |
49 … | + padding-right: 1em; | |
50 … | + } | |
51 … | + } | |
52 … | + } | |
53 … | +} |
modules_basic/message-author.js | ||
---|---|---|
@@ -1,0 +1,39 @@ | ||
1 … | +const fs = require('fs') | |
2 … | +const h = require('../h') | |
3 … | +const when = require('@mmckegg/mutant/when') | |
4 … | + | |
5 … | +exports.needs = { | |
6 … | + avatar_link: 'first', | |
7 … | + avatar_image: 'first', | |
8 … | + avatar_name: 'first', | |
9 … | + timestamp: 'first' | |
10 … | +} | |
11 … | + | |
12 … | +exports.gives = { | |
13 … | + message_author: true, | |
14 … | + mcss: true | |
15 … | +} | |
16 … | + | |
17 … | +exports.create = function (api) { | |
18 … | + return { | |
19 … | + message_author, | |
20 … | + mcss: () => fs.readFileSync(__filename.replace(/js$/, 'mcss'), 'utf8') | |
21 … | + } | |
22 … | + | |
23 … | + function message_author (msg, opts = {}) { | |
24 … | + var { size = 'small' } = opts | |
25 … | + var { value } = msg | |
26 … | + var { author } = value | |
27 … | + | |
28 … | + return h('MessageAuthor', { | |
29 … | + className: `-${size}` | |
30 … | + }, [ | |
31 … | + when(size !== 'mini', | |
32 … | + h('section -image', api.avatar_link(author, api.avatar_image(author, 'thumbnail'))) | |
33 … | + ), | |
34 … | + h('section -name', api.avatar_link(author, api.avatar_name(author))), | |
35 … | + h('section -timestamp', api.timestamp(msg)) | |
36 … | + ]) | |
37 … | + } | |
38 … | +} | |
39 … | + |
modules_basic/message-author.mcss | ||
---|---|---|
@@ -1,0 +1,38 @@ | ||
1 … | +MessageAuthor { | |
2 … | + display: flex | |
3 … | + flex-direction: column | |
4 … | + | |
5 … | + section { | |
6 … | + -image { | |
7 … | + margin-bottom: .3rem | |
8 … | + } | |
9 … | + | |
10 … | + -name { | |
11 … | + max-width: 7rem | |
12 … | + a { $text-primary } | |
13 … | + } | |
14 … | + | |
15 … | + -timestamp { | |
16 … | + | |
17 … | + } | |
18 … | + } | |
19 … | + | |
20 … | + -mini { | |
21 … | + flex-direction: row | |
22 … | + | |
23 … | + section { | |
24 … | + margin-right: .5rem | |
25 … | + | |
26 … | + -name { | |
27 … | + position: initial | |
28 … | + left: initial | |
29 … | + min-width: 6.5rem | |
30 … | + max-width: none | |
31 … | + } | |
32 … | + | |
33 … | + -timestamp { | |
34 … | + | |
35 … | + } | |
36 … | + } | |
37 … | + } | |
38 … | +} |
modules_basic/message-backlinks.js | ||
---|---|---|
@@ -1,0 +1,39 @@ | ||
1 … | +const fs = require('fs') | |
2 … | +const h = require('../h') | |
3 … | + | |
4 … | +exports.gives = { | |
5 … | + message_backlinks: true, | |
6 … | + mcss: true | |
7 … | +} | |
8 … | + | |
9 … | +exports.create = function (api) { | |
10 … | + return { | |
11 … | + message_backlinks, | |
12 … | + mcss: () => fs.readFileSync(__filename.replace(/js$/, 'mcss'), 'utf8') | |
13 … | + } | |
14 … | + | |
15 … | + function message_backlinks (msg) { | |
16 … | + var links = [] | |
17 … | + for(var k in CACHE) { | |
18 … | + var _msg = CACHE[k] | |
19 … | + if(Array.isArray(_msg.content.mentions)) { | |
20 … | + for(var i = 0; i < _msg.content.mentions.length; i++) | |
21 … | + if(_msg.content.mentions[i].link == msg.key) | |
22 … | + links.push(k) | |
23 … | + } | |
24 … | + } | |
25 … | + | |
26 … | + if (links.length === 0) return null | |
27 … | + | |
28 … | + return h('MessageBacklinks', [ | |
29 … | + h('header', 'backlinks:'), | |
30 … | + h('ul', links.map(function (link) { | |
31 … | + return h('li', [ | |
32 … | + h('a -backlink', { | |
33 … | + href: `#${link}` | |
34 … | + }, link) | |
35 … | + ]) | |
36 … | + })) | |
37 … | + ]) | |
38 … | + } | |
39 … | +} |
modules_basic/message-backlinks.mcss | ||
---|---|---|
@@ -1,0 +1,14 @@ | ||
1 … | +MessageBacklinks { | |
2 … | + header { | |
3 … | + | |
4 … | + } | |
5 … | + ul { | |
6 … | + li { | |
7 … | + a { | |
8 … | + -backlink { | |
9 … | + | |
10 … | + } | |
11 … | + } | |
12 … | + } | |
13 … | + } | |
14 … | +} |
modules_basic/message.mcss | ||
---|---|---|
@@ -1,0 +1,80 @@ | ||
1 … | +Message { | |
2 … | + padding: 1rem .5rem 1rem 7.5rem | |
3 … | + border-top: solid 1px gainsboro | |
4 … | + min-height: 5rem | |
5 … | + | |
6 … | + position: relative | |
7 … | + display: flex | |
8 … | + flex-direction: row | |
9 … | + flex-wrap: wrap | |
10 … | + justify-content: flex-end | |
11 … | + | |
12 … | + header.author { | |
13 … | + position: absolute | |
14 … | + left: .5rem | |
15 … | + } | |
16 … | + | |
17 … | + section.title { | |
18 … | + flex-grow: 1 | |
19 … | + font-size: .9rem | |
20 … | + } | |
21 … | + | |
22 … | + section.meta { | |
23 … | + display: flex | |
24 … | + a { | |
25 … | + margin-left: .2rem | |
26 … | + $text-subtle | |
27 … | + } | |
28 … | + | |
29 … | + input{ | |
30 … | + margin-right: 0 | |
31 … | + order: 99 | |
32 … | + } | |
33 … | + } | |
34 … | + | |
35 … | + section.content { | |
36 … | + flex-basis: 100% | |
37 … | + | |
38 … | + (img) { | |
39 … | + max-width: 100% | |
40 … | + } | |
41 … | + } | |
42 … | + | |
43 … | + section.action { | |
44 … | + flex-basis: 100% | |
45 … | + display: flex | |
46 … | + justify-content: flex-end | |
47 … | + | |
48 … | + a { | |
49 … | + margin-left: .5em | |
50 … | + } | |
51 … | + } | |
52 … | + | |
53 … | + footer.backlinks { | |
54 … | + | |
55 … | + } | |
56 … | + | |
57 … | + | |
58 … | + -mini { | |
59 … | + font-size: .9rem | |
60 … | + justify-content: flex-start | |
61 … | + padding: .25rem .5rem | |
62 … | + min-height: inherit | |
63 … | + | |
64 … | + header.author { | |
65 … | + order: 0 | |
66 … | + position: initial | |
67 … | + left: initial | |
68 … | + } | |
69 … | + | |
70 … | + section.content { | |
71 … | + order: 1 | |
72 … | + flex-basis: initial | |
73 … | + flex-grow: 1 | |
74 … | + } | |
75 … | + | |
76 … | + section.meta { | |
77 … | + order: 2 | |
78 … | + } | |
79 … | + } | |
80 … | +} |
modules_basic/reply.js | ||
---|---|---|
@@ -1,0 +1,9 @@ | ||
1 … | +var h = require('../h') | |
2 … | + | |
3 … | +exports.gives = 'message_action' | |
4 … | + | |
5 … | +exports.create = function () { | |
6 … | + return function (msg) { | |
7 … | + return h('a', { href: '#' + msg.key }, 'Reply') | |
8 … | + } | |
9 … | +} |
modules_basic/timestamp.mcss | ||
---|---|---|
@@ -1,0 +1,7 @@ | ||
1 … | +Timestamp { | |
2 … | + a { | |
3 … | + $text-subtle | |
4 … | + font-size: .8rem | |
5 … | + } | |
6 … | +} | |
7 … | + |
modules_core/app.js | ||
---|---|---|
@@ -1,13 +1,19 @@ | ||
1 | 1 … | var plugs = require('../plugs') |
2 | 2 … | var h = require('hyperscript') |
3 … | +var insertCss = require('insert-css') | |
3 | 4 … | |
4 | 5 … | module.exports = { |
5 | - needs: {screen_view: 'first'}, | |
6 … | + needs: { | |
7 … | + screen_view: 'first', | |
8 … | + styles: 'first' | |
9 … | + }, | |
6 | 10 … | gives: 'app', |
7 | 11 … | create: function (api) { |
8 | 12 … | return function () { |
9 | - document.head.appendChild(h('style', require('../style.css.json'))) | |
13 … | + process.nextTick(function () { | |
14 … | + insertCss(api.styles()) | |
15 … | + }) | |
10 | 16 … | |
11 | 17 … | window.addEventListener('error', window.onError = function (e) { |
12 | 18 … | document.body.appendChild(h('div.error', |
13 | 19 … | h('h1', e.message), |
modules_core/index.js | ||
---|---|---|
@@ -6,7 +6,9 @@ | ||
6 | 6 … | "file-input.js": require('./file-input.js'), |
7 | 7 … | "menu.js": require('./menu.js'), |
8 | 8 … | "message-confirm.js": require('./message-confirm.js'), |
9 | 9 … | "tabs.js": require('./tabs.js'), |
10 | - "sbot.js": require('./sbot.js') | |
10 … | + "sbot.js": require('./sbot.js'), | |
11 … | + "style-mixins.js": require('./style-mixins.js'), | |
12 … | + "styles.js": require('./styles.js') | |
11 | 13 … | } |
12 | 14 … |
modules_core/style-mixins.js | ||
---|---|---|
@@ -1,0 +1,22 @@ | ||
1 … | + | |
2 … | +const mixins = ` | |
3 … | + $text-primary { | |
4 … | + color: black | |
5 … | + } | |
6 … | + | |
7 … | + $text-subtle { | |
8 … | + color: gray | |
9 … | + } | |
10 … | +` | |
11 … | + | |
12 … | +module.exports = { | |
13 … | + gives: { | |
14 … | + mcss: true | |
15 … | + }, | |
16 … | + create: function (api) { | |
17 … | + return { | |
18 … | + mcss: () => mixins | |
19 … | + } | |
20 … | + } | |
21 … | +} | |
22 … | + |
modules_core/styles.js | ||
---|---|---|
@@ -1,0 +1,34 @@ | ||
1 … | +var h = require('../h') | |
2 … | +var compile = require('micro-css') | |
3 … | +var fs = require('fs') | |
4 … | +var Path = require('path') | |
5 … | + | |
6 … | +// TODO distribute these styles across all | |
7 … | +// the relevant modules, not as a core style. | |
8 … | +var coreStyle = fs.readFileSync(Path.join(__dirname, '../style.css')) | |
9 … | + | |
10 … | +module.exports = { | |
11 … | + needs: { | |
12 … | + mcss: 'map', | |
13 … | + css: 'map' | |
14 … | + }, | |
15 … | + gives: { | |
16 … | + mcss: true, | |
17 … | + css: true, | |
18 … | + styles: true | |
19 … | + }, | |
20 … | + create: function (api) { | |
21 … | + var styles = '' | |
22 … | + process.nextTick(function () { | |
23 … | + var mcss = api.mcss().join('\n') | |
24 … | + var css = api.css().join('\n') | |
25 … | + styles = coreStyle + compile(mcss) + css | |
26 … | + }) | |
27 … | + return { | |
28 … | + styles: function () { return styles }, | |
29 … | + // export empty styles | |
30 … | + mcss: function () { return '' }, | |
31 … | + css: function () { return '' } | |
32 … | + } | |
33 … | + } | |
34 … | +} |
modules_extra/git.js | ||
---|---|---|
@@ -33,9 +33,10 @@ | ||
33 | 33 … | |
34 | 34 … | exports.gives = { |
35 | 35 … | message_action: true, |
36 | 36 … | message_meta: true, |
37 | - message_content: true | |
37 … | + message_content: true, | |
38 … | + message_title: true | |
38 | 39 … | } |
39 | 40 … | |
40 | 41 … | |
41 | 42 … | var self_id = require('../keys').id |
@@ -301,10 +302,8 @@ | ||
301 | 302 … | if(c.type === 'git-repo') { |
302 | 303 … | var branchesT, tagsT, openIssuesT, closedIssuesT, openPRsT, closedPRsT |
303 | 304 … | var forksT |
304 | 305 … | var div = h('div', |
305 | - h('p', 'git repo ', repoName(msg.key)), | |
306 | - c.upstream ? h('p', 'fork of ', repoLink(c.upstream)) : '', | |
307 | 306 … | h('p', h('code', 'ssb://' + msg.key)), |
308 | 307 … | h('div.git-table-wrapper', {style: {'max-height': '12em'}}, |
309 | 308 … | h('table', |
310 | 309 … | branchesT = tableRows(h('tr', |
@@ -409,9 +408,8 @@ | ||
409 | 408 … | } |
410 | 409 … | |
411 | 410 … | if(c.type === 'git-update') { |
412 | 411 … | return [ |
413 | - h('p', 'pushed to ', repoLink(c.repo)), | |
414 | 412 … | c.refs ? h('ul', Object.keys(c.refs).map(function (ref) { |
415 | 413 … | var rev = c.refs[ref] |
416 | 414 … | return h('li', |
417 | 415 … | shortRefName(ref) + ': ', |
@@ -449,25 +447,54 @@ | ||
449 | 447 … | } |
450 | 448 … | |
451 | 449 … | if(c.type === 'issue') { |
452 | 450 … | return h('div', |
453 | - h('p', 'opened issue on ', repoLink(c.project)), | |
454 | 451 … | c.title ? h('h4', c.title) : '', |
455 | 452 … | api.markdown(c) |
456 | 453 … | ) |
457 | 454 … | } |
458 | 455 … | |
459 | 456 … | if(c.type === 'pull-request') { |
460 | 457 … | return h('div', |
461 | - h('p', 'opened pull-request ', | |
462 | - 'to ', repoLink(c.repo), ':', c.branch, ' ', | |
463 | - 'from ', repoLink(c.head_repo), ':', c.head_branch), | |
464 | 458 … | c.title ? h('h4', c.title) : '', |
465 | 459 … | api.markdown(c) |
466 | 460 … | ) |
467 | 461 … | } |
468 | 462 … | }, |
469 | 463 … | |
464 … | + message_title: function (msg) { | |
465 … | + var c = msg.value.content | |
466 … | + | |
467 … | + if(c.type === 'git-repo') { | |
468 … | + return h('div', [ | |
469 … | + h('p', 'git repo ', repoName(msg.key)), | |
470 … | + c.upstream ? h('p', 'fork of ', repoLink(c.upstream)) : '' | |
471 … | + ]) | |
472 … | + } | |
473 … | + | |
474 … | + if(c.type === 'git-update') { | |
475 … | + return h('p', 'pushed to ', repoLink(c.repo)) | |
476 … | + } | |
477 … | + | |
478 … | + if(c.type === 'issue-edit' || (c.type === 'post' && c.text === '')) { | |
479 … | + return h('div', [ | |
480 … | + c.issue ? renderIssueEdit(c) : null, | |
481 … | + c.issues ? c.issues.map(renderIssueEdit) : null | |
482 … | + ]) | |
483 … | + } | |
484 … | + | |
485 … | + if(c.type === 'issue') { | |
486 … | + return h('p', 'opened issue on ', repoLink(c.project)) | |
487 … | + } | |
488 … | + | |
489 … | + if(c.type === 'pull-request') { | |
490 … | + return h('p', 'opened pull-request ', [ | |
491 … | + 'to ', repoLink(c.repo), ':', c.branch, ' ', | |
492 … | + 'from ', repoLink(c.head_repo), ':', c.head_branch | |
493 … | + ]) | |
494 … | + } | |
495 … | + }, | |
496 … | + | |
470 | 497 … | message_meta: function (msg, sbot) { |
471 | 498 … | var type = msg.value.content.type |
472 | 499 … | if (type === 'issue' || type === 'pull-request') { |
473 | 500 … | var el = h('em', '...') |
@@ -515,5 +542,4 @@ | ||
515 | 542 … | } |
516 | 543 … | } |
517 | 544 … | } |
518 | 545 … | |
519 | - |
modules_extra/raw.js | ||
---|---|---|
@@ -28,10 +28,11 @@ | ||
28 | 28 … | return h('input', { |
29 | 29 … | type: 'checkbox', |
30 | 30 … | title: 'View Data', |
31 | 31 … | onclick: function () { |
32 | - var msgEl = this.parentNode.parentNode.parentNode | |
33 | - var msgContentEl = msgEl.querySelector('.message_content') | |
32 … | + // HACK (mw) yo we need a better way to replace the content | |
33 … | + var msgEl = this.parentNode.parentNode | |
34 … | + var msgContentEl = msgEl.querySelector('.\\.content') | |
34 | 35 … | if (this.checked) { |
35 | 36 … | // move away the content |
36 | 37 … | while (el = msgContentEl.firstChild) |
37 | 38 … | tmp.appendChild(el) |
package.json | ||
---|---|---|
@@ -7,11 +7,14 @@ | ||
7 | 7 … | "type": "git", |
8 | 8 … | "url": "git://github.com/dominictarr/patchbay.git" |
9 | 9 … | }, |
10 | 10 … | "dependencies": { |
11 … | + "@mmckegg/mutant": "^3.10.1", | |
12 … | + "brfs": "^1.4.3", | |
11 | 13 … | "cont": "^1.0.3", |
12 | 14 … | "dataurl-": "^0.1.0", |
13 | 15 … | "depject": "^3.0.0", |
16 … | + "es2040": "^1.2.4", | |
14 | 17 … | "hjson": "^2.0.3", |
15 | 18 … | "human-time": "0.0.1", |
16 | 19 … | "hypercombo": "0.1.0", |
17 | 20 … | "hypercrop": "^1.0.1", |
@@ -19,11 +22,13 @@ | ||
19 | 22 … | "hyperlightbox": "^0.1.3", |
20 | 23 … | "hyperprogress": "0.1.0", |
21 | 24 … | "hyperscript": "^1.4.7", |
22 | 25 … | "hypertabs": "^3.0.0", |
26 … | + "insert-css": "^2.0.0", | |
23 | 27 … | "is-visible": "^2.1.1", |
24 | 28 … | "kvgraph": "^0.1.0", |
25 | 29 … | "map-filter-reduce": "^3.0.1", |
30 … | + "micro-css": "^0.6.2", | |
26 | 31 … | "mime-types": "^2.1.11", |
27 | 32 … | "moment": "^2.13.0", |
28 | 33 … | "open-external": "^0.1.1", |
29 | 34 … | "peaks.js": "^0.4.7", |
@@ -34,8 +39,9 @@ | ||
34 | 39 … | "pull-reconnect": "^0.0.3", |
35 | 40 … | "pull-scroll": "^0.3.3", |
36 | 41 … | "pull-stream": "^3.4.5", |
37 | 42 … | "scuttlebot": "^8.7.2", |
43 … | + "setimmediate": "^1.0.5", | |
38 | 44 … | "simple-mime": "^0.1.0", |
39 | 45 … | "split-buffer": "^1.0.0", |
40 | 46 … | "ssb-avatar": "^0.2.0", |
41 | 47 … | "ssb-blobs": "^0.1.7", |
@@ -60,12 +66,18 @@ | ||
60 | 66 … | "electro": "^2.0.3", |
61 | 67 … | "electron": "^1.4.10", |
62 | 68 … | "indexhtmlify": "^1.3.1" |
63 | 69 … | }, |
70 … | + "browserify": { | |
71 … | + "transform": [ | |
72 … | + "brfs", | |
73 … | + "es2040" | |
74 … | + ] | |
75 … | + }, | |
64 | 76 … | "scripts": { |
65 | - "lite": "node scripts/style.js && mkdir -p build && browserify index.js | indexhtmlify --title patchbay > build/index.html", | |
77 … | + "lite": "mkdir -p build && browserify index.js | indexhtmlify --title patchbay > build/index.html", | |
66 | 78 … | "start": "electro index.js", |
67 | - "bundle": "node scripts/style.js && mkdir -p build && browselectrify index.js > build/bundle.js", | |
79 … | + "bundle": "mkdir -p build && browselectrify index.js > build/bundle.js", | |
68 | 80 … | "rebuild": "npm rebuild --runtime=electron --target=$(electron -v) --abi=$(electron --abi) --disturl=https://atom.io/download/atom-shell", |
69 | 81 … | "graph": "node index.js | dot -Tsvg > graph.svg", |
70 | 82 … | "test": "set -e; for t in test/*.js; do node $t; done" |
71 | 83 … | }, |
scripts/create-index.js | ||
---|---|---|
@@ -1,8 +1,0 @@ | ||
1 | -var fs = require('fs') | |
2 | -var path = require('path') | |
3 | - | |
4 | -fs.writeFileSync( | |
5 | - path.join(__dirname, '..', 'style.css.json'), | |
6 | - JSON.stringify(fs.readFileSync(path.join(__dirname, '..', 'style.css'), 'utf8')) | |
7 | -) | |
8 | - |
scripts/style.js | ||
---|---|---|
@@ -1,8 +1,0 @@ | ||
1 | -var fs = require('fs') | |
2 | -var path = require('path') | |
3 | - | |
4 | -fs.writeFileSync( | |
5 | - path.join(__dirname, '..', 'style.css.json'), | |
6 | - JSON.stringify(fs.readFileSync(path.join(__dirname, '..', 'style.css'), 'utf8')) | |
7 | -) | |
8 | - |
style.css | ||
---|---|---|
@@ -176,8 +176,9 @@ | ||
176 | 176 … | float: right; |
177 | 177 … | } |
178 | 178 … | |
179 | 179 … | /* messages */ |
180 … | +/*to be deprecated once message preview is converted to modular style*/ | |
180 | 181 … | |
181 | 182 … | .message { |
182 | 183 … | position: relative; |
183 | 184 … | flex-basis: 0; |
@@ -192,15 +193,8 @@ | ||
192 | 193 … | .message:hover { |
193 | 194 … | background: #f9f9f9; |
194 | 195 … | } |
195 | 196 … | |
196 | -.message--mini { | |
197 | - font-size: 1em; | |
198 | - margin: 0; | |
199 | - padding: .2em; | |
200 | - border: none; | |
201 | - background: inherit; | |
202 | -} | |
203 | 197 … | |
204 | 198 … | .message_content div > span { |
205 | 199 … | font-size: 0.9em; |
206 | 200 … | margin-bottom: 0.7em; |
@@ -315,11 +309,16 @@ | ||
315 | 309 … | .avatar--thumbnail { |
316 | 310 … | width: 2.5em; |
317 | 311 … | height: 2.5em; |
318 | 312 … | float: left; |
319 | - margin-right: .5ex; | |
313 … | + margin: 0 .25ex; | |
320 | 314 … | } |
321 | 315 … | |
316 … | +.\.meta .avatar--thumbnail { | |
317 … | + width: 1.9em; | |
318 … | + height: 1.9em; | |
319 … | +} | |
320 … | + | |
322 | 321 … | .avatar--fullsize { |
323 | 322 … | width: 50%; |
324 | 323 … | } |
325 | 324 … |
Built with git-ssb-web