git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: eb221fb4cfcd450d2458461fa14d5079ee0a3bd7

Files: eb221fb4cfcd450d2458461fa14d5079ee0a3bd7 / feed / obs / thread.js

3315 bytesRaw
1var nest = require('depnest')
2var sort = require('ssb-sort')
3var ref = require('ssb-ref')
4var { Array: MutantArray, Value, map, concat, computed } = require('mutant')
5
6exports.needs = nest({
7 'backlinks.obs.for': 'first',
8 'sbot.async.get': 'first',
9 'message.sync.unbox': 'first',
10 'message.sync.root': 'first',
11 'contact.obs.blocking': 'first',
12 'keys.sync.id': 'first'
13})
14
15exports.gives = nest('feed.obs.thread')
16
17exports.create = function (api) {
18 return nest('feed.obs.thread', thread)
19
20 function thread (rootId, { branch } = {}) {
21 if (!ref.isLink(rootId)) throw new Error('an id must be specified')
22 var sync = Value(false)
23
24 const blocking = api.contact.obs.blocking(api.keys.sync.id())
25
26 var prepend = MutantArray()
27 api.sbot.async.get(rootId, (err, value) => {
28 sync.set(true)
29 if (!err) {
30 var msg = unboxIfNeeded({key: rootId, value})
31 if (blocking().includes(msg.value.author)) msg.isBlocked = true
32 prepend.push(Value(msg))
33 }
34 })
35
36 var backlinks = api.backlinks.obs.for(rootId)
37 var replies = map(computed(backlinks, (msgs) => {
38 return msgs.filter(msg => {
39 return !blocking().includes(msg.value.author) &&
40 msg.value.content.type !== 'vote' && (
41 api.message.sync.root(msg) === rootId ||
42 matchAny(msg.value.content.branch, rootId)
43 )
44 })
45 }), x => Value(x), {
46 // avoid refresh of entire list when items added
47 comparer: (a, b) => a === b
48 })
49
50 var messages = concat([prepend, replies])
51
52 var result = {
53 messages,
54 lastId: computed(messages, (messages) => {
55 var branches = sort.heads(messages)
56 if (branches.length <= 1) {
57 branches = branches[0]
58 }
59 return branches
60 }),
61 rootId: computed(messages, (messages) => {
62 if (branch && messages.length) {
63 return messages[0].value.content.root
64 } else {
65 return rootId
66 }
67 }),
68 branchId: computed(messages, (messages) => {
69 if (branch) return rootId
70 }),
71 previousKey: function (msg) {
72 return PreviousKey(result.messages, msg)
73 },
74 isPrivate: computed(messages, msgs => {
75 if (!msgs[0]) return false
76
77 return msgs[0].value.private || false
78 }),
79 channel: computed(messages, msgs => {
80 if (!msgs[0]) return undefined
81
82 return msgs[0].value.content.channel
83 }),
84 recps: computed(messages, msgs => {
85 if (!msgs[0]) return undefined
86
87 return msgs[0].value.content.recps
88 })
89 }
90
91 result.sync = computed([backlinks.sync, sync], (a, b) => a && b, {idle: true})
92 return result
93 }
94
95 function unboxIfNeeded (msg) {
96 if (msg.value && typeof msg.value.content === 'string') {
97 return api.message.sync.unbox(msg) || msg
98 } else {
99 return msg
100 }
101 }
102}
103
104function PreviousKey (collection, item) {
105 return computed(collection, (c) => {
106 var index = collection.indexOf(item)
107 if (~index) {
108 var previous = c[index - 1]
109 if (previous) {
110 return previous.key
111 }
112 }
113 })
114}
115
116function matchAny (valueOrArray, compare) {
117 if (valueOrArray === compare) {
118 return true
119 } else if (Array.isArray(valueOrArray)) {
120 return valueOrArray.includes(compare)
121 }
122}
123

Built with git-ssb-web