git ssb

2+

mixmix / ticktack



Tree: f1d5a7c472bb8e838a7fd395f59be8d473f8a872

Files: f1d5a7c472bb8e838a7fd395f59be8d473f8a872 / app / html / blogCard.js

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

Built with git-ssb-web