git ssb

2+

mixmix / ticktack



Tree: c579769220cc3a79b16cc065f3554b1a450038fd

Files: c579769220cc3a79b16cc065f3554b1a450038fd / app / html / blogCard.js

4106 bytesRaw
1var nest = require('depnest')
2var h = require('mutant/h')
3var isString= require('lodash/isString')
4var maxBy= require('lodash/maxBy')
5var marksum = require('markdown-summary')
6var markdown = require('ssb-markdown')
7var ref = require('ssb-ref')
8var htmlEscape = require('html-escape')
9
10function renderEmoji (emoji, url) {
11 if (!url) return ':' + emoji + ':'
12 return `
13 <img
14 src="${htmlEscape(url)}"
15 alt=":${htmlEscape(emoji)}:"
16 title=":${htmlEscape(emoji)}:"
17 class="emoji"
18 >
19 `
20}
21
22exports.gives = nest('app.html.blogCard', true)
23
24exports.needs = nest({
25 'keys.sync.id': 'first',
26 'history.sync.push': 'first',
27 'about.obs.color': 'first',
28 'about.obs.name': 'first',
29 'about.html.avatar': 'first',
30 'translations.sync.strings': 'first',
31 'unread.sync.isUnread': 'first',
32 // 'message.html.markdown': 'first',
33 'message.html.channel': 'first',
34 'message.html.timeago': 'first',
35 'blob.sync.url': 'first',
36 'emoji.sync.url': 'first'
37})
38
39exports.create = function (api) {
40
41 //render markdown, but don't support patchwork@2 style mentions or custom emoji right now.
42 function render (source) {
43 return markdown.block(source, {
44 emoji: (emoji) => {
45 return renderEmoji(emoji, api.emoji.sync.url(emoji))
46 },
47 toUrl: (id) => {
48 if (ref.isBlob(id)) return api.blob.sync.url(id)
49 return id
50 },
51 imageLink: (id) => id
52 })
53 }
54
55
56 //render the icon for a blog.
57 //it would be more depjecty to split this
58 //into two methods, one in a private plugin
59 //one in a channel plugin
60 function blogIcon (msg) {
61 if(msg.value.private) {
62 const myId = api.keys.sync.id()
63
64 return msg.value.content.recps
65 .map(link => isString(link) ? link : link.link)
66 .filter(link => link !== myId)
67 .map(link => api.about.html.avatar)
68 }
69 else if(msg.value.content.channel)
70 return '#'+msg.value.content.channel
71 }
72
73
74 // REFACTOR: move this to a template?
75 function buildRecipientNames (blog) {
76 const myId = api.keys.sync.id()
77
78 return blog.value.content.recps
79 .map(link => isString(link) ? link : link.link)
80 .filter(link => link !== myId)
81 .map(api.about.obs.name)
82 }
83
84 return nest('app.html.blogCard', (blog, opts = {}) => {
85 var strings = api.translations.sync.strings()
86
87 if(!blog.value) return
88 if('string' !== typeof blog.value.content.text) return
89
90 const lastReply = blog.replies && maxBy(blog.replies, r => r.timestamp)
91
92 const goToBlog = () => api.history.sync.push(blog)
93 const onClick = opts.onClick || goToBlog
94 const id = `${blog.key.replace(/[^a-z0-9]/gi, '')}` //-${JSON.stringify(opts)}`
95 // id is only here to help morphdom morph accurately
96
97 const { content, author } = blog.value
98
99 var img = h('Thumbnail')
100 var m = /\!\[[^]+\]\(([^\)]+)\)/.exec(marksum.image(content.text))
101 if(m) {
102 //Hey this works! fit an image into a specific size (see blog-card.mcss)
103 //centered, and scaled to fit the square (works with both landscape and portrait!)
104 //This is functional css not opinionated css, so all embedded.
105 img.style = 'background-image: url("'+api.blob.sync.url(m[1])+'"); background-position:center; background-size: cover;'
106 } else {
107 var style = { 'background-color': api.about.obs.color(blog.key) }
108 img = h('Thumbnail -empty', { style }, [
109 h('i.fa.fa-file-text-o')
110 ])
111 }
112
113 const title = render(marksum.title(content.text))
114 const summary = render(marksum.summary(content.text))
115
116 const className = blog.unread ? '-unread': ''
117
118 return h('BlogCard', { id, className, 'ev-click': onClick }, [
119 h('div.context', [
120 api.about.html.avatar(author, 'tiny'),
121 h('div.name', api.about.obs.name(author)),
122 api.message.html.timeago(blog)
123 ]),
124 h('div.content', [
125 img,
126 h('div.text', [
127 h('h2', {innerHTML: title}),
128 content.channel
129 ? api.message.html.channel(blog)
130 : '',
131 h('div.summary', {innerHTML: summary})
132 ])
133 ])
134 ])
135 })
136}
137
138
139

Built with git-ssb-web