git ssb

16+

Dominic / patchbay



Tree: 5c866da4bc329c8a371cb24ee975d3c8eeab9c3c

Files: 5c866da4bc329c8a371cb24ee975d3c8eeab9c3c / app / page / notifications.js

3307 bytesRaw
1const nest = require('depnest')
2const { h } = require('mutant')
3const pull = require('pull-stream')
4const pullMerge = require('pull-merge')
5const pullAbort = require('pull-abortable')
6const Scroller = require('pull-scroll')
7const next = require('pull-next-query')
8const BookNotifications = require('scuttle-book/pull/notifications')
9
10exports.gives = nest({
11 'app.html.menuItem': true,
12 'app.page.notifications': true
13})
14
15exports.needs = nest({
16 'app.html.filter': 'first',
17 'app.html.scroller': 'first',
18 'app.sync.goTo': 'first',
19 'feed.pull.public': 'first',
20 'keys.sync.id': 'first',
21 'message.html.render': 'first',
22 'message.sync.isBlocked': 'first',
23 'sbot.pull.stream': 'first'
24})
25
26exports.create = function (api) {
27 return nest({
28 'app.html.menuItem': menuItem,
29 'app.page.notifications': notificationsPage
30 })
31
32 function menuItem () {
33 return h('a', {
34 'ev-click': () => api.app.sync.goTo({ page: 'notifications' })
35 }, '/notifications')
36 }
37
38 function notificationsPage (location) {
39 const { filterMenu, filterDownThrough, filterUpThrough, resetFeed } = api.app.html.filter(draw)
40 const { container, content } = api.app.html.scroller({ prepend: [ filterMenu ] })
41
42 var abortableDown = pullAbort()
43 var abortableUp = pullAbort()
44
45 function draw () {
46 resetFeed({ container, content })
47
48 abortableDown.abort()
49 abortableDown = pullAbort()
50 pull(
51 pullMentions({ old: false, live: true }),
52 abortableDown,
53 filterDownThrough(),
54 Scroller(container, content, render, true, false)
55 )
56
57 abortableUp.abort()
58 abortableUp = pullAbort()
59 pull(
60 pullMentions({ reverse: true, live: false }),
61 abortableUp,
62 filterUpThrough(),
63 Scroller(container, content, render, false, false)
64 )
65 }
66 draw()
67
68 container.title = '/notifications'
69 return container
70 }
71
72 function render (msg) {
73 return api.message.html.render(msg, { showTitle: true })
74 }
75
76 // NOTE - currently this stream is know to pick up:
77 // - post mentions (public)
78 // - patchwork replies (public)
79 // - scry (public, private)
80 // - reviews on scuttle-books you posted (public)
81
82 function pullMentions (opts) {
83 const query = [{
84 $filter: {
85 dest: api.keys.sync.id(),
86 timestamp: { $gt: 0 }
87 }
88 }, {
89 $filter: {
90 value: {
91 author: { $ne: api.keys.sync.id() } // not my messages!
92 // NOTE putting this in second filter might be necessary to stop index trying to use this author value
93 }
94 }
95 }]
96
97 const _opts = Object.assign({
98 query,
99 limit: 100,
100 index: 'DTA'
101 }, opts)
102
103 return api.sbot.pull.stream(server => {
104 const bookNotifications = BookNotifications(server)
105 return pullMerge(
106 pull(
107 next(server.backlinks.read, _opts, ['timestamp']),
108 pull.filter(m => {
109 if (m.value.content.type !== 'post') return true
110 return !m.value.private // no private posts
111 }),
112 pull.filter(m => !api.message.sync.isBlocked(m))
113 ),
114 pull(bookNotifications(api.keys.sync.id(), opts)),
115 (lhs, rhs) => {
116 return rhs.value.timestamp - lhs.value.timestamp
117 }
118 )
119 })
120 }
121}
122

Built with git-ssb-web