git ssb

10+

Matt McKegg / patchwork



Tree: 35b3aece890ce9483986f9581925792a5bcd647d

Files: 35b3aece890ce9483986f9581925792a5bcd647d / plugs / message / html / layout / default.js

4523 bytesRaw
1const { h, computed, Value, when } = require('mutant')
2var nest = require('depnest')
3var ref = require('ssb-ref')
4var ExpanderHook = require('../../../../lib/expander-hook')
5
6exports.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
24exports.gives = nest('message.html.layout')
25
26exports.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
142function last (array) {
143 if (Array.isArray(array)) {
144 return array[array.length - 1]
145 } else {
146 return array
147 }
148}
149
150function toggleAndTrack (param) {
151 return {
152 handleEvent: handleToggle,
153 param
154 }
155}
156
157function 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