Files: aed5ebed79d6ab447fb2352806b064238968e9a4 / message / html / comment.js
3999 bytesRaw
1 | const nest = require('depnest') |
2 | const { h, Value, map, when, resolve, computed, onceTrue } = require('mutant') |
3 | const get = require('lodash/get') |
4 | const { heads } = require('ssb-sort') |
5 | |
6 | exports.gives = nest('message.html.comment') |
7 | |
8 | exports.needs = nest({ |
9 | 'about.html.avatar': 'first', |
10 | 'about.obs.name': 'first', |
11 | 'backlinks.obs.for': 'first', |
12 | 'blog.html.title': 'first', |
13 | 'message.html.compose': 'first', |
14 | 'message.html.markdown': 'first', |
15 | 'message.html.timeago': 'first', |
16 | 'message.html.likes': 'first', |
17 | 'unread.sync.markRead': 'first', |
18 | 'unread.sync.isUnread': 'first', |
19 | 'sbot.obs.connection': 'first', |
20 | 'translations.sync.strings': 'first' |
21 | }) |
22 | |
23 | exports.create = (api) => { |
24 | return nest('message.html.comment', Comment) |
25 | |
26 | function Comment ({ comment, replies, branch, showRootLink = false }) { |
27 | const strings = api.translations.sync.strings() |
28 | const msg = resolve(comment) |
29 | var root = get(msg, 'value.content.root') |
30 | if (!root) return |
31 | |
32 | const { author, content } = msg.value |
33 | |
34 | if (!replies) { |
35 | replies = computed(api.backlinks.obs.for(msg.key), backlinks => { |
36 | return backlinks.filter(backlinker => { |
37 | const { type, root: _root, fork } = backlinker.value.content |
38 | return type === 'post' && fork === msg.key && _root === root |
39 | }) |
40 | }) |
41 | } |
42 | if (!branch) { |
43 | branch = computed(api.backlinks.obs.for(root), backlinks => { |
44 | return heads(backlinks) |
45 | }) |
46 | } |
47 | |
48 | var className = api.unread.sync.isUnread(msg) ? ' -unread' : ' -read' |
49 | api.unread.sync.markRead(msg) |
50 | |
51 | var title = Value() |
52 | if (showRootLink) { |
53 | processMessage(root, msg => { |
54 | var t = api.blog.html.title(msg) |
55 | title.set(t.innerText ? t.innerText : t) |
56 | }) |
57 | } |
58 | |
59 | var nestedReplyCompose = Value(false) |
60 | const toggleCompose = () => nestedReplyCompose.set(!nestedReplyCompose()) |
61 | const nestedReplyComposer = api.message.html.compose({ |
62 | meta: { |
63 | type: 'post', |
64 | root, |
65 | fork: msg.key, |
66 | branch, |
67 | channel: content.channel |
68 | }, |
69 | shrink: false, |
70 | canAttach: true, |
71 | canPreview: false, |
72 | placeholder: strings.writeComment |
73 | }, toggleCompose) |
74 | |
75 | return h('Comment', { className }, [ |
76 | h('div.left', api.about.html.avatar(author, 'tiny')), |
77 | h('div.right', [ |
78 | h('section.context', [ |
79 | h('div.name', api.about.obs.name(author)), |
80 | api.message.html.timeago(msg), |
81 | when(showRootLink, h('a.rootLink', {href: root}, ['<< ', title, ' >>'])) |
82 | // TODO don't link to root, link to position of message within blog! |
83 | ]), |
84 | h('section.content', api.message.html.markdown(get(msg, 'value.content.text'))), |
85 | h('section.actions', [ |
86 | h('div.reply', { 'ev-click': toggleCompose }, [ |
87 | h('i.fa.fa-commenting-o') |
88 | ]), |
89 | api.message.html.likes(msg) |
90 | ]), |
91 | when(replies, |
92 | h('section.replies', |
93 | map( |
94 | replies, |
95 | NestedComment, |
96 | { |
97 | comparer: (a, b) => { |
98 | if (a === undefined || b === undefined) return false |
99 | return a.key === b.key |
100 | } |
101 | } |
102 | ) |
103 | ) |
104 | ), |
105 | when(nestedReplyCompose, nestedReplyComposer) |
106 | ]) |
107 | ]) |
108 | } |
109 | |
110 | function NestedComment (comment) { |
111 | const msg = resolve(comment) |
112 | const raw = get(msg, 'value.content.text') |
113 | if (!raw) return |
114 | |
115 | const { author } = msg.value |
116 | |
117 | return h('Comment -nested', [ |
118 | h('div.left'), |
119 | h('div.right', [ |
120 | h('section.context', [ |
121 | h('div.name', api.about.obs.name(author)), |
122 | api.message.html.timeago(msg) |
123 | ]), |
124 | h('section.content', api.message.html.markdown(raw)) |
125 | ]) |
126 | ]) |
127 | } |
128 | |
129 | function processMessage (key, fn) { |
130 | onceTrue(api.sbot.obs.connection, server => server.get(key, (err, value) => { |
131 | if (err) return console.error(err) |
132 | fn({ key, value }) |
133 | })) |
134 | } |
135 | } |
136 |
Built with git-ssb-web