git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: 51b10fcae8f88e89444a0c702a5a50bcaf49c157

Files: 51b10fcae8f88e89444a0c702a5a50bcaf49c157 / about / obs.js

4406 bytesRaw
1var {Value, computed, onceTrue} = require('mutant')
2var defer = require('pull-defer')
3var pull = require('pull-stream')
4var nest = require('depnest')
5var ref = require('ssb-ref')
6var colorHash = new (require('color-hash'))()
7
8exports.needs = nest({
9 'sbot.obs.connection': 'first',
10 'blob.sync.url': 'first',
11 'keys.sync.id': 'first'
12})
13
14exports.gives = nest({
15 'about.obs': [
16 'name',
17 'description',
18 'image',
19 'imageUrl',
20 'names',
21 'images',
22 'color'
23 ]
24})
25
26exports.create = function (api) {
27 var sync = Value(false)
28 var cache = {}
29 var cacheLoading = false
30
31 return nest({
32 'about.obs': {
33 name: (id) => get(id).name,
34 description: (id) => get(id).description,
35 image: (id) => get(id).image,
36 imageUrl: (id) => get(id).imageUrl,
37 names: (id) => get(id).names,
38 images: (id) => get(id).images,
39 color: (id) => computed(id, (id) => colorHash.hex(id))
40 }
41 })
42
43 function get (id) {
44 if (!ref.isFeed(id)) {
45 console.log(id) //throw new Error('About requires an id!')
46 console.trace()
47 }
48 if (!cacheLoading) {
49 cacheLoading = true
50 loadCache()
51 window.things = cache
52 }
53 if (!cache[id]) {
54 cache[id] = About(api, id)
55 }
56 return cache[id]
57 }
58
59 function loadCache () {
60 pull(
61 StreamWhenConnected(api.sbot.obs.connection, sbot => sbot.about.stream({live: true})),
62 pull.drain(item => {
63 for (var target in item) {
64 if (ref.isFeed(target)) {
65 get(target).push(item[target])
66 }
67 }
68
69 if (!sync()) {
70 sync.set(true)
71 }
72 })
73 )
74 }
75}
76
77function About (api, id) {
78 // transparent image
79 var fallbackImageUrl = 'data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
80
81 var state = Value({})
82 var yourId = api.keys.sync.id()
83 var image = computed([state, 'image', id, yourId], socialValue)
84 var name = computed([state, 'name', id, yourId, id.slice(1, 10)], socialValue)
85 var description = computed([state, 'description', id, yourId], socialValue)
86
87 return {
88 name,
89 image,
90 description,
91 names: computed([state, 'name', id, yourId, id.slice(1, 10)], allValues),
92 images: computed([state, 'image', id, yourId], allValues),
93 descriptions: computed([state, 'description', id, yourId], allValues),
94 imageUrl: computed(image, (blobId) => {
95 if (blobId) {
96 return api.blob.sync.url(blobId)
97 } else {
98 return fallbackImageUrl
99 }
100 }),
101 push: function (values) {
102 var lastState = state()
103 var changed = false
104 for (var key in values) {
105 var valuesForKey = lastState[key] = lastState[key] || {}
106 for (var author in values[key]) {
107 var value = values[key][author]
108 if (!valuesForKey[author] || value.lastSeq > valuesForKey[author].lastSeq) {
109 valuesForKey[author] = value
110 changed = true
111 }
112 }
113 }
114 if (changed) {
115 state.set(lastState)
116 }
117 }
118 }
119}
120
121function socialValue (lookup, key, id, yourId, fallback) {
122 var result = lookup[key] ? getValue(lookup[key][yourId]) || getValue(lookup[key][id]) || highestRank(lookup[key]) : null
123 if (result != null) {
124 return result
125 } else {
126 return fallback || null
127 }
128}
129
130function allValues (lookup, key, id, yourId) {
131 var values = {}
132 for (var author in lookup[key]) {
133 var value = getValue(lookup[key][author])
134 if (value != null) {
135 values[value] = values[value] || []
136 values[value].push(author)
137 }
138 }
139 return values
140}
141
142function highestRank (lookup) {
143 var counts = {}
144 var highestCount = 0
145 var currentHighest = null
146 for (var key in lookup) {
147 var value = getValue(lookup[key])
148 if (value != null) {
149 counts[value] = (counts[value] || 0) + 1
150 if (counts[value] > highestCount) {
151 currentHighest = value
152 highestCount = counts[value]
153 }
154 }
155 }
156 return currentHighest
157}
158
159function getValue (item) {
160 if (item && item.value) {
161 if (typeof item.value === 'string') {
162 return item.value
163 } else if (item.value && item.value.link && ref.isLink(item.value.link)) {
164 return item.value.link
165 }
166 }
167}
168
169function StreamWhenConnected (connection, fn) {
170 var stream = defer.source()
171 onceTrue(connection, function (connection) {
172 stream.resolve(fn(connection))
173 })
174 return stream
175}
176

Built with git-ssb-web