Commit 94a864d41161acab3c2937769986c0037321d093
contact.obs: use new reducer pattern from about.obs
Matt McKegg committed on 6/20/2017, 4:47:09 AMParent: 043b2e20476159dcff94dd46890be1c353e9132e
Files changed
contact/obs.js | changed |
contact/obs.js | ||
---|---|---|
@@ -1,7 +1,6 @@ | ||
1 | 1 … | var nest = require('depnest') |
2 | -var {Value, onceTrue, computed} = require('mutant') | |
3 | -var defer = require('pull-defer') | |
2 … | +var {Value, computed} = require('mutant') | |
4 | 3 … | var pull = require('pull-stream') |
5 | 4 … | var ref = require('ssb-ref') |
6 | 5 … | |
7 | 6 … | exports.needs = nest({ |
@@ -19,22 +18,23 @@ | ||
19 | 18 … | var sync = Value(false) |
20 | 19 … | |
21 | 20 … | return nest({ |
22 | 21 … | 'contact.obs': { |
23 | - following: (id) => get(id).following, | |
24 | - followers: (id) => get(id).followers | |
22 … | + following: (id) => values(get(id), 'following', true), | |
23 … | + followers: (id) => values(get(id), 'followers', true) | |
25 | 24 … | }, |
26 | 25 … | 'sbot.hook.publish': function (msg) { |
27 | 26 … | if (isContact(msg)) { |
27 … | + // HACK: make interface more responsive when sbot is busy | |
28 | 28 … | var source = msg.value.author |
29 | 29 … | var dest = msg.value.content.contact |
30 | 30 … | if (typeof msg.value.content.following === 'boolean') { |
31 | - get(source).push({ | |
31 … | + update(source, { | |
32 | 32 … | following: { |
33 | 33 … | [dest]: [msg.value.content] |
34 | 34 … | } |
35 | 35 … | }) |
36 | - get(dest).push({ | |
36 … | + update(dest, { | |
37 | 37 … | followers: { |
38 | 38 … | [source]: [msg.value.content] |
39 | 39 … | } |
40 | 40 … | }) |
@@ -42,16 +42,20 @@ | ||
42 | 42 … | } |
43 | 43 … | } |
44 | 44 … | }) |
45 | 45 … | |
46 … | + function values (state, key, compare) { | |
47 … | + var obs = computed([state, key, compare], getIds) | |
48 … | + obs.sync = sync | |
49 … | + return obs | |
50 … | + } | |
51 … | + | |
46 | 52 … | function loadCache () { |
47 | 53 … | pull( |
48 | 54 … | api.sbot.pull.stream(sbot => sbot.contacts.stream({live: true})), |
49 | 55 … | pull.drain(item => { |
50 | 56 … | for (var target in item) { |
51 | - if (ref.isFeed(target)) { | |
52 | - get(target).push(item[target]) | |
53 | - } | |
57 … | + if (ref.isFeed(target)) update(target, item[target]) | |
54 | 58 … | } |
55 | 59 … | |
56 | 60 … | if (!sync()) { |
57 | 61 … | sync.set(true) |
@@ -59,52 +63,40 @@ | ||
59 | 63 … | }) |
60 | 64 … | ) |
61 | 65 … | } |
62 | 66 … | |
67 … | + function update (id, values) { | |
68 … | + var state = get(id) | |
69 … | + var lastState = state() | |
70 … | + var changed = false | |
71 … | + for (var key in values) { | |
72 … | + var valuesForKey = lastState[key] = lastState[key] || {} | |
73 … | + for (var dest in values[key]) { | |
74 … | + var value = values[key][dest] | |
75 … | + if (!valuesForKey[dest] || value[1] > valuesForKey[dest][1] || !values[1] || !valuesForKey[dest[1]]) { | |
76 … | + valuesForKey[dest] = value | |
77 … | + changed = true | |
78 … | + } | |
79 … | + } | |
80 … | + } | |
81 … | + if (changed) { | |
82 … | + state.set(lastState) | |
83 … | + } | |
84 … | + } | |
85 … | + | |
63 | 86 … | function get (id) { |
64 | 87 … | if (!ref.isFeed(id)) throw new Error('Contact state requires an id!') |
65 | 88 … | if (!cacheLoading) { |
66 | 89 … | cacheLoading = true |
67 | 90 … | loadCache() |
68 | 91 … | } |
69 | 92 … | if (!cache[id]) { |
70 | - cache[id] = Contact(api, id, sync) | |
93 … | + cache[id] = Value({}) | |
71 | 94 … | } |
72 | 95 … | return cache[id] |
73 | 96 … | } |
74 | 97 … | } |
75 | 98 … | |
76 | -function Contact (api, id, sync) { | |
77 | - var state = Value({}) | |
78 | - return { | |
79 | - following: computedIds(state, 'following', true, sync), | |
80 | - followers: computedIds(state, 'followers', true, sync), | |
81 | - push: function (values) { | |
82 | - var lastState = state() | |
83 | - var changed = false | |
84 | - for (var key in values) { | |
85 | - var valuesForKey = lastState[key] = lastState[key] || {} | |
86 | - for (var dest in values[key]) { | |
87 | - var value = values[key][dest] | |
88 | - if (!valuesForKey[dest] || value[1] > valuesForKey[dest][1] || !values[1] || !valuesForKey[dest[1]]) { | |
89 | - valuesForKey[dest] = value | |
90 | - changed = true | |
91 | - } | |
92 | - } | |
93 | - } | |
94 | - if (changed) { | |
95 | - state.set(lastState) | |
96 | - } | |
97 | - } | |
98 | - } | |
99 | -} | |
100 | - | |
101 | -function computedIds (state, key, compare, sync) { | |
102 | - var obs = computed([state, key, true], getIds) | |
103 | - obs.sync = sync | |
104 | - return obs | |
105 | -} | |
106 | - | |
107 | 99 … | function getIds (state, key, compare) { |
108 | 100 … | var result = new Set() |
109 | 101 … | if (state[key]) { |
110 | 102 … | for (var dest in state[key]) { |
@@ -112,12 +104,10 @@ | ||
112 | 104 … | result.add(dest) |
113 | 105 … | } |
114 | 106 … | } |
115 | 107 … | } |
116 | - | |
117 | 108 … | return result |
118 | 109 … | } |
119 | 110 … | |
120 | 111 … | function isContact (msg) { |
121 | 112 … | return msg.value && msg.value.content && msg.value.content.type === 'contact' |
122 | 113 … | } |
123 | - |
Built with git-ssb-web