git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: dcb68fb50cc8bee039bf3b455495c4057767384e

Files: dcb68fb50cc8bee039bf3b455495c4057767384e / about / obs.js

5251 bytesRaw
1var {Value, computed} = require('mutant')
2var pull = require('pull-stream')
3var nest = require('depnest')
4var ref = require('ssb-ref')
5var colorHash = new (require('color-hash'))()
6var fallbackImageUrl = 'data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
7
8exports.needs = nest({
9 'sbot.pull.stream': 'first',
10 'blob.sync.url': 'first',
11 'about.sync.shortFeedId': 'first',
12 'keys.sync.id': 'first'
13})
14
15exports.gives = nest({
16 'about.obs': [
17 'name',
18 'description',
19 'image',
20 'imageUrl',
21 'names',
22 'images',
23 'color',
24 'latestValue',
25 'valueFrom',
26 'socialValue',
27 'groupedValues'
28 ]
29})
30
31exports.create = function (api) {
32 var syncValue = Value(false)
33 var sync = computed(syncValue, x => x)
34 var cache = null
35
36 return nest({
37 'about.obs': {
38 // quick helpers, probably should deprecate!
39 name: (id) => socialValue(id, 'name', api.about.sync.shortFeedId(id)),
40 description: (id) => socialValue(id, 'description'),
41 image: (id) => socialValue(id, 'image'),
42 names: (id) => groupedValues(id, 'name'),
43 images: (id) => groupedValues(id, 'image'),
44 color: (id) => computed(id, (id) => colorHash.hex(id)),
45 imageUrl: (id) => computed(socialValue(id, 'image'), (blobId) => {
46 return blobId ? api.blob.sync.url(blobId) : fallbackImageUrl
47 }),
48
49 // custom abouts (the future!)
50 valueFrom,
51 latestValue,
52 socialValue,
53 groupedValues
54 }
55 })
56
57 function valueFrom (id, key, author) {
58 if (!ref.isLink(id)) throw new Error('About requires an ssb ref!')
59 return withSync(computed([get(id), key, author], getValueFrom))
60 }
61
62 function latestValue (id, key) {
63 if (!ref.isLink(id)) throw new Error('About requires an ssb ref!')
64 return withSync(computed([get(id), key], getLatestValue))
65 }
66
67 function socialValue (id, key, defaultValue) {
68 if (!ref.isLink(id)) throw new Error('About requires an ssb ref!')
69 var yourId = api.keys.sync.id()
70 return withSync(computed([get(id), key, id, yourId, defaultValue], getSocialValue))
71 }
72
73 function groupedValues (id, key) {
74 if (!ref.isLink(id)) throw new Error('About requires an ssb ref!')
75 return withSync(computed([get(id), key], getGroupedValues))
76 }
77
78 function withSync (obs) {
79 obs.sync = sync
80 return obs
81 }
82
83 function get (id) {
84 if (!ref.isLink(id)) throw new Error('About requires an ssb ref!')
85 load()
86 if (!cache[id]) {
87 cache[id] = Value({})
88 }
89 return cache[id]
90 }
91
92 function load () {
93 if (!cache) {
94 cache = {}
95 pull(
96 api.sbot.pull.stream(sbot => sbot.about.stream({live: true})),
97 pull.drain(item => {
98 for (var target in item) {
99 var state = get(target)
100 var lastState = state()
101 var values = item[target]
102 var changed = false
103 for (var key in values) {
104 var valuesForKey = lastState[key] = lastState[key] || {}
105 for (var author in values[key]) {
106 var value = values[key][author]
107 if (!valuesForKey[author] || value[1] > valuesForKey[author][1]) {
108 valuesForKey[author] = value
109 changed = true
110 }
111 }
112 }
113 if (changed) {
114 state.set(lastState)
115 }
116 }
117
118 if (!syncValue()) {
119 syncValue.set(true)
120 }
121 })
122 )
123 }
124 }
125}
126
127function getSocialValue (lookup, key, id, yourId, fallback) {
128 var result = lookup[key] ? getValue(lookup[key][yourId]) || getValue(lookup[key][id]) || highestRank(lookup[key]) : null
129 if (result != null) {
130 return result
131 } else {
132 return fallback || null
133 }
134}
135
136function getGroupedValues (lookup, key) {
137 var values = {}
138 for (var author in lookup[key]) {
139 var value = getValue(lookup[key][author])
140 if (value != null) {
141 values[value] = values[value] || []
142 values[value].push(author)
143 }
144 }
145 return values
146}
147
148function highestRank (lookup) {
149 var counts = {}
150 var highestCount = 0
151 var currentHighest = null
152 for (var key in lookup) {
153 var value = getValue(lookup[key])
154 if (value != null) {
155 counts[value] = (counts[value] || 0) + 1
156 if (counts[value] > highestCount) {
157 currentHighest = value
158 highestCount = counts[value]
159 }
160 }
161 }
162 return currentHighest
163}
164
165function getValue (item) {
166 if (item && item[0]) {
167 if (typeof item[0] === 'string') {
168 return item[0]
169 } else if (item[0] && item[0].link && ref.isLink(item[0].link) && !item[0].remove) {
170 return item[0].link
171 }
172 }
173}
174
175function getLatestValue (lookup, key) {
176 var latestTime = 0
177 var latestValue = null
178
179 if (lookup[key]) {
180 for (var author in lookup[key]) {
181 if (Array.isArray(lookup[key][author])) {
182 var value = lookup[key][author][0]
183 var timestamp = lookup[key][author][1]
184 if (timestamp > latestTime) {
185 latestTime = timestamp
186 latestValue = value
187 }
188 }
189 }
190 }
191
192 return latestValue
193}
194
195function getValueFrom (lookup, key, author) {
196 if (lookup[key] && Array.isArray(lookup[key][author])) {
197 return lookup[key][author][0]
198 }
199}
200

Built with git-ssb-web