about/obs.jsView |
---|
1 | | -var {Value, Struct, computed} = require('mutant') |
2 | | -var Abortable = require('pull-abortable') |
| 1 … | +var {Value, Struct, Dict, computed} = require('mutant') |
| 2 … | +var pullPause = require('pull-pause') |
3 | 3 … | var pull = require('pull-stream') |
4 | 4 … | var msgs = require('ssb-msgs') |
5 | | -var visualize = require('visualize-buffer') |
6 | 5 … | var nest = require('depnest') |
| 6 … | +var colorHash = new (require('color-hash'))() |
7 | 7 … | |
8 | 8 … | exports.needs = nest({ |
9 | | - 'sbot.pull.userFeed': 'first', |
10 | | - 'blob.sync.url': 'first' |
| 9 … | + 'sbot.pull.links': 'first', |
| 10 … | + 'blob.sync.url': 'first', |
| 11 … | + 'keys.sync.id': 'first' |
11 | 12 … | }) |
12 | 13 … | exports.gives = nest({ |
13 | 14 … | 'about.obs': [ |
14 | 15 … | 'name', |
| 16 … | + 'description', |
15 | 17 … | 'image', |
16 | | - 'imageUrl' |
| 18 … | + 'imageUrl', |
| 19 … | + 'names', |
| 20 … | + 'images', |
| 21 … | + 'color' |
17 | 22 … | ] |
18 | 23 … | }) |
19 | 24 … | |
20 | 25 … | exports.create = function (api) { |
22 | 27 … | |
23 | 28 … | return nest({ |
24 | 29 … | 'about.obs': { |
25 | 30 … | name: (id) => get(id).displayName, |
| 31 … | + description: (id) => get(id).description, |
26 | 32 … | image: (id) => get(id).image, |
27 | | - imageUrl: (id) => get(id).imageUrl |
| 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)) |
28 | 38 … | } |
29 | 39 … | }) |
30 | 40 … | |
31 | 41 … | function get (id) { |
36 | 46 … | } |
37 | 47 … | } |
38 | 48 … | |
39 | 49 … | function About (api, id) { |
40 | | - |
| 50 … | + var pauser = pullPause((paused) => {}) |
41 | 51 … | |
42 | | - var fallbackImageUrl = genImage(id) |
| 52 … | + |
| 53 … | + var fallbackImageUrl = 'data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==' |
43 | 54 … | |
| 55 … | + var sync = Value(false) |
| 56 … | + var yourId = api.keys.sync.id() |
| 57 … | + |
44 | 58 … | var obs = Struct({ |
45 | | - displayName: Value(id.slice(1, 10)), |
46 | | - image: Value(genImage(id)) |
| 59 … | + assignedNames: Dict(), |
| 60 … | + assignedImages: Dict(), |
| 61 … | + assignedDescriptions: Dict() |
| 62 … | + }, { |
| 63 … | + onListen: pauser.resume, |
| 64 … | + onUnlisten: pauser.pause |
47 | 65 … | }) |
48 | 66 … | |
49 | | - obs.imageUrl = computed(obs.image, (image) => { |
50 | | - var obj = msgs.link(image, 'blob') |
51 | | - if (obj) { |
52 | | - return api.blob.sync.url(obj.link) |
| 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) |
53 | 78 … | } else { |
54 | 79 … | return fallbackImageUrl |
55 | 80 … | } |
56 | 81 … | }) |
57 | 82 … | |
58 | | - var hasName = false |
59 | | - var hasImage = false |
60 | | - |
61 | | - var abortable = Abortable() |
62 | | - |
63 | | - |
64 | 83 … | pull( |
65 | | - api.sbot.pull.userFeed({reverse: true, id}), |
66 | | - abortable, |
67 | | - pull.drain(function (item) { |
68 | | - update(item) |
69 | | - if (hasName && obs.image()) { |
70 | | - abortable.abort() |
| 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 … | + } |
71 | 102 … | } |
| 103 … | + }, () => { |
| 104 … | + sync.set(true) |
72 | 105 … | }) |
73 | 106 … | ) |
74 | 107 … | |
75 | | - |
76 | | - pull( |
77 | | - api.sbot.pull.userFeed({old: false, id}), |
78 | | - pull.drain(update) |
79 | | - ) |
80 | | - |
81 | 108 … | return obs |
| 109 … | +} |
82 | 110 … | |
83 | | - |
| 111 … | +function socialValue (lookup, id, yourId, fallback) { |
| 112 … | + return lookup[yourId] || lookup[id] || highestRank(lookup) || fallback || null |
| 113 … | +} |
84 | 114 … | |
85 | | - function update (item) { |
86 | | - if (item.value && item.value.content.type === 'about' && item.value.content.about === id) { |
87 | | - if (item.value.content.name) { |
88 | | - if (!hasName || hasName < item.value.timestamp) { |
89 | | - hasName = item.value.timestamp |
90 | | - obs.displayName.set(item.value.content.name) |
91 | | - } |
92 | | - } |
93 | | - if (item.value.content.image) { |
94 | | - if (!hasImage || hasImage < item.value.timestamp) { |
95 | | - hasImage = item.value.timestamp |
96 | | - obs.image.set(item.value.content.image) |
97 | | - } |
98 | | - } |
| 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 |
99 | 124 … | } |
100 | | - } |
| 125 … | + }) |
| 126 … | + return currentHighest |
101 | 127 … | } |
102 | 128 … | |
103 | | -function genImage (id) { |
104 | | - return visualize(new Buffer(id.substring(1), 'base64'), 256).src |
| 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 |
105 | 139 … | } |