Files: 6e309f8eeaa5f795ea26b439be0f4fcf4c4103a4 / plugs / message / html / layout / default.js
4523 bytesRaw
1 | const { h, computed, Value, when } = require('mutant') |
2 | var nest = require('depnest') |
3 | var ref = require('ssb-ref') |
4 | var ExpanderHook = require('../../../../lib/expander-hook') |
5 | |
6 | exports.needs = nest({ |
7 | 'profile.html.person': 'first', |
8 | 'message.obs.backlinks': 'first', |
9 | 'message.obs.name': 'first', |
10 | 'message.obs.author': 'first', |
11 | 'contact.obs.following': 'first', |
12 | 'keys.sync.id': 'first', |
13 | 'message.html': { |
14 | link: 'first', |
15 | meta: 'map', |
16 | action: 'map', |
17 | timestamp: 'first', |
18 | backlinks: 'first' |
19 | }, |
20 | 'about.html.image': 'first', |
21 | 'intl.sync.i18n': 'first' |
22 | }) |
23 | |
24 | exports.gives = nest('message.html.layout') |
25 | |
26 | exports.create = function (api) { |
27 | const i18n = api.intl.sync.i18n |
28 | var yourFollows = null |
29 | |
30 | // to get sync follows |
31 | setImmediate(() => { |
32 | var yourId = api.keys.sync.id() |
33 | yourFollows = api.contact.obs.following(yourId) |
34 | }) |
35 | |
36 | return nest('message.html.layout', layout) |
37 | |
38 | function layout (msg, {layout, previousId, priority, content, includeReferences = false, includeForks = true, compact = false}) { |
39 | if (!(layout === undefined || layout === 'default')) return |
40 | |
41 | var classList = ['Message'] |
42 | var replyInfo = null |
43 | |
44 | var needsExpand = Value(false) |
45 | var expanded = Value(false) |
46 | |
47 | // new message previews shouldn't contract |
48 | if (!msg.key) expanded.set(true) |
49 | |
50 | if (msg.value.content.root) { |
51 | classList.push('-reply') |
52 | var branch = msg.value.content.branch |
53 | if (branch) { |
54 | if (!previousId || (previousId && last(branch) && previousId !== last(branch))) { |
55 | replyInfo = h('span', [i18n('in reply to '), api.message.html.link(last(branch))]) |
56 | } |
57 | } |
58 | } else if (msg.value.content.project) { |
59 | replyInfo = h('span', [i18n('on '), api.message.html.link(msg.value.content.project)]) |
60 | } |
61 | |
62 | if (yourFollows && yourFollows().includes(msg.value.author)) { |
63 | classList.push('-following') |
64 | } |
65 | |
66 | if (compact) { |
67 | classList.push('-compact') |
68 | } |
69 | |
70 | if (priority === 2) { |
71 | classList.push('-new') |
72 | } |
73 | |
74 | if (priority === 1) { |
75 | classList.push('-unread') |
76 | } |
77 | |
78 | return h('div', { |
79 | classList |
80 | }, [ |
81 | messageHeader(msg, { replyInfo, priority, needsExpand, expanded }), |
82 | h('section', { |
83 | classList: [ when(expanded, '-expanded') ], |
84 | hooks: [ ExpanderHook(needsExpand) ] |
85 | }, [content]), |
86 | computed(msg.key, (key) => { |
87 | if (ref.isMsg(key)) { |
88 | return h('footer', [ |
89 | when(needsExpand, h('div.expander', { |
90 | classList: when(expanded, null, '-truncated') |
91 | }, [ |
92 | h('a', { |
93 | href: '#', |
94 | 'ev-click': toggleAndTrack(expanded) |
95 | }, when(expanded, i18n('See less'), i18n('See more'))) |
96 | ])), |
97 | h('div.actions', [ |
98 | api.message.html.action(msg) |
99 | ]) |
100 | ]) |
101 | } |
102 | }), |
103 | api.message.html.backlinks(msg, {includeReferences, includeForks}) |
104 | ]) |
105 | |
106 | // scoped |
107 | |
108 | function messageHeader (msg, {replyInfo, priority}) { |
109 | var yourId = api.keys.sync.id() |
110 | var additionalMeta = [] |
111 | if (priority === 2) { |
112 | additionalMeta.push(h('span.flag -new', {title: i18n('New Message')})) |
113 | } else if (priority === 1) { |
114 | additionalMeta.push(h('span.flag -unread', {title: i18n('Unread Message')})) |
115 | } |
116 | |
117 | return h('header', [ |
118 | h('div.main', [ |
119 | h('a.avatar', {href: `${msg.value.author}`}, [ |
120 | api.about.html.image(msg.value.author) |
121 | ]), |
122 | h('div.main', [ |
123 | h('div.name', [ |
124 | api.profile.html.person(msg.value.author), |
125 | msg.value.author === yourId ? [' ', h('span.you', {}, i18n('(you)'))] : null |
126 | ]), |
127 | h('div.meta', [ |
128 | api.message.html.timestamp(msg), ' ', |
129 | replyInfo |
130 | ]) |
131 | ]) |
132 | ]), |
133 | h('div.meta', [ |
134 | api.message.html.meta(msg), |
135 | additionalMeta |
136 | ]) |
137 | ]) |
138 | } |
139 | } |
140 | } |
141 | |
142 | function last (array) { |
143 | if (Array.isArray(array)) { |
144 | return array[array.length - 1] |
145 | } else { |
146 | return array |
147 | } |
148 | } |
149 | |
150 | function toggleAndTrack (param) { |
151 | return { |
152 | handleEvent: handleToggle, |
153 | param |
154 | } |
155 | } |
156 | |
157 | function handleToggle (ev) { |
158 | this.param.set(!this.param()) |
159 | if (!this.param()) { |
160 | ev.target.scrollIntoViewIfNeeded() |
161 | |
162 | // HACK: due to a browser bug, sometimes the body gets affected!? |
163 | // Why not just hack it!!! |
164 | if (document.body.scrollTop > 0) { |
165 | document.body.scrollTop = 0 |
166 | } |
167 | } |
168 | } |
169 |
Built with git-ssb-web