git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: b57e44a4c2db39bc5672f61e5a4fdc3c9abccab7

Files: b57e44a4c2db39bc5672f61e5a4fdc3c9abccab7 / about / obs.js

4775 bytesRaw
1var {Value, Struct, Dict, computed} = require('mutant')
2var pullPause = require('pull-pause')
3var pull = require('pull-stream')
4var msgs = require('ssb-msgs')
5var nest = require('depnest')
6var ref = require('ssb-ref')
7var colorHash = new (require('color-hash'))()
8
9exports.needs = nest({
10 'sbot.pull.query': 'first',
11 'blob.sync.url': '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 ]
25})
26
27exports.create = function (api) {
28 var sync = Value(false)
29 var cache = {}
30 var cacheLoading = false
31
32 return nest({
33 'about.obs': {
34 name: (id) => get(id).displayName,
35 description: (id) => get(id).description,
36 image: (id) => get(id).image,
37 imageUrl: (id) => get(id).imageUrl,
38
39 names: (id) => get(id).names,
40 images: (id) => get(id).images,
41 color: (id) => computed(id, (id) => colorHash.hex(id))
42 }
43 })
44
45 function get (id) {
46 if (!cacheLoading) {
47 cacheLoading = true
48 loadCache()
49 }
50 if (!cache[id]) {
51 cache[id] = About(api, id, sync)
52 }
53 return cache[id]
54 }
55
56 function loadCache () {
57 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)
84 }
85 },
86 () => sync.set(true)
87 )
88 )
89 }
90}
91
92function About (api, id, sync) {
93 if (!ref.isLink(id)) throw new Error('About requires an id!')
94
95 var pauser = pullPause((paused) => {})
96
97 // transparent image
98 var fallbackImageUrl = 'data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
99
100 var yourId = api.keys.sync.id()
101 var lastestTimestamps = {}
102
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
138 }
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)
149 }
150 }
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 }
156}
157
158function socialValue (lookup, id, yourId, fallback) {
159 return lookup[yourId] || lookup[id] || highestRank(lookup) || fallback || null
160}
161
162function highestRank (lookup) {
163 var indexed = indexByValue(lookup)
164 var highestCount = 0
165 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
171 }
172 })
173 return currentHighest
174}
175
176function indexByValue (lookup) {
177 var result = {}
178 Object.keys(lookup).forEach((key) => {
179 var value = lookup[key]
180 if (!result[value]) {
181 result[value] = []
182 }
183 result[value].push(key)
184 })
185 return result
186}
187
188function isAbout (msg) {
189 return msg.value && msg.value.content && msg.value.content.type === 'about'
190}
191

Built with git-ssb-web