git ssb

16+

Dominic / patchbay



Tree: d3a0c5e302f7edc7a52b5002d4c9ad4f2a2d4df3

Files: d3a0c5e302f7edc7a52b5002d4c9ad4f2a2d4df3 / app / page / thread.js

2701 bytesRaw
1const { h, Struct, Value, when, map, resolve, onceTrue } = require('mutant')
2const nest = require('depnest')
3const { isMsg, isFeed } = require('ssb-ref')
4
5exports.gives = nest('app.page.thread')
6
7exports.needs = nest({
8 'about.html.avatar': 'first',
9 'app.html.scroller': 'first',
10 'contact.obs.following': 'first',
11 'feed.obs.thread': 'first',
12 'keys.sync.id': 'first',
13 message: {
14 html: {
15 compose: 'first',
16 render: 'first'
17 },
18 'async.name': 'first',
19 'sync.unbox': 'first'
20 },
21 sbot: {
22 'async.get': 'first',
23 'pull.links': 'first'
24 }
25})
26
27exports.create = function (api) {
28 return nest('app.page.thread', threadPage)
29
30 function threadPage ({ msg }) {
31 const myId = api.keys.sync.id()
32 const ImFollowing = api.contact.obs.following(myId)
33 const { messages, isPrivate, rootId, lastId, channel, recps } = api.feed.obs.thread(msg)
34 const meta = Struct({
35 type: 'post',
36 root: rootId,
37 branch: lastId,
38 channel,
39 recps
40 })
41 const contactWarning = Value(false)
42 const header = when(isPrivate, [
43 h('section.recipients', map(recps, r => {
44 const id = isFeed(r) ? r : r.link
45
46 var className
47 if (contactIsTrouble(id)) {
48 className = 'warning'
49 contactWarning.set(true)
50 }
51 return h('div', { className }, api.about.html.avatar(id))
52 })),
53 when(contactWarning,
54 h('section.info -warning', 'There is a person in this thread you do not follow (bordered in red). If you think you know this person it might be worth checking their profile to confirm they are who they say they are.'),
55 h('section.info', 'These are the other participants in this thread. Once a private thread is started you cannot add people to it.')
56 )
57 ])
58 function contactIsTrouble (id) {
59 if (id === myId) return false
60 if (Array.from(ImFollowing()).includes(id)) return false
61 return true
62 }
63
64 const composer = api.message.html.compose({
65 meta,
66 placeholder: 'Write a reply',
67 shrink: false
68 })
69 const content = h('section.content', map(messages, m => {
70 return api.message.html.render(resolve(m), {pageId: msg})
71 }))
72 const { container } = api.app.html.scroller({ prepend: header, content, append: composer })
73
74 container.classList.add('Thread')
75 container.id = msg
76 container.title = msg
77 api.message.async.name(msg, (err, name) => {
78 if (err) throw err
79 container.title = name
80 })
81
82 onceTrue(channel, ch => {
83 const channelInput = composer.querySelector('input')
84 channelInput.value = `#${ch}`
85 channelInput.disabled = true
86 })
87
88 return container
89 }
90}
91
92

Built with git-ssb-web