git ssb

1+

Daan Patchwork / patchwork



Tree: 770fe5e2a3d5973a5c9b7d0945b214c3b2ea6793

Files: 770fe5e2a3d5973a5c9b7d0945b214c3b2ea6793 / lib / plugins / gatherings.js

4685 bytesRaw
1'use strict'
2const pull = require('pull-stream')
3const extend = require('xtend')
4const pullResume = require('../pull-resume')
5const threadSummary = require('../thread-summary')
6const ResolveAbouts = require('../resolve-abouts')
7const Paramap = require('pull-paramap')
8const FilterBlocked = require('../filter-blocked')
9const LookupRoots = require('../lookup-roots')
10
11const async = require('async')
12
13exports.manifest = {
14 latest: 'source',
15 latestAttending: 'source',
16 roots: 'source'
17}
18
19exports.init = function (ssb) {
20 return {
21 latest: function () {
22 return pull(
23 ssb.messagesByType({ type: 'gathering', live: true, old: false }),
24 ResolveAbouts({ ssb }),
25 ApplyFilterResult({ ssb, passThroughOwn: true }),
26 pull.filter(msg => !!msg.filterResult)
27 )
28 },
29 latestAttending: function () {
30 return pull(
31 ssb.query.read({
32 query: [{ $filter: { value: { content: { type: 'about', attendee: { link: ssb.id } } } } }]
33 }),
34 LookupRoots({ ssb }),
35 ResolveAbouts({ ssb }),
36 ApplyFilterResult({ ssb, passThroughOwn: true }),
37 pull.filter(msg => !!msg.filterResult)
38 )
39 },
40 roots: function ({ reverse, limit, resume, onlyAttending = false }) {
41 // use resume option if specified
42 const opts = { reverse, old: true, type: 'gathering', private: true }
43 if (resume) {
44 opts[reverse ? 'lt' : 'gt'] = resume
45 }
46
47 return pullResume.source(ssb.messagesByType(opts), {
48 limit,
49 getResume: (item) => {
50 return item.timestamp
51 },
52 filterMap: pull(
53 // don't include if author blocked
54 FilterBlocked([ssb.id], {
55 isBlocking: ssb.patchwork.contacts.isBlocking
56 }),
57
58 // RESOLVE ROOTS WITH ABOUTS
59 ResolveAbouts({ ssb }),
60
61 // FILTER GATHERINGS BASED ON ATTENDEES AND AUTHOR (and hide if no title)
62 ApplyFilterResult({ ssb, onlyAttending }),
63 pull.filter(msg => !!msg.filterResult),
64
65 // ADD THREAD SUMMARY
66 Paramap((item, cb) => {
67 threadSummary(item.key, {
68 recentLimit: 3,
69 readThread: ssb.patchwork.thread.read,
70 bumpFilter,
71 pullFilter: pull(
72 FilterBlocked([item.value && item.value.author, ssb.id], { isBlocking: ssb.patchwork.contacts.isBlocking }),
73 ApplyReplyFilterResult({ ssb })
74 )
75 }, (err, summary) => {
76 if (err) return cb(err)
77 cb(null, extend(item, summary, {
78 rootBump: bumpFilter(item)
79 }))
80 })
81 }, 10)
82 )
83 })
84 }
85 }
86}
87
88function bumpFilter (msg) {
89 if (msg.value.content.type === 'about' && msg.filterResult && msg.value.content.attendee && !msg.value.content.attendee.remove) {
90 return { type: 'attending' }
91 }
92}
93
94function ApplyFilterResult ({ ssb, passThroughOwn = false, onlyAttending = false }) {
95 return pull.asyncMap((msg, cb) => {
96 const isYours = ssb.id === msg.value.author
97 const recps = msg.value.content.recps
98 const passThrough = isYours && passThroughOwn
99 ssb.patchwork.contacts.isFollowing({ source: ssb.id, dest: msg.value.author }, (err, followingAuthor) => {
100 if (err) return cb(err)
101 const attending = (msg.gathering && msg.gathering.attending) || []
102 async.filterSeries(attending, (dest, cb) => {
103 ssb.patchwork.contacts.isFollowing({ source: ssb.id, dest }, cb)
104 }, (err, followingAttending) => {
105 if (err) return cb(err)
106 const isAttending = Array.isArray(attending) && attending.includes(ssb.id)
107 const isRecp = Array.isArray(recps) && recps.includes(ssb.id)
108 const hasTitle = !!msg.gathering.title
109 const isVisible = passThrough || hasTitle
110
111 if (onlyAttending && !isAttending && !isYours) {
112 // only wanting events we are attending, and we are not attending so don't run filters
113 } else if ((followingAttending.length || followingAuthor || isYours || isAttending || isRecp) && isVisible) {
114 msg.filterResult = {
115 followingAttending,
116 followingAuthor,
117 isAttending,
118 isYours,
119 hasTitle
120 }
121 }
122
123 cb(null, msg)
124 })
125 })
126 })
127}
128
129function ApplyReplyFilterResult ({ ssb }) {
130 return pull.asyncMap((msg, cb) => {
131 ssb.patchwork.contacts.isFollowing({ source: ssb.id, dest: msg.value.author }, (err, isFollowing) => {
132 if (err) return cb(err)
133 if (isFollowing) {
134 msg.filterResult = {
135 isFollowing
136 }
137 }
138 cb(null, msg)
139 })
140 })
141}
142

Built with git-ssb-web