Files: 6de90614bba444a5983be5bf651a2f79fcc19e73 / about / obs.js
3455 bytesRaw
1 | var {Value, Struct, Dict, computed} = require('mutant') |
2 | var pullPause = require('pull-pause') |
3 | var pull = require('pull-stream') |
4 | var msgs = require('ssb-msgs') |
5 | var nest = require('depnest') |
6 | var colorHash = new (require('color-hash'))() |
7 | |
8 | exports.needs = nest({ |
9 | 'sbot.pull.links': 'first', |
10 | 'blob.sync.url': 'first', |
11 | 'keys.sync.id': 'first' |
12 | }) |
13 | exports.gives = nest({ |
14 | 'about.obs': [ |
15 | 'name', |
16 | 'description', |
17 | 'image', |
18 | 'imageUrl', |
19 | 'names', |
20 | 'images', |
21 | 'color' |
22 | ] |
23 | }) |
24 | |
25 | exports.create = function (api) { |
26 | var cache = {} |
27 | |
28 | return nest({ |
29 | 'about.obs': { |
30 | name: (id) => get(id).displayName, |
31 | description: (id) => get(id).description, |
32 | image: (id) => get(id).image, |
33 | imageUrl: (id) => get(id).imageUrl, |
34 | |
35 | names: (id) => get(id).names, |
36 | images: (id) => get(id).images, |
37 | color: (id) => computed(id, (id) => colorHash.hex(id)) |
38 | } |
39 | }) |
40 | |
41 | function get (id) { |
42 | if (!cache[id]) { |
43 | cache[id] = About(api, id) |
44 | } |
45 | return cache[id] |
46 | } |
47 | } |
48 | |
49 | function About (api, id) { |
50 | var pauser = pullPause((paused) => {}) |
51 | |
52 | // transparent image |
53 | var fallbackImageUrl = 'data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==' |
54 | |
55 | var sync = Value(false) |
56 | var yourId = api.keys.sync.id() |
57 | |
58 | var obs = Struct({ |
59 | assignedNames: Dict(), |
60 | assignedImages: Dict(), |
61 | assignedDescriptions: Dict() |
62 | }, { |
63 | onListen: pauser.resume, |
64 | onUnlisten: pauser.pause |
65 | }) |
66 | |
67 | obs.sync = computed([sync, obs], (v) => v) |
68 | obs.displayName = computed([obs.assignedNames, id, yourId, id.slice(1, 10)], socialValue) |
69 | obs.description = computed([obs.assignedDescriptions, id, yourId], socialValue) |
70 | obs.image = computed([obs.assignedImages, id, yourId], socialValue) |
71 | |
72 | obs.names = computed(obs.assignedNames, indexByValue) |
73 | obs.images = computed(obs.assignedImages, indexByValue) |
74 | |
75 | obs.imageUrl = computed(obs.image, (blobId) => { |
76 | if (blobId) { |
77 | return api.blob.sync.url(blobId) |
78 | } else { |
79 | return fallbackImageUrl |
80 | } |
81 | }) |
82 | |
83 | pull( |
84 | api.sbot.pull.links({dest: id, rel: 'about', values: true, live: true}), |
85 | pauser, |
86 | pull.drain(function (msg) { |
87 | if (msg.sync) { |
88 | sync.set(true) |
89 | } else { |
90 | if (msg.value.content.name) { |
91 | obs.assignedNames.put(msg.value.author, msg.value.content.name) |
92 | } |
93 | if (msg.value.content.image) { |
94 | var obj = msgs.link(msg.value.content.image, 'blob') |
95 | if (obj && obj.link) { |
96 | obs.assignedImages.put(msg.value.author, obj.link) |
97 | } |
98 | } |
99 | if (msg.value.content.description) { |
100 | obs.assignedDescriptions.put(msg.value.author, msg.value.content.description) |
101 | } |
102 | } |
103 | }, () => { |
104 | sync.set(true) |
105 | }) |
106 | ) |
107 | |
108 | return obs |
109 | } |
110 | |
111 | function socialValue (lookup, id, yourId, fallback) { |
112 | return lookup[yourId] || lookup[id] || highestRank(lookup) || fallback || null |
113 | } |
114 | |
115 | function highestRank (lookup) { |
116 | var indexed = indexByValue(lookup) |
117 | var highestCount = 0 |
118 | var currentHighest = null |
119 | Object.keys(indexed).forEach((item) => { |
120 | var count = indexed[item].length |
121 | if (count > highestCount) { |
122 | highestCount = count |
123 | currentHighest = item |
124 | } |
125 | }) |
126 | return currentHighest |
127 | } |
128 | |
129 | function indexByValue (lookup) { |
130 | var result = {} |
131 | Object.keys(lookup).forEach((key) => { |
132 | var value = lookup[key] |
133 | if (!result[value]) { |
134 | result[value] = [] |
135 | } |
136 | result[value].push(key) |
137 | }) |
138 | return result |
139 | } |
140 |
Built with git-ssb-web