git ssb

10+

Matt McKegg / patchwork



Tree: 9612ad288ce92ed027371e3b3e1c005116464264

Files: 9612ad288ce92ed027371e3b3e1c005116464264 / modules / feed-summary.js

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

Built with git-ssb-web