git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Tree: 8397cee5bd7b17b9f2ebf584813ed0c0a035023d

Files: 8397cee5bd7b17b9f2ebf584813ed0c0a035023d / modules / feed-summary.js

6117 bytesRaw
1var Value = require('mutant/value')
2var when = require('mutant/when')
3var computed = require('mutant/computed')
4var MutantArray = require('mutant/array')
5var Abortable = require('pull-abortable')
6var onceTrue = require('../lib/once-true')
7var pull = require('pull-stream')
8
9var Scroller = require('../lib/pull-scroll')
10var FeedSummary = require('../lib/feed-summary')
11
12var h = require('../lib/h')
13
14exports.needs = {
15 message: {
16 render: 'first',
17 link: 'first'
18 },
19 sbot: {
20 get: 'first',
21 get_id: 'first'
22 },
23 helpers: {
24 build_scroller: 'first'
25 },
26 person: 'first',
27 many_people: 'first',
28 people_names: 'first'
29}
30
31exports.gives = {
32 feed_summary: true
33}
34
35exports.create = function (api) {
36 return {
37 feed_summary (getStream, prepend, opts) {
38 var sync = Value(false)
39 var updates = Value(0)
40
41 var filter = opts && opts.filter
42 var bumpFilter = opts && opts.bumpFilter
43 var windowSize = opts && opts.windowSize
44 var waitFor = opts && opts.waitFor || true
45
46 var updateLoader = h('a Notifier -loader', {
47 href: '#',
48 'ev-click': refresh
49 }, [
50 'Show ',
51 h('strong', [updates]), ' ',
52 when(computed(updates, a => a === 1), 'update', 'updates')
53 ])
54
55 var { container, content } = api.helpers.build_scroller({ prepend })
56
57 setTimeout(refresh, 10)
58
59 onceTrue(waitFor, () => {
60 pull(
61 getStream({old: false}),
62 pull.drain((item) => {
63 var type = item && item.value && item.value.content.type
64 if (type && type !== 'vote') {
65 if (item.value && item.value.author === api.sbot.get_id() && !updates()) {
66 return refresh()
67 }
68 if (filter) {
69 var update = (item.value.content.type === 'post' && item.value.content.root) ? {
70 type: 'message',
71 messageId: item.value.content.root,
72 channel: item.value.content.channel
73 } : {
74 type: 'message',
75 author: item.value.author,
76 channel: item.value.content.channel,
77 messageId: item.key
78 }
79
80 ensureAuthor(update, (err, update) => {
81 if (!err) {
82 if (filter(update)) {
83 updates.set(updates() + 1)
84 }
85 }
86 })
87 } else {
88 updates.set(updates() + 1)
89 }
90 }
91 })
92 )
93 })
94
95 var abortLastFeed = null
96
97 var result = MutantArray([
98 when(updates, updateLoader),
99 when(sync, container, h('Loading -large'))
100 ])
101
102 result.reload = refresh
103 result.pendingUpdates = updates
104
105 return result
106
107 // scoped
108
109 function refresh () {
110 if (abortLastFeed) {
111 abortLastFeed()
112 }
113 updates.set(0)
114 sync.set(false)
115 content.innerHTML = ''
116
117 var abortable = Abortable()
118 abortLastFeed = abortable.abort
119
120 pull(
121 FeedSummary(getStream, {windowSize, bumpFilter}, () => {
122 sync.set(true)
123 }),
124 pull.asyncMap(ensureAuthor),
125 pull.filter((item) => {
126 if (filter) {
127 return filter(item)
128 } else {
129 return true
130 }
131 }),
132 abortable,
133 Scroller(container, content, renderItem, false, false)
134 )
135 }
136 }
137 }
138
139 function ensureAuthor (item, cb) {
140 if (item.type === 'message' && !item.message) {
141 api.sbot.get(item.messageId, (_, value) => {
142 if (value) {
143 item.author = value.author
144 }
145 cb(null, item)
146 })
147 } else {
148 cb(null, item)
149 }
150 }
151
152 function renderItem (item) {
153 if (item.type === 'message') {
154 var meta = null
155 var previousId = item.messageId
156 var replies = item.replies.slice(-4).map((msg) => {
157 var result = api.message.render(msg, {inContext: true, inSummary: true, previousId})
158 previousId = msg.key
159 return result
160 })
161 var renderedMessage = item.message ? api.message.render(item.message, {inContext: true}) : null
162 if (renderedMessage) {
163 if (item.lastUpdateType === 'reply' && item.repliesFrom.size) {
164 meta = h('div.meta', {
165 title: api.people_names(item.repliesFrom)
166 }, [
167 api.many_people(item.repliesFrom), ' replied'
168 ])
169 } else if (item.lastUpdateType === 'dig' && item.digs.size) {
170 meta = h('div.meta', {
171 title: api.people_names(item.digs)
172 }, [
173 api.many_people(item.digs), ' dug this message'
174 ])
175 }
176
177 return h('FeedEvent', [
178 meta,
179 renderedMessage,
180 when(replies.length, [
181 when(item.replies.length > replies.length,
182 h('a.full', {href: `#${item.messageId}`}, ['View full thread'])
183 ),
184 h('div.replies', replies)
185 ])
186 ])
187 } else {
188 if (item.lastUpdateType === 'reply' && item.repliesFrom.size) {
189 meta = h('div.meta', {
190 title: api.people_names(item.repliesFrom)
191 }, [
192 api.many_people(item.repliesFrom), ' replied to ', api.message.link(item.messageId)
193 ])
194 } else if (item.lastUpdateType === 'dig' && item.digs.size) {
195 meta = h('div.meta', {
196 title: api.people_names(item.digs)
197 }, [
198 api.many_people(item.digs), ' dug ', api.message.link(item.messageId)
199 ])
200 }
201
202 if (meta || replies.length) {
203 return h('FeedEvent', [
204 meta, h('div.replies', replies)
205 ])
206 }
207 }
208 } else if (item.type === 'follow') {
209 return h('FeedEvent -follow', [
210 h('div.meta', {
211 title: api.people_names(item.contacts)
212 }, [
213 api.person(item.id), ' followed ', api.many_people(item.contacts)
214 ])
215 ])
216 }
217
218 return h('div')
219 }
220}
221

Built with git-ssb-web