git ssb

2+

mixmix / ticktack



Tree: dd1d12954ae9c549f848026f96a4d9320f69e9e2

Files: dd1d12954ae9c549f848026f96a4d9320f69e9e2 / app / html / thread-card.js

2962 bytesRaw
1var h = require('mutant/h')
2const last = require('lodash/last')
3var nest = require('depnest')
4
5exports.gives = nest('app.html.threadCard', true)
6
7exports.needs = nest({
8 'keys.sync.id': 'first',
9 'history.sync.push': 'first',
10 'about.obs.name': 'first',
11 'about.html.image': 'first',
12 'message.html.markdown': 'first',
13 'translations.sync.strings': 'first'
14})
15
16function isString (s) {
17 return 'string' === typeof s
18}
19
20function firstLine (text) {
21 if(text.length < 80 && !~text.indexOf('\n')) return text
22
23 //get the first non-empty line
24 var line = text.trim().split('\n').shift().trim()
25
26 //always break on a space, so that links are preserved.
27 var i = line.indexOf(' ', 80)
28 var sample = line.substring(0, ~i ? i : line.length)
29
30 const ellipsis = (sample.length < line.length) ? '...' : ''
31 return sample + ellipsis
32}
33
34function trimLeadingMentions (str) {
35 return str.replace(/^(\s*\[@[^\)]+\)\s*)*/, '')
36 // deletes any number of pattern " [@...) " from start of line
37}
38
39function hasBrokenLink (str) {
40 return /\[[^\]]*\]\([^\)]*$/.test(str)
41 // matches "[name](start_of_link"
42}
43
44
45exports.create = function (api) {
46
47 //render the icon for a thread.
48 //it would be more depjecty to split this
49 //into two methods, one in a private plugin
50 //one in a channel plugin
51 function threadIcon (msg) {
52 if(msg.value.private) {
53 const myId = api.keys.sync.id()
54
55 return msg.value.content.recps
56 .map(link => isString(link) ? link : link.link)
57 .filter(link => link !== myId)
58 .map(api.about.html.image)
59 }
60 else if(msg.value.content.channel)
61 return '#'+msg.value.content.channel
62 }
63
64
65 // REFACTOR: move this to a template?
66 function buildRecipientNames (thread) {
67 const myId = api.keys.sync.id()
68
69 return thread.value.content.recps
70 .map(link => isString(link) ? link : link.link)
71 .filter(link => link !== myId)
72 .map(api.about.obs.name)
73 }
74
75 function link(location) {
76 return {'ev-click': () => api.history.sync.push(location)}
77 }
78
79 function subject (msg) {
80 const { subject, text } = msg.value.content
81 return api.message.html.markdown(firstLine(subject|| text))
82 }
83
84 return {app: {html: {threadCard: function (thread, opts = {}) {
85 var strings = api.translations.sync.strings()
86
87 if(!thread.value) return
88 if(!thread.value.content.text) return
89
90 const subjectEl = h('div.subject', [
91 opts.nameRecipients
92 ? h('div.recps', buildRecipientNames(thread).map(recp => h('div.recp', recp)))
93 : null,
94 subject(thread)
95 ])
96
97 const lastReply = thread.replies && last(thread.replies)
98 const replyEl = lastReply
99 ? h('div.reply', [
100 h('div.replySymbol', strings.replySymbol),
101 subject(lastReply)
102 ])
103 : null
104
105 return h('div.thread', link(thread), [
106 h('div.context', threadIcon(thread)),
107 h('div.content', [
108 subjectEl,
109 replyEl
110 ])
111 ])
112 }}}}
113}
114
115
116
117

Built with git-ssb-web