git ssb

10+

Matt McKegg / patchwork



Tree: 05c5b4f2078be5153b1a4ff2c0f7455a930242b1

Files: 05c5b4f2078be5153b1a4ff2c0f7455a930242b1 / modules / feed-summary.js

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

Built with git-ssb-web