Commit b10ce2e3fb81fd4e7ded0080858d4a7ff1d508f9
add Comment cards, and likes
mix irving committed on 10/18/2017, 4:34:28 AMParent: d1fb3daa34d11265fab5f4118776a40e96d39062
Files changed
app/html/comments.js | changed |
app/html/comments.mcss | added |
app/page/blogShow.js | changed |
app/page/blogShow.mcss | changed |
message/html/likes.js | added |
message/html/likes.mcss | added |
message/index.js | changed |
app/html/comments.js | ||
---|---|---|
@@ -9,10 +9,12 @@ | ||
9 | 9 | 'about.obs.name': 'first', |
10 | 10 | 'feed.obs.thread': 'first', |
11 | 11 | 'keys.sync.id': 'first', |
12 | 12 | 'message.html.markdown': 'first', |
13 | + 'message.html.timeago': 'first', | |
14 | + 'message.html.likes': 'first', | |
13 | 15 | 'unread.sync.markRead': 'first', |
14 | - 'unread.sync.isUnread': 'first' | |
16 | + 'unread.sync.isUnread': 'first', | |
15 | 17 | }) |
16 | 18 | |
17 | 19 | exports.create = (api) => { |
18 | 20 | return nest('app.html.comments', comments) |
@@ -34,23 +36,20 @@ | ||
34 | 36 | if (!get(msg, 'value.content.root')) return |
35 | 37 | |
36 | 38 | const { author } = msg.value |
37 | 39 | return h('Comment', { className }, [ |
38 | - h('div.left', api.about.html.avatar(author)), | |
40 | + h('div.left', api.about.html.avatar(author, 'tiny')), | |
39 | 41 | h('div.right', [ |
40 | 42 | h('section.context', [ |
41 | 43 | h('div.name', api.about.obs.name(author)), |
42 | - h('div.timeago', '3 hours ago'), //TODO | |
44 | + api.message.html.timeago(msg) | |
43 | 45 | ]), |
44 | 46 | h('section.content', api.message.html.markdown(raw)), |
45 | 47 | h('section.actions', [ |
46 | 48 | h('div.reply', [ |
47 | 49 | h('i.fa.fa-commenting-o'), |
48 | 50 | ]), |
49 | - h('div.like', [ | |
50 | - Math.random() > 0.5 ? h('i.fa.fa-heart') : h('i.fa.fa-heart-o'), // TODO -obs I like | |
51 | - 3 // TODO -obs like count | |
52 | - ]) | |
51 | + api.message.html.likes(msg) | |
53 | 52 | ]) |
54 | 53 | ]) |
55 | 54 | ]) |
56 | 55 | } |
app/html/comments.mcss | ||
---|---|---|
@@ -1,0 +1,65 @@ | ||
1 | +Comments { | |
2 | + margin: 0 1.5rem | |
3 | + | |
4 | + div.Comment {} | |
5 | +} | |
6 | + | |
7 | +Comment { | |
8 | + display: flex | |
9 | + | |
10 | + div.left { | |
11 | + margin-right: 1rem | |
12 | + | |
13 | + div.Avatar {} | |
14 | + } | |
15 | + | |
16 | + div.right { | |
17 | + flex-grow: 1 | |
18 | + | |
19 | + border-bottom: 1px solid gainsboro | |
20 | + padding-bottom: 1rem | |
21 | + margin-bottom: 1rem | |
22 | + | |
23 | + section.context { | |
24 | + display: flex | |
25 | + align-items: baseline | |
26 | + | |
27 | + div.name { | |
28 | + font-size: 1.2rem | |
29 | + margin-right: 1rem | |
30 | + } | |
31 | + div.Timeago {} | |
32 | + } | |
33 | + | |
34 | + section.content { | |
35 | + font-size: .9rem | |
36 | + line-height: 1.4 | |
37 | + div.Markdown {} | |
38 | + } | |
39 | + | |
40 | + section.actions { | |
41 | + font-size: 1.2rem | |
42 | + margin-right: .5rem | |
43 | + | |
44 | + display: flex | |
45 | + justify-content: flex-end | |
46 | + align-items: baseline | |
47 | + | |
48 | + div.reply { | |
49 | + margin-right: 1.5rem | |
50 | + i.fa {} | |
51 | + } | |
52 | + | |
53 | + div.Likes { | |
54 | + min-width: 2.5rem | |
55 | + | |
56 | + display: flex | |
57 | + align-items: center | |
58 | + | |
59 | + i.fa { margin-right: .3rem } | |
60 | + div.count {} | |
61 | + } | |
62 | + } | |
63 | + } | |
64 | +} | |
65 | + |
app/page/blogShow.js | ||
---|---|---|
@@ -25,9 +25,9 @@ | ||
25 | 25 | |
26 | 26 | const { author, content } = blogMsg.value |
27 | 27 | |
28 | 28 | const blog = content.text |
29 | - const title = content.title || getTitle(blog) | |
29 | + const title = api.message.html.markdown(content.title || getTitle(blog)) | |
30 | 30 | |
31 | 31 | const comments = api.app.html.comments(blogMsg.key) |
32 | 32 | |
33 | 33 | const meta = { |
app/page/blogShow.mcss | ||
---|---|---|
@@ -1,8 +1,14 @@ | ||
1 | 1 | Page -blogShow { |
2 | 2 | // div.context {} |
3 | 3 | |
4 | 4 | div.content { |
5 | + header, div, section { | |
6 | + $maxWidth | |
7 | + margin-left: auto | |
8 | + margin-right: auto | |
9 | + } | |
10 | + | |
5 | 11 | header { |
6 | 12 | $backgroundPrimaryText |
7 | 13 | padding: 1rem |
8 | 14 | |
@@ -15,8 +21,10 @@ | ||
15 | 21 | |
16 | 22 | h1 { |
17 | 23 | flex-basis: 100% |
18 | 24 | |
25 | + $markdownLarge | |
26 | + font-size: 2rem | |
19 | 27 | font-weight: 300 |
20 | 28 | margin: 0 0 1rem 0 |
21 | 29 | } |
22 | 30 |
message/html/likes.js | ||
---|---|---|
@@ -1,0 +1,44 @@ | ||
1 | +var { h, computed, when } = require('mutant') | |
2 | +var nest = require('depnest') | |
3 | + | |
4 | +exports.needs = nest({ | |
5 | + 'keys.sync.id': 'first', | |
6 | + 'message.obs.likes': 'first', | |
7 | + 'sbot.async.publish': 'first' | |
8 | +}) | |
9 | + | |
10 | +exports.gives = nest('message.html.likes') | |
11 | + | |
12 | +exports.create = (api) => { | |
13 | + return nest('message.html.likes', function likes (msg) { | |
14 | + var id = api.keys.sync.id() | |
15 | + var likes = api.message.obs.likes(msg.key) | |
16 | + var iLike = computed(likes, likes => likes.includes(id)) | |
17 | + var count = computed(likes, likes => likes.length ? likes.length : '') | |
18 | + | |
19 | + return h('Likes', {'ev-click': () => publishLike(msg, !iLike())}, [ | |
20 | + h('i.fa', { className: when(iLike, 'fa-heart', 'fa-heart-o') }), | |
21 | + h('div.count', count) | |
22 | + ]) | |
23 | + }) | |
24 | + | |
25 | + function publishLike (msg, status = true) { | |
26 | + var like = status ? { | |
27 | + type: 'vote', | |
28 | + channel: msg.value.content.channel, | |
29 | + vote: { link: msg.key, value: 1, expression: 'Like' } | |
30 | + } : { | |
31 | + type: 'vote', | |
32 | + channel: msg.value.content.channel, | |
33 | + vote: { link: msg.key, value: 0, expression: 'Unlike' } | |
34 | + } | |
35 | + if (msg.value.content.recps) { | |
36 | + like.recps = msg.value.content.recps.map(function (e) { | |
37 | + return e && typeof e !== 'string' ? e.link : e | |
38 | + }) | |
39 | + like.private = true | |
40 | + } | |
41 | + api.sbot.async.publish(like) | |
42 | + } | |
43 | +} | |
44 | + |
Built with git-ssb-web