git ssb

2+

mixmix / ticktack



Tree: dfa8dcc1b8dc80fea753df44f2c9faa9c5eb88ef

Files: dfa8dcc1b8dc80fea753df44f2c9faa9c5eb88ef / app / html / comments.js

4003 bytesRaw
1const nest = require('depnest')
2const { h, Array: MutantArray, Value, map, computed, when, resolve } = require('mutant')
3const get = require('lodash/get')
4
5exports.gives = nest('app.html.comments')
6
7exports.needs = nest({
8 'about.html.avatar': 'first',
9 'about.obs.name': 'first',
10 'backlinks.obs.for': 'first',
11 'feed.obs.thread': 'first',
12 'message.html.compose': 'first',
13 'message.html.markdown': 'first',
14 'message.html.timeago': 'first',
15 'message.html.likes': 'first',
16 'unread.sync.markRead': 'first',
17 'unread.sync.isUnread': 'first',
18})
19
20exports.create = (api) => {
21 return nest('app.html.comments', comments)
22
23 function comments (root) {
24 const { messages, channel, lastId: branch } = api.feed.obs.thread(root)
25
26 // TODO - move this up into Patchcore
27 const messagesTree = computed(messages, msgs => {
28 return msgs
29 .filter(msg => forkOf(msg) === undefined)
30 .map(threadMsg => {
31 const nestedReplies = msgs.filter(msg => forkOf(msg) === threadMsg.key)
32 threadMsg.replies = nestedReplies
33 return threadMsg
34 })
35 })
36
37 const meta = {
38 type: 'post',
39 root,
40 branch,
41 channel
42 }
43 const twoComposers = computed(messages, messages => {
44 return messages.length > 5
45 })
46 const { compose } = api.message.html
47
48
49 return h('Comments', [
50 when(twoComposers, compose({ meta, shrink: true, canAttach: false })),
51 map(messagesTree, msg => Comment(msg, root, branch)),
52 compose({ meta, shrink: false, canAttach: false }),
53 ])
54 }
55
56 function Comment (msgObs, root, branch) {
57 const msg = resolve(msgObs)
58
59 const raw = get(msg, 'value.content.text')
60 var className = api.unread.sync.isUnread(msg) ? ' -unread' : ' -read'
61 api.unread.sync.markRead(msg)
62
63 if (!get(msg, 'value.content.root')) return
64
65 const { author, content } = msg.value
66
67 // // TODO - move this upstream into patchcore:feed.obs.thread ??
68 // // OR change strategy to use forks
69 // const backlinks = api.backlinks.obs.for(msg.key)
70 // const nestedReplies = computed(backlinks, backlinks => {
71 // return backlinks.filter(backlinker => {
72 // const { type, root } = backlinker.value.content
73 // return type === 'post' && root === msg.key
74 // })
75 // })
76
77 var nestedReplyCompose = Value(false)
78 const toggleCompose = () => nestedReplyCompose.set(!nestedReplyCompose())
79 const nestedReplyComposer = api.message.html.compose({
80 meta: {
81 type: 'post',
82 root,
83 fork: msg.key,
84 branch,
85 channel: content.channel
86 },
87 shrink: false,
88 canAttach: false,
89 canPreview: false
90 }, toggleCompose)
91
92 return h('Comment', { className }, [
93 h('div.left', api.about.html.avatar(author, 'tiny')),
94 h('div.right', [
95 h('section.context', [
96 h('div.name', api.about.obs.name(author)),
97 api.message.html.timeago(msg)
98 ]),
99 h('section.content', api.message.html.markdown(raw)),
100 when(msgObs.replies,
101 h('section.replies',
102 map(msgObs.replies, NestedComment)
103 )
104 ),
105 h('section.actions', [
106 h('div.reply', { 'ev-click': toggleCompose }, [
107 h('i.fa.fa-commenting-o'),
108 ]),
109 api.message.html.likes(msg)
110 ]),
111 when(nestedReplyCompose, nestedReplyComposer),
112 ])
113 ])
114 }
115
116 function NestedComment (msgObs) {
117 const msg = resolve(msgObs)
118 const raw = get(msg, 'value.content.text')
119 if (!raw) return
120
121 const { author } = msg.value
122
123 return h('Comment -nested', [
124 h('div.left'),
125 h('div.right', [
126 h('section.context', [
127 h('div.name', api.about.obs.name(author)),
128 api.message.html.timeago(msg)
129 ]),
130 h('section.content', api.message.html.markdown(raw)),
131 ])
132 ])
133
134 api.message.html.markdown(raw)
135 }
136}
137
138function forkOf (msg) {
139 return get(msg, 'value.content.fork')
140}
141

Built with git-ssb-web