git ssb

7+

dinoworm 🐛 / patchcore



Commit 51b10fcae8f88e89444a0c702a5a50bcaf49c157

use ssb-about reducer for `about.obs`

Matt McKegg committed on 6/12/2017, 11:54:23 AM
Parent: 196bfa929c905a10e03900db3ff77a5f05c35300

Files changed

about/obs.jschanged
about/obs.jsView
@@ -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')
33 var pull = require('pull-stream')
4-var msgs = require('ssb-msgs')
54 var nest = require('depnest')
65 var ref = require('ssb-ref')
76 var colorHash = new (require('color-hash'))()
87
98 exports.needs = nest({
10- 'sbot.pull.query': 'first',
9 + 'sbot.obs.connection': 'first',
1110 'blob.sync.url': 'first',
1211 'keys.sync.id': 'first'
1312 })
1413
@@ -30,161 +29,147 @@
3029 var cacheLoading = false
3130
3231 return nest({
3332 'about.obs': {
34- name: (id) => get(id).displayName,
33 + name: (id) => get(id).name,
3534 description: (id) => get(id).description,
3635 image: (id) => get(id).image,
3736 imageUrl: (id) => get(id).imageUrl,
38-
3937 names: (id) => get(id).names,
4038 images: (id) => get(id).images,
4139 color: (id) => computed(id, (id) => colorHash.hex(id))
4240 }
4341 })
4442
4543 function get (id) {
44 + if (!ref.isFeed(id)) {
45 + console.log(id) //throw new Error('About requires an id!')
46 + console.trace()
47 + }
4648 if (!cacheLoading) {
4749 cacheLoading = true
4850 loadCache()
51 + window.things = cache
4952 }
5053 if (!cache[id]) {
51- cache[id] = About(api, id, sync)
54 + cache[id] = About(api, id)
5255 }
5356 return cache[id]
5457 }
5558
5659 function loadCache () {
5760 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])
8466 }
85- },
86- () => sync.set(true)
87- )
67 + }
68 +
69 + if (!sync()) {
70 + sync.set(true)
71 + }
72 + })
8873 )
8974 }
9075 }
9176
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) {
9778 // transparent image
9879 var fallbackImageUrl = 'data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
9980
81 + var state = Value({})
10082 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)
10286
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
13899 }
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 + }
149113 }
114 + if (changed) {
115 + state.set(lastState)
116 + }
150117 }
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- }
155118 }
156119 }
157120
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 + }
160128 }
161129
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 +
162142 function highestRank (lookup) {
163- var indexed = indexByValue(lookup)
143 + var counts = {}
164144 var highestCount = 0
165145 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 + }
171154 }
172- })
155 + }
173156 return currentHighest
174157 }
175158
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
182165 }
183- result[value].push(key)
184- })
185- return result
166 + }
186167 }
187168
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
190175 }

Built with git-ssb-web