git ssb

1+

Daan Patchwork / patchwork



Tree: 770fe5e2a3d5973a5c9b7d0945b214c3b2ea6793

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

3946 bytesRaw
1const pull = require('pull-stream')
2const parallel = require('run-parallel')
3const Paramap = require('pull-paramap')
4const extend = require('xtend')
5
6const HLRU = require('hashlru')
7const pullResume = require('../pull-resume')
8const threadSummary = require('../thread-summary')
9const LookupRoots = require('../lookup-roots')
10const ResolveAbouts = require('../resolve-abouts')
11const UniqueRoots = require('../unique-roots')
12const getRoot = require('../get-root')
13
14exports.manifest = {
15 avatar: 'async',
16 latest: 'source',
17 roots: 'source'
18}
19
20exports.init = function (ssb) {
21 const cache = HLRU(100)
22
23 return {
24 avatar: function avatar ({ id }, cb) {
25 const result = { id }
26 parallel([(done) => {
27 ssb.about.socialValue({ dest: id, key: 'name' }, (err, value) => {
28 if (err) return done(err)
29 result.name = value
30 done()
31 })
32 }, (done) => {
33 ssb.about.socialValue({ dest: id, key: 'image' }, (err, value) => {
34 if (err) return done(err)
35 if (value && value instanceof Object && value.link) value = value.link
36 result.image = value
37 done()
38 })
39 }], (err) => {
40 if (err) return cb(err)
41 cb(null, result)
42 })
43 },
44 latest: function latest ({ id }) {
45 return pull(
46 ssb.createUserStream({ id, live: true, old: false, awaitReady: false }),
47 pull.filter(bumpFilter),
48 LookupRoots({ ssb, cache }),
49 pull.filter(msg => {
50 return !getRoot(msg.root)
51 })
52 // TODO: handle blocked users
53 )
54
55 function bumpFilter (msg) {
56 return checkBump(msg, { id })
57 }
58 },
59 roots: function roots ({ id, limit, reverse, resume }) {
60 // use resume option if specified
61
62 const opts = { id, reverse, old: true, awaitReady: false }
63 if (resume) {
64 opts[reverse ? 'lt' : 'gt'] = resume
65 }
66
67 return pullResume.source(ssb.createUserStream(opts), {
68 limit,
69 getResume: (item) => {
70 return item && item.value && item.value.sequence
71 },
72 filterMap: pull(
73 pull.filter(bumpFilter),
74
75 LookupRoots({ ssb, cache }),
76
77 // DON'T REPEAT THE SAME THREAD
78 UniqueRoots(),
79
80 // DON'T INCLUDE UN-ROOTED MESSAGES (e.g. missing conversation root)
81 pull.filter(msg => {
82 return !getRoot(msg.root)
83 }),
84
85 // JUST RETURN THE ROOT OF THE MESSAGE
86 pull.map(msg => {
87 return msg.root || msg
88 }),
89
90 // RESOLVE ROOTS WITH ABOUTS (gatherings)
91 ResolveAbouts({ ssb }),
92
93 // ADD THREAD SUMMARY
94 Paramap((item, cb) => {
95 threadSummary(item.key, {
96 readThread: ssb.patchwork.thread.read,
97 recentLimit: 3,
98 bumpFilter,
99 recentFilter
100 // TODO: hide blocked replies from other users
101 }, (err, summary) => {
102 if (err) return cb(err)
103 cb(null, extend(item, summary))
104 })
105 }, 20)
106 )
107 })
108
109 function recentFilter (msg) {
110 // only show replies by this feed on the profile
111 return msg.value.author === id
112 }
113
114 function bumpFilter (msg) {
115 return checkBump(msg, { id })
116 }
117 }
118 }
119}
120
121function checkBump (msg, { id }) {
122 if (msg.value.author === id) {
123 const content = msg.value.content
124 const type = content.type
125 if (type === 'vote' && !getRoot(msg)) { // only show likes when root post
126 const vote = content.vote
127 if (vote) {
128 return { type: 'reaction', reaction: vote.expression, value: vote.value }
129 }
130 } else if (type === 'post') {
131 if (getRoot(msg)) {
132 return 'reply'
133 } else {
134 return 'post'
135 }
136 } else if (type === 'about') {
137 return 'update'
138 } else if (type === 'contact') {
139 return 'post'
140 }
141 }
142}
143

Built with git-ssb-web