Commit 37af73bc5ddcbd3b63159caf24f253e95f6f3664
don't include replies in threads or rollups from people blocked by root message author
Matt McKegg committed on 7/8/2018, 2:50:11 AMParent: 632f74ad8a65960017ff438eaf47b2e90ccd7cc8
Files changed
contact/obs.js | changed |
feed/obs/thread.js | changed |
feed/pull/with-replies.js | changed |
message/sync/is-blocked.js | changed |
contact/obs.js | ||
---|---|---|
@@ -9,9 +9,9 @@ | ||
9 | 9 … | 'sbot.pull.stream': 'first' |
10 | 10 … | }) |
11 | 11 … | |
12 | 12 … | exports.gives = nest({ |
13 | - 'contact.obs': ['following', 'followers', 'blocking', 'blockers'], | |
13 … | + 'contact.obs': ['following', 'followers', 'blocking', 'blockers', 'raw'], | |
14 | 14 … | 'sbot.hook.publish': true |
15 | 15 … | }) |
16 | 16 … | |
17 | 17 … | exports.create = function (api) { |
@@ -31,9 +31,10 @@ | ||
31 | 31 … | |
32 | 32 … | following: (key) => matchingValueKeys(get(key, cache), true), |
33 | 33 … | followers: (key) => matchingValueKeys(get(key, reverseCache), true), |
34 | 34 … | blocking: (key) => matchingValueKeys(get(key, cache), false), |
35 | - blockers: (key) => matchingValueKeys(get(key, reverseCache), false) | |
35 … | + blockers: (key) => matchingValueKeys(get(key, reverseCache), false), | |
36 … | + raw: (key) => get(key, cache) | |
36 | 37 … | }, |
37 | 38 … | 'sbot.hook.publish': function (msg) { |
38 | 39 … | if (!isContact(msg)) return |
39 | 40 … |
feed/obs/thread.js | ||
---|---|---|
@@ -3,9 +3,9 @@ | ||
3 | 3 … | var ref = require('ssb-ref') |
4 | 4 … | var isBlog = require('scuttle-blog/isBlog') |
5 | 5 … | var Blog = require('scuttle-blog') |
6 | 6 … | |
7 | -var { Array: MutantArray, Value, map, computed, concat } = require('mutant') | |
7 … | +var { Array: MutantArray, Value, map, computed, concat, ProxyCollection } = require('mutant') | |
8 | 8 … | |
9 | 9 … | exports.needs = nest({ |
10 | 10 … | 'backlinks.obs.for': 'first', |
11 | 11 … | 'sbot.async.get': 'first', |
@@ -23,46 +23,49 @@ | ||
23 | 23 … | function thread (rootId, { branch } = {}) { |
24 | 24 … | if (!ref.isLink(rootId)) throw new Error('an id must be specified') |
25 | 25 … | var sync = Value(false) |
26 | 26 … | var { isBlocked, root } = api.message.sync |
27 … | + var replies = ProxyCollection() | |
27 | 28 … | |
28 | 29 … | var prepend = MutantArray() |
29 | 30 … | api.sbot.async.get(rootId, (err, value) => { |
31 … | + var rootMessage = null | |
30 | 32 … | if (!err) { |
31 | - var msg = unboxIfNeeded({key: rootId, value}) | |
32 | - if (isBlocked(msg)) msg.isBlocked = true | |
33 … | + rootMessage = unboxIfNeeded({key: rootId, value}) | |
34 … | + if (isBlocked(rootMessage)) rootMessage.isBlocked = true | |
33 | 35 … | |
34 | - if (isBlog(msg)) { | |
36 … | + if (isBlog(rootMessage)) { | |
35 | 37 … | // resolve the blog body before returning |
36 | - Blog(api.sbot.obs.connection).async.get(msg, (err, result) => { | |
38 … | + Blog(api.sbot.obs.connection).async.get(rootMessage, (err, result) => { | |
37 | 39 … | if (!err) { |
38 | - msg.body = result.body | |
39 | - prepend.push(Value(msg)) | |
40 … | + rootMessage.body = result.body | |
41 … | + prepend.push(Value(rootMessage)) | |
40 | 42 … | sync.set(true) |
41 | 43 … | } |
42 | 44 … | }) |
43 | 45 … | } else { |
44 | 46 … | sync.set(true) |
45 | - prepend.push(Value(msg)) | |
47 … | + prepend.push(Value(rootMessage)) | |
46 | 48 … | } |
47 | 49 … | } else { |
48 | 50 … | sync.set(true) |
49 | 51 … | } |
52 … | + | |
53 … | + // calcaulate after message has been resolved so that we can check if thread author blocks the reply | |
54 … | + // wrap computed in a map to turn into individual observables | |
55 … | + replies.set(map(computed(backlinks, (msgs) => { | |
56 … | + return sort(msgs.filter(msg => { | |
57 … | + const { type, branch } = msg.value.content | |
58 … | + return type !== 'vote' && !isBlocked(msg, rootMessage) && (root(msg) === rootId || matchAny(branch, rootId)) | |
59 … | + })) | |
60 … | + }), x => Value(x), { | |
61 … | + // avoid refresh of entire list when items added | |
62 … | + comparer: (a, b) => a === b | |
63 … | + })) | |
50 | 64 … | }) |
51 | 65 … | |
52 | 66 … | var backlinks = api.backlinks.obs.for(rootId) |
53 | 67 … | |
54 | - // wrap computed in a map to turn into individual observables | |
55 | - var replies = map(computed(backlinks, (msgs) => { | |
56 | - return sort(msgs.filter(msg => { | |
57 | - const { type, branch } = msg.value.content | |
58 | - return type !== 'vote' && !isBlocked(msg) && (root(msg) === rootId || matchAny(branch, rootId)) | |
59 | - })) | |
60 | - }), x => Value(x), { | |
61 | - // avoid refresh of entire list when items added | |
62 | - comparer: (a, b) => a === b | |
63 | - }) | |
64 | - | |
65 | 68 … | // append the root message to the sorted replies list |
66 | 69 … | // ------------------------- |
67 | 70 … | // concat preserves the individual observable messages so that clients don't need to |
68 | 71 … | // rerender the entire list when an item is added (map will only be called for new items) |
feed/pull/with-replies.js | ||
---|---|---|
@@ -18,9 +18,9 @@ | ||
18 | 18 … | // use global backlinks cache |
19 | 19 … | var backlinks = api.backlinks.obs.for(rootMessage.key) |
20 | 20 … | onceTrue(backlinks.sync, () => { |
21 | 21 … | var replies = resolve(backlinks).filter(msg => { |
22 | - return api.message.sync.root(msg) === rootMessage.key && !api.message.sync.isBlocked(msg) | |
22 … | + return api.message.sync.root(msg) === rootMessage.key && !api.message.sync.isBlocked(msg, rootMessage) | |
23 | 23 … | }) |
24 | 24 … | cb(null, extend(rootMessage, { replies })) |
25 | 25 … | }) |
26 | 26 … | }) |
message/sync/is-blocked.js | |||
---|---|---|---|
@@ -3,18 +3,27 @@ | |||
3 | 3 … | exports.gives = nest('message.sync.isBlocked') | |
4 | 4 … | ||
5 | 5 … | exports.needs = nest({ | |
6 | 6 … | 'contact.obs.blocking': 'first', | |
7 … | + 'contact.obs.raw': 'first', | ||
7 | 8 … | 'keys.sync.id': 'first' | |
8 | 9 … | }) | |
9 | 10 … | ||
10 | 11 … | exports.create = function (api) { | |
11 | 12 … | var cache = null | |
12 | 13 … | ||
13 | - return nest('message.sync.isBlocked', function isBlockedMessage (msg) { | ||
14 … | + return nest('message.sync.isBlocked', function isBlockedMessage (msg, rootMessage) { | ||
14 | 15 … | if (!cache) { | |
15 | 16 … | cache = api.contact.obs.blocking(api.keys.sync.id()) | |
16 | 17 … | } | |
17 | 18 … | ||
19 … | + if (rootMessage) { | ||
20 … | + // check if the author of the root message blocks the author of the message | ||
21 … | + var rawContact = api.contact.obs.raw(rootMessage.value.author) | ||
22 … | + if (rawContact()[msg.value.author] === false) { | ||
23 … | + return true | ||
24 … | + } | ||
25 … | + } | ||
26 … | + | ||
18 | 27 … | return cache().includes(msg.value.author) | |
19 | 28 … | }) | |
20 | 29 … | } |
Built with git-ssb-web