git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Tree: 402f85029889d7cc332cef170ab52fdc69bf4ae4

Files: 402f85029889d7cc332cef170ab52fdc69bf4ae4 / modules / feed-summary.js

5816 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 (item.value && item.value.author && !updates()) {
61 return refresh()
62 }
63 if (type && type !== 'vote') {
64 if (filter) {
65 var update = (item.value.content.type === 'post' && item.value.content.root) ? {
66 type: 'message',
67 messageId: item.value.content.root,
68 channel: item.value.content.channel
69 } : {
70 type: 'message',
71 author: item.value.author,
72 channel: item.value.content.channel,
73 messageId: item.key
74 }
75
76 ensureAuthor(update, (err, update) => {
77 if (!err) {
78 if (filter(update)) {
79 updates.set(updates() + 1)
80 }
81 }
82 })
83 } else {
84 updates.set(updates() + 1)
85 }
86 }
87 })
88 )
89 })
90
91 var abortLastFeed = null
92
93 var result = MutantArray([
94 when(updates, updateLoader),
95 when(sync, scrollElement, m('Loading -large'))
96 ])
97
98 result.reload = refresh
99 result.pendingUpdates = updates
100
101 return result
102
103 // scoped
104
105 function refresh () {
106 if (abortLastFeed) {
107 abortLastFeed()
108 }
109 updates.set(0)
110 sync.set(false)
111 content.innerHTML = ''
112
113 var abortable = Abortable()
114 abortLastFeed = abortable.abort
115
116 pull(
117 FeedSummary(getStream, {windowSize, bumpFilter}, () => {
118 sync.set(true)
119 }),
120 pull.asyncMap(ensureAuthor),
121 pull.filter((item) => {
122 if (filter) {
123 return filter(item)
124 } else {
125 return true
126 }
127 }),
128 abortable,
129 Scroller(scrollElement, content, renderItem, false, false)
130 )
131 }
132}
133
134function ensureAuthor (item, cb) {
135 if (item.type === 'message' && !item.message) {
136 sbot_get(item.messageId, (_, value) => {
137 if (value) {
138 item.author = value.author
139 }
140 cb(null, item)
141 })
142 } else {
143 cb(null, item)
144 }
145}
146
147function renderItem (item) {
148 if (item.type === 'message') {
149 var meta = null
150 var previousId = item.messageId
151 var replies = item.replies.slice(-4).map((msg) => {
152 var result = message_render(msg, {inContext: true, inSummary: true, previousId})
153 previousId = msg.key
154 return result
155 })
156 var renderedMessage = item.message ? message_render(item.message, {inContext: true}) : null
157 if (renderedMessage) {
158 if (item.lastUpdateType === 'reply' && item.repliesFrom.size) {
159 meta = m('div.meta', {
160 title: people_names(item.repliesFrom)
161 }, [
162 many_people(item.repliesFrom), ' replied'
163 ])
164 } else if (item.lastUpdateType === 'dig' && item.digs.size) {
165 meta = m('div.meta', {
166 title: people_names(item.digs)
167 }, [
168 many_people(item.digs), ' dug this message'
169 ])
170 }
171
172 return m('FeedEvent', [
173 meta,
174 renderedMessage,
175 when(replies.length, [
176 when(item.replies.length > replies.length,
177 m('a.full', {href: `#${item.messageId}`}, ['View full thread'])
178 ),
179 m('div.replies', replies)
180 ])
181 ])
182 } else {
183 if (item.lastUpdateType === 'reply' && item.repliesFrom.size) {
184 meta = m('div.meta', {
185 title: people_names(item.repliesFrom)
186 }, [
187 many_people(item.repliesFrom), ' replied to ', message_link(item.messageId)
188 ])
189 } else if (item.lastUpdateType === 'dig' && item.digs.size) {
190 meta = m('div.meta', {
191 title: people_names(item.digs)
192 }, [
193 many_people(item.digs), ' dug ', message_link(item.messageId)
194 ])
195 }
196
197 if (meta || replies.length) {
198 return m('FeedEvent', [
199 meta, m('div.replies', replies)
200 ])
201 }
202 }
203 } else if (item.type === 'follow') {
204 return m('FeedEvent -follow', [
205 m('div.meta', {
206 title: people_names(item.contacts)
207 }, [
208 person(item.id), ' followed ', many_people(item.contacts)
209 ])
210 ])
211 }
212
213 return h('div')
214}
215

Built with git-ssb-web