git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: 40c2f3dae32d12b6a79216ecb01df3cf7c57ce4b

Files: 40c2f3dae32d12b6a79216ecb01df3cf7c57ce4b / feed / obs / thread.js

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

Built with git-ssb-web