git ssb

2+

mixmix / ticktack



Tree: adca29179dee2177af6fefa725c91581ffef5395

Files: adca29179dee2177af6fefa725c91581ffef5395 / app / html / blogCard.js

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

Built with git-ssb-web