Commit 51b10fcae8f88e89444a0c702a5a50bcaf49c157
use ssb-about reducer for `about.obs`
Matt McKegg committed on 6/12/2017, 11:54:23 AMParent: 196bfa929c905a10e03900db3ff77a5f05c35300
Files changed
about/obs.js | changed |
about/obs.js | ||
---|---|---|
@@ -1,14 +1,13 @@ | ||
1 | -var {Value, Struct, Dict, computed} = require('mutant') | |
2 | -var pullPause = require('pull-pause') | |
1 … | +var {Value, computed, onceTrue} = require('mutant') | |
2 … | +var defer = require('pull-defer') | |
3 | 3 … | var pull = require('pull-stream') |
4 | -var msgs = require('ssb-msgs') | |
5 | 4 … | var nest = require('depnest') |
6 | 5 … | var ref = require('ssb-ref') |
7 | 6 … | var colorHash = new (require('color-hash'))() |
8 | 7 … | |
9 | 8 … | exports.needs = nest({ |
10 | - 'sbot.pull.query': 'first', | |
9 … | + 'sbot.obs.connection': 'first', | |
11 | 10 … | 'blob.sync.url': 'first', |
12 | 11 … | 'keys.sync.id': 'first' |
13 | 12 … | }) |
14 | 13 … | |
@@ -30,161 +29,147 @@ | ||
30 | 29 … | var cacheLoading = false |
31 | 30 … | |
32 | 31 … | return nest({ |
33 | 32 … | 'about.obs': { |
34 | - name: (id) => get(id).displayName, | |
33 … | + name: (id) => get(id).name, | |
35 | 34 … | description: (id) => get(id).description, |
36 | 35 … | image: (id) => get(id).image, |
37 | 36 … | imageUrl: (id) => get(id).imageUrl, |
38 | - | |
39 | 37 … | names: (id) => get(id).names, |
40 | 38 … | images: (id) => get(id).images, |
41 | 39 … | color: (id) => computed(id, (id) => colorHash.hex(id)) |
42 | 40 … | } |
43 | 41 … | }) |
44 | 42 … | |
45 | 43 … | function get (id) { |
44 … | + if (!ref.isFeed(id)) { | |
45 … | + console.log(id) //throw new Error('About requires an id!') | |
46 … | + console.trace() | |
47 … | + } | |
46 | 48 … | if (!cacheLoading) { |
47 | 49 … | cacheLoading = true |
48 | 50 … | loadCache() |
51 … | + window.things = cache | |
49 | 52 … | } |
50 | 53 … | if (!cache[id]) { |
51 | - cache[id] = About(api, id, sync) | |
54 … | + cache[id] = About(api, id) | |
52 | 55 … | } |
53 | 56 … | return cache[id] |
54 | 57 … | } |
55 | 58 … | |
56 | 59 … | function loadCache () { |
57 | 60 … | pull( |
58 | - api.sbot.pull.query({ | |
59 | - query: [ | |
60 | - {$filter: { | |
61 | - value: { | |
62 | - content: { | |
63 | - type: 'about' | |
64 | - } | |
65 | - } | |
66 | - }}, | |
67 | - {$map: { | |
68 | - timestamp: 'timestamp', | |
69 | - author: ['value', 'author'], | |
70 | - id: ['value', 'content', 'about'], | |
71 | - name: ['value', 'content', 'name'], | |
72 | - image: ['value', 'content', 'image'], | |
73 | - description: ['value', 'content', 'description'] | |
74 | - }} | |
75 | - ], | |
76 | - live: true | |
77 | - }), | |
78 | - pull.drain( | |
79 | - msg => { | |
80 | - if (msg.sync) { | |
81 | - sync.set(true) | |
82 | - } else if (msgs.isLink(msg.id, 'feed')) { | |
83 | - get(msg.id).push(msg) | |
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]) | |
84 | 66 … | } |
85 | - }, | |
86 | - () => sync.set(true) | |
87 | - ) | |
67 … | + } | |
68 … | + | |
69 … | + if (!sync()) { | |
70 … | + sync.set(true) | |
71 … | + } | |
72 … | + }) | |
88 | 73 … | ) |
89 | 74 … | } |
90 | 75 … | } |
91 | 76 … | |
92 | -function About (api, id, sync) { | |
93 | - if (!ref.isLink(id)) throw new Error('About requires an id!') | |
94 | - | |
95 | - var pauser = pullPause((paused) => {}) | |
96 | - | |
77 … | +function About (api, id) { | |
97 | 78 … | // transparent image |
98 | 79 … | var fallbackImageUrl = 'data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==' |
99 | 80 … | |
81 … | + var state = Value({}) | |
100 | 82 … | var yourId = api.keys.sync.id() |
101 | - var lastestTimestamps = {} | |
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) | |
102 | 86 … | |
103 | - var obs = Struct({ | |
104 | - assignedNames: Dict(), | |
105 | - assignedImages: Dict(), | |
106 | - assignedDescriptions: Dict() | |
107 | - }, { | |
108 | - onListen: pauser.resume, | |
109 | - onUnlisten: pauser.pause | |
110 | - }) | |
111 | - | |
112 | - obs.sync = computed([sync, obs], (v) => v) | |
113 | - obs.displayName = computed([obs.assignedNames, id, yourId, id.slice(1, 10)], socialValue) | |
114 | - obs.description = computed([obs.assignedDescriptions, id, yourId], socialValue) | |
115 | - obs.image = computed([obs.assignedImages, id, yourId], socialValue) | |
116 | - | |
117 | - obs.names = computed(obs.assignedNames, indexByValue) | |
118 | - obs.images = computed(obs.assignedImages, indexByValue) | |
119 | - | |
120 | - obs.imageUrl = computed(obs.image, (blobId) => { | |
121 | - if (blobId) { | |
122 | - return api.blob.sync.url(blobId) | |
123 | - } else { | |
124 | - return fallbackImageUrl | |
125 | - } | |
126 | - }) | |
127 | - | |
128 | - obs.push = push | |
129 | - | |
130 | - return obs | |
131 | - | |
132 | - // scoped | |
133 | - | |
134 | - function push (msg) { | |
135 | - if (!lastestTimestamps[msg.author]) { | |
136 | - lastestTimestamps[msg.author] = { | |
137 | - name: 0, image: 0, description: 0 | |
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 | |
138 | 99 … | } |
139 | - } | |
140 | - if (msg.name && lastestTimestamps[msg.author].name < msg.timestamp) { | |
141 | - lastestTimestamps[msg.author].name = msg.timestamp | |
142 | - obs.assignedNames.put(msg.author, msg.name) | |
143 | - } | |
144 | - if (msg.image && lastestTimestamps[msg.author].image < msg.timestamp) { | |
145 | - lastestTimestamps[msg.author].image = msg.timestamp | |
146 | - var obj = msgs.link(msg.image, 'blob') | |
147 | - if (obj && obj.link) { | |
148 | - obs.assignedImages.put(msg.author, obj.link) | |
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 … | + } | |
149 | 113 … | } |
114 … | + if (changed) { | |
115 … | + state.set(lastState) | |
116 … | + } | |
150 | 117 … | } |
151 | - if (msg.description && lastestTimestamps[msg.author].description < msg.timestamp) { | |
152 | - lastestTimestamps[msg.author].description = msg.timestamp | |
153 | - obs.assignedDescriptions.put(msg.author, msg.description) | |
154 | - } | |
155 | 118 … | } |
156 | 119 … | } |
157 | 120 … | |
158 | -function socialValue (lookup, id, yourId, fallback) { | |
159 | - return lookup[yourId] || lookup[id] || highestRank(lookup) || fallback || null | |
121 … | +function 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 … | + } | |
160 | 128 … | } |
161 | 129 … | |
130 … | +function 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 … | + | |
162 | 142 … | function highestRank (lookup) { |
163 | - var indexed = indexByValue(lookup) | |
143 … | + var counts = {} | |
164 | 144 … | var highestCount = 0 |
165 | 145 … | var currentHighest = null |
166 | - Object.keys(indexed).forEach((item) => { | |
167 | - var count = indexed[item].length | |
168 | - if (count > highestCount) { | |
169 | - highestCount = count | |
170 | - currentHighest = item | |
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 … | + } | |
171 | 154 … | } |
172 | - }) | |
155 … | + } | |
173 | 156 … | return currentHighest |
174 | 157 … | } |
175 | 158 … | |
176 | -function indexByValue (lookup) { | |
177 | - var result = {} | |
178 | - Object.keys(lookup).forEach((key) => { | |
179 | - var value = lookup[key] | |
180 | - if (!result[value]) { | |
181 | - result[value] = [] | |
159 … | +function 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 | |
182 | 165 … | } |
183 | - result[value].push(key) | |
184 | - }) | |
185 | - return result | |
166 … | + } | |
186 | 167 … | } |
187 | 168 … | |
188 | -function isAbout (msg) { | |
189 | - return msg.value && msg.value.content && msg.value.content.type === 'about' | |
169 … | +function StreamWhenConnected (connection, fn) { | |
170 … | + var stream = defer.source() | |
171 … | + onceTrue(connection, function (connection) { | |
172 … | + stream.resolve(fn(connection)) | |
173 … | + }) | |
174 … | + return stream | |
190 | 175 … | } |
Built with git-ssb-web