git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Tree: 8b4e456e87cad1c31bf2022137e937fe3a47c2ad

Files: 8b4e456e87cad1c31bf2022137e937fe3a47c2ad / modules / page / html / render / message.js

4243 bytesRaw
1var { h, when, map, Proxy, Struct, Value, computed, watch } = require('mutant')
2var nest = require('depnest')
3var ref = require('ssb-ref')
4var AnchorHook = require('../../../../lib/anchor-hook')
5
6exports.needs = nest({
7 'keys.sync.id': 'first',
8 'feed.obs.thread': 'first',
9 'message.sync.unbox': 'first',
10 'message.sync.root': 'first',
11 'message.html': {
12 render: 'first',
13 compose: 'first'
14 },
15 'sbot.async.get': 'first',
16 'intl.sync.i18n': 'first',
17 'message.html.missing': 'first'
18})
19
20exports.gives = nest('page.html.render')
21
22exports.create = function (api) {
23 const i18n = api.intl.sync.i18n
24 return nest('page.html.render', function (id) {
25 if (!ref.isMsg(id)) return
26 var loader = h('div', {className: 'Loading -large'})
27
28 var result = Proxy(loader)
29 var anchor = Value()
30
31 var meta = Struct({
32 type: 'post',
33 root: Proxy(id),
34 branch: Proxy(id),
35 reply: Value(undefined),
36 channel: Value(undefined),
37 recps: Value(undefined)
38 })
39
40 var compose = api.message.html.compose({
41 meta,
42 isPrivate: when(meta.recps, true),
43 shrink: false,
44 hooks: [
45 AnchorHook('reply', anchor, (el) => el.focus())
46 ],
47 placeholder: when(meta.recps, i18n('Write a private reply'), i18n('Write a public reply'))
48 })
49
50 api.sbot.async.get(id, (err, value) => {
51 if (err) {
52 return result.set(h('PageHeading', [
53 h('h1', i18n('Cannot load thead'))
54 ]))
55 }
56
57 if (typeof value.content === 'string') {
58 value = api.message.sync.unbox(value)
59 }
60
61 if (!value) {
62 return result.set(h('PageHeading', [
63 h('h1', i18n('Cannot display message.'))
64 ]))
65 }
66
67 // what happens in private stays in private!
68 meta.recps.set(value.content.recps)
69
70 var author = value.author
71 var root = api.message.sync.root({key: id, value}) || id
72 var isReply = id !== root
73 var thread = api.feed.obs.thread(id, {branch: isReply})
74
75 meta.channel.set(value.content.channel)
76 meta.root.set(root || thread.rootId)
77
78 // if root thread, reply to last post
79 meta.branch.set(isReply ? thread.branchId : thread.lastId)
80
81 var container = h('Thread', [
82 h('div.messages', [
83 when(thread.branchId, h('a.full', {href: thread.rootId, anchor: id}, [i18n('View full thread')])),
84 map(thread.messages, (msg) => {
85 return computed([msg, thread.previousKey(msg)], (msg, previousId) => {
86 return h('div', {
87 hooks: [AnchorHook(msg.key, anchor, showContext)]
88 }, [
89 msg.key !== id ? api.message.html.missing(last(msg.value.content.branch), msg) : null,
90 api.message.html.render(msg, {
91 pageId: id,
92 previousId,
93 includeForks: msg.key !== id,
94 includeReferences: true
95 })
96 ])
97 })
98 }, {
99 maxTime: 5,
100 idle: true
101 })
102 ]),
103 compose
104 ])
105 result.set(when(thread.sync, container, loader))
106
107 watch(anchor, (anchor) => {
108 if (anchor === 'reply') {
109 meta.reply.set([author])
110 } else {
111 meta.reply.set(undefined)
112 }
113 })
114 })
115
116 var view = h('div', {className: 'SplitView'}, [
117 h('div.main', [
118 result
119 ])
120 ])
121
122 view.setAnchor = function (value) {
123 anchor.set(value)
124 }
125
126 return view
127 })
128}
129
130function showContext (element) {
131 var scrollParent = getScrollParent(element)
132 if (scrollParent) {
133 // ensure context is visible
134 scrollParent.scrollTop = Math.max(0, scrollParent.scrollTop - 100)
135 }
136}
137
138function getScrollParent (element) {
139 while (element.parentNode) {
140 if (element.parentNode.scrollTop > 10 && isScroller(element.parentNode)) {
141 return element.parentNode
142 } else {
143 element = element.parentNode
144 }
145 }
146}
147
148function isScroller (element) {
149 var value = window.getComputedStyle(element)['overflow-y']
150 return (value === 'auto' || value === 'scroll')
151}
152
153function last (array) {
154 if (Array.isArray(array)) {
155 return array[array.length - 1]
156 } else {
157 return array
158 }
159}
160

Built with git-ssb-web