Commit a69b107634854812d8fe243ff4f0ce3e4e19bd8c
Merge branch 'updates_msg' of https://github.com/Happy0/patchwork into Happy0-updates_msg
Matt McKegg committed on 10/19/2017, 2:41:02 AMParent: d03a610c77cee73a156ebe6e4fc1f7369d27fe9d
Parent: 56ec071bbd3b367a7e702487f671bc947642e52c
Files changed
modules/feed/html/rollup.js | ||
---|---|---|
@@ -20,8 +20,9 @@ | ||
20 | 20 | |
21 | 21 | exports.needs = nest({ |
22 | 22 | 'about.obs.name': 'first', |
23 | 23 | 'app.sync.externalHandler': 'first', |
24 | + 'message.html.canRender': 'first', | |
24 | 25 | 'message.html.render': 'first', |
25 | 26 | 'profile.html.person': 'first', |
26 | 27 | 'message.html.link': 'first', |
27 | 28 | 'message.sync.root': 'first', |
@@ -95,10 +96,14 @@ | ||
95 | 96 | }), |
96 | 97 | pull.drain((msg) => { |
97 | 98 | if (msg.value.content.type === 'vote') return |
98 | 99 | if (api.app.sync.externalHandler(msg)) return |
99 | - newSinceRefresh.add(msg.key) | |
100 | 100 | |
101 | + // Only increment the 'new since' for items that we render on | |
102 | + // the feed as otherwise the 'show <n> updates message' will be | |
103 | + // shown on new messages that patchwork cannot render | |
104 | + if (canRenderMessage(msg)) newSinceRefresh.add(msg.key) | |
105 | + | |
101 | 106 | if (updates() === 0 && msg.value.author === yourId && container.scrollTop < 20) { |
102 | 107 | refresh() |
103 | 108 | } else { |
104 | 109 | updates.set(newSinceRefresh.size) |
@@ -116,8 +121,12 @@ | ||
116 | 121 | result.reload = refresh |
117 | 122 | |
118 | 123 | return result |
119 | 124 | |
125 | + function canRenderMessage(msg) { | |
126 | + return api.message.html.canRender(msg); | |
127 | + } | |
128 | + | |
120 | 129 | function refresh () { |
121 | 130 | onceTrue(waitFor, () => { |
122 | 131 | if (abortLastFeed) abortLastFeed() |
123 | 132 | updates.set(0) |
plugs/message/html/render/about.js | ||
---|---|---|
@@ -16,68 +16,79 @@ | ||
16 | 16 | 'blob.sync.url': 'first', |
17 | 17 | 'intl.sync.i18n': 'first', |
18 | 18 | }) |
19 | 19 | |
20 | -exports.gives = nest('message.html.render') | |
20 | +exports.gives = nest('message.html', { | |
21 | + canRender: true, | |
22 | + render: true | |
23 | +}) | |
21 | 24 | |
22 | 25 | exports.create = function (api) { |
23 | 26 | const i18n = api.intl.sync.i18n |
24 | - return nest('message.html.render', function about (msg, opts) { | |
25 | - if (msg.value.content.type !== 'about') return | |
26 | - if (!ref.isFeed(msg.value.content.about)) return | |
27 | + return nest('message.html', { | |
28 | + canRender: isRenderable, | |
29 | + render: function (msg, opts) { | |
30 | + if (!isRenderable(msg)) return; | |
27 | 31 | |
28 | - var c = msg.value.content | |
29 | - var self = msg.value.author === c.about | |
32 | + var c = msg.value.content | |
33 | + var self = msg.value.author === c.about | |
30 | 34 | |
31 | - var miniContent = [] | |
32 | - var content = [] | |
35 | + var miniContent = [] | |
36 | + var content = [] | |
33 | 37 | |
34 | - if (c.name) { | |
35 | - var target = api.profile.html.person(c.about, c.name) | |
36 | - miniContent.push(computed([self, api.about.obs.name(c.about), c.name], (self, a, b) => { | |
37 | - if (self) { | |
38 | - return [i18n('self identifies as "'), target, '"'] | |
39 | - } else if (a === b) { | |
40 | - return [i18n('identified '), api.profile.html.person(c.about)] | |
41 | - } else { | |
42 | - return [i18n('identifies '), api.profile.html.person(c.about), i18n(' as "'), target, '"'] | |
38 | + if (c.name) { | |
39 | + var target = api.profile.html.person(c.about, c.name) | |
40 | + miniContent.push(computed([self, api.about.obs.name(c.about), c.name], (self, a, b) => { | |
41 | + if (self) { | |
42 | + return [i18n('self identifies as "'), target, '"'] | |
43 | + } else if (a === b) { | |
44 | + return [i18n('identified '), api.profile.html.person(c.about)] | |
45 | + } else { | |
46 | + return [i18n('identifies '), api.profile.html.person(c.about), i18n(' as "'), target, '"'] | |
47 | + } | |
48 | + })) | |
49 | + } | |
50 | + | |
51 | + if (c.image) { | |
52 | + if (!miniContent.length) { | |
53 | + var imageAction = self ? i18n('self assigned a display image') : [i18n('assigned a display image to '), api.profile.html.person(c.about)] | |
54 | + miniContent.push(imageAction) | |
43 | 55 | } |
44 | - })) | |
45 | - } | |
46 | 56 | |
47 | - if (c.image) { | |
48 | - if (!miniContent.length) { | |
49 | - var imageAction = self ? i18n('self assigned a display image') : [i18n('assigned a display image to '), api.profile.html.person(c.about)] | |
50 | - miniContent.push(imageAction) | |
57 | + content.push(h('a AboutImage', { | |
58 | + href: c.about | |
59 | + }, [ | |
60 | + h('img', {src: api.blob.sync.url(c.image)}) | |
61 | + ])) | |
51 | 62 | } |
52 | 63 | |
53 | - content.push(h('a AboutImage', { | |
54 | - href: c.about | |
55 | - }, [ | |
56 | - h('img', {src: api.blob.sync.url(c.image)}) | |
57 | - ])) | |
58 | - } | |
64 | + var elements = [] | |
59 | 65 | |
60 | - var elements = [] | |
66 | + if (miniContent.length) { | |
67 | + var element = api.message.html.layout(msg, extend({ | |
68 | + showActions: true, | |
69 | + miniContent, | |
70 | + content, | |
71 | + layout: 'mini' | |
72 | + }, opts)) | |
73 | + elements.push(api.message.html.decorate(element, { msg })) | |
74 | + } | |
61 | 75 | |
62 | - if (miniContent.length) { | |
63 | - var element = api.message.html.layout(msg, extend({ | |
64 | - showActions: true, | |
65 | - miniContent, | |
66 | - content, | |
67 | - layout: 'mini' | |
68 | - }, opts)) | |
69 | - elements.push(api.message.html.decorate(element, { msg })) | |
70 | - } | |
76 | + if (c.description) { | |
77 | + elements.push(api.message.html.decorate(api.message.html.layout(msg, extend({ | |
78 | + showActions: true, | |
79 | + miniContent: self ? i18n('self assigned a description') : [i18n('assigned a description to '), api.profile.html.person(c.about)], | |
80 | + content: api.message.html.markdown(c.description), | |
81 | + layout: 'mini' | |
82 | + }, opts)), { msg })) | |
83 | + } | |
71 | 84 | |
72 | - if (c.description) { | |
73 | - elements.push(api.message.html.decorate(api.message.html.layout(msg, extend({ | |
74 | - showActions: true, | |
75 | - miniContent: self ? i18n('self assigned a description') : [i18n('assigned a description to '), api.profile.html.person(c.about)], | |
76 | - content: api.message.html.markdown(c.description), | |
77 | - layout: 'mini' | |
78 | - }, opts)), { msg })) | |
85 | + return elements | |
79 | 86 | } |
87 | + }) | |
80 | 88 | |
81 | - return elements | |
82 | - }) | |
89 | + function isRenderable(msg) { | |
90 | + if (msg.value.content.type !== 'about') return undefined | |
91 | + else if (!ref.isFeed(msg.value.content.about)) return undefined | |
92 | + return true | |
93 | + } | |
83 | 94 | } |
plugs/message/html/render/attending.js | ||
---|---|---|
@@ -10,25 +10,40 @@ | ||
10 | 10 | }, |
11 | 11 | 'about.obs.latestValue': 'first' |
12 | 12 | }) |
13 | 13 | |
14 | -exports.gives = nest('message.html.render') | |
14 | +exports.gives = nest('message.html', { | |
15 | + canRender: true, | |
16 | + render: true | |
17 | +}) | |
15 | 18 | |
16 | -exports.create = function (api) { | |
17 | - return nest('message.html.render', function about (msg, opts) { | |
18 | - if (msg.value.content.type !== 'about') return | |
19 | - if (!ref.isMsg(msg.value.content.about)) return | |
20 | - if (!msg.value.content.attendee) return | |
21 | - if (msg.value.content.attendee.link !== msg.value.author) return | |
19 | +exports.create = function(api) { | |
20 | + return nest('message.html', { | |
21 | + canRender: isRenderable, | |
22 | + render: function about(msg, opts) { | |
23 | + if (!isRenderable(msg)) return | |
22 | 24 | |
23 | - var action = msg.value.content.attendee.remove ? `can't attend` : 'is attending' | |
24 | - var target = msg.value.content.about | |
25 | - var title = api.about.obs.latestValue(target, 'title') | |
26 | - var element = api.message.html.layout(msg, extend({ | |
27 | - showActions: true, | |
28 | - miniContent: [action, ' ', h('a', {href: target}, title)], | |
29 | - layout: 'mini' | |
30 | - }, opts)) | |
25 | + var action = msg.value.content.attendee.remove ? `can't attend` : 'is attending' | |
26 | + var target = msg.value.content.about | |
27 | + var title = api.about.obs.latestValue(target, 'title') | |
28 | + var element = api.message.html.layout(msg, extend({ | |
29 | + showActions: true, | |
30 | + miniContent: [action, ' ', h('a', { | |
31 | + href: target | |
32 | + }, title)], | |
33 | + layout: 'mini' | |
34 | + }, opts)) | |
31 | 35 | |
32 | - return api.message.html.decorate(element, { msg }) | |
36 | + return api.message.html.decorate(element, { | |
37 | + msg | |
38 | + }) | |
39 | + } | |
33 | 40 | }) |
41 | + | |
42 | + function isRenderable(msg) { | |
43 | + if (msg.value.content.type !== 'about') return undefined | |
44 | + else if (!ref.isMsg(msg.value.content.about)) return undefined | |
45 | + else if (!msg.value.content.attendee) return undefined | |
46 | + else if (msg.value.content.attendee.link !== msg.value.author) return undefined | |
47 | + else return true | |
48 | + } | |
34 | 49 | } |
plugs/message/html/render/channel.js | ||
---|---|---|
@@ -6,30 +6,44 @@ | ||
6 | 6 | 'message.html': { |
7 | 7 | decorate: 'reduce', |
8 | 8 | layout: 'first' |
9 | 9 | }, |
10 | - 'intl.sync.i18n':'first', | |
10 | + 'intl.sync.i18n': 'first', | |
11 | 11 | }) |
12 | 12 | |
13 | -exports.gives = nest('message.html.render') | |
13 | +exports.gives = nest('message.html', { | |
14 | + canRender: true, | |
15 | + render: true | |
16 | +}) | |
14 | 17 | |
15 | -exports.create = function (api) { | |
18 | +exports.create = function(api) { | |
16 | 19 | const i18n = api.intl.sync.i18n |
17 | - return nest('message.html.render', function renderMessage (msg, opts) { | |
18 | - if (msg.value.content.type !== 'channel') return | |
19 | - var element = api.message.html.layout(msg, extend({ | |
20 | - miniContent: messageContent(msg), | |
21 | - layout: 'mini' | |
22 | - }, opts)) | |
20 | + return nest('message.html', { | |
21 | + canRender: isRenderable, | |
22 | + render: function (msg, opts) { | |
23 | + if (!isRenderable(msg)) return | |
24 | + var element = api.message.html.layout(msg, extend({ | |
25 | + miniContent: messageContent(msg), | |
26 | + layout: 'mini' | |
27 | + }, opts)) | |
23 | 28 | |
24 | - return api.message.html.decorate(element, { msg }) | |
29 | + return api.message.html.decorate(element, { | |
30 | + msg | |
31 | + }) | |
32 | + } | |
25 | 33 | }) |
26 | 34 | |
27 | - function messageContent (msg) { | |
35 | + function messageContent(msg) { | |
28 | 36 | var channel = `#${msg.value.content.channel}` |
29 | 37 | var subscribed = msg.value.content.subscribed |
30 | 38 | return [ |
31 | 39 | subscribed ? i18n('subscribed to ') : i18n('unsubscribed from '), |
32 | - h('a', {href: channel}, channel) | |
40 | + h('a', { | |
41 | + href: channel | |
42 | + }, channel) | |
33 | 43 | ] |
34 | 44 | } |
35 | 45 | } |
46 | + | |
47 | +function isRenderable(msg) { | |
48 | + return msg.value.content.type === 'channel' ? true : undefined | |
49 | +} |
plugs/message/html/render/following.js | ||
---|---|---|
@@ -11,26 +11,32 @@ | ||
11 | 11 | 'profile.html.person': 'first', |
12 | 12 | 'intl.sync.i18n': 'first', |
13 | 13 | }) |
14 | 14 | |
15 | -exports.gives = nest('message.html.render') | |
15 | +exports.gives = nest('message.html', { | |
16 | + canRender: true, | |
17 | + render: true | |
18 | +}) | |
16 | 19 | |
17 | -exports.create = function (api) { | |
20 | +exports.create = function(api) { | |
18 | 21 | const i18n = api.intl.sync.i18n |
19 | - return nest('message.html.render', function renderMessage (msg, opts) { | |
20 | - if (msg.value.content.type !== 'contact') return | |
21 | - if (!ref.isFeed(msg.value.content.contact)) return | |
22 | - if (typeof msg.value.content.following !== 'boolean' && typeof msg.value.content.blocking !== 'boolean') return | |
22 | + return nest('message.html', { | |
23 | + canRender: isRenderable, | |
24 | + render: function(msg, opts) { | |
25 | + if (!isRenderable(msg)) return | |
23 | 26 | |
24 | - var element = api.message.html.layout(msg, extend({ | |
25 | - miniContent: messageContent(msg), | |
26 | - layout: 'mini' | |
27 | - }, opts)) | |
27 | + var element = api.message.html.layout(msg, extend({ | |
28 | + miniContent: messageContent(msg), | |
29 | + layout: 'mini' | |
30 | + }, opts)) | |
28 | 31 | |
29 | - return api.message.html.decorate(element, { msg }) | |
32 | + return api.message.html.decorate(element, { | |
33 | + msg | |
34 | + }) | |
35 | + } | |
30 | 36 | }) |
31 | 37 | |
32 | - function messageContent (msg) { | |
38 | + function messageContent(msg) { | |
33 | 39 | var following = msg.value.content.following |
34 | 40 | var blocking = msg.value.content.blocking |
35 | 41 | |
36 | 42 | if (blocking === true) { |
@@ -47,5 +53,13 @@ | ||
47 | 53 | i18n('unblocked '), api.profile.html.person(msg.value.content.contact) |
48 | 54 | ] |
49 | 55 | } |
50 | 56 | } |
57 | + | |
58 | + function isRenderable(msg) { | |
59 | + if (msg.value.content.type !== 'contact') return undefined | |
60 | + else if (!ref.isFeed(msg.value.content.contact)) return undefined | |
61 | + else if (typeof msg.value.content.following !== 'boolean' && typeof msg.value.content.blocking !== 'boolean') return undefined | |
62 | + return true; | |
63 | + } | |
64 | + | |
51 | 65 | } |
plugs/message/html/render/gathering.js | ||
---|---|---|
@@ -1,5 +1,5 @@ | ||
1 | -var {h, computed, when, map, send} = require('mutant') | |
1 | +var { h, computed, when, map, send } = require('mutant') | |
2 | 2 | var nest = require('depnest') |
3 | 3 | var extend = require('xtend') |
4 | 4 | var moment = require('moment') |
5 | 5 | |
@@ -18,82 +18,93 @@ | ||
18 | 18 | 'blob.sync.url': 'first', |
19 | 19 | 'gathering.sheet.edit': 'first' |
20 | 20 | }) |
21 | 21 | |
22 | -exports.gives = nest('message.html.render') | |
22 | +exports.gives = nest('message.html', { | |
23 | + canRender: true, | |
24 | + render: true | |
25 | +}) | |
23 | 26 | |
24 | -exports.create = function (api) { | |
27 | +exports.create = function(api) { | |
25 | 28 | var following = null |
26 | 29 | |
27 | - return nest('message.html.render', function renderGathering (msg, opts) { | |
28 | - if (msg.value.content.type !== 'gathering') return | |
29 | - var yourId = api.keys.sync.id() | |
30 | - var hidden = api.about.obs.valueFrom(msg.key, 'hidden', yourId) | |
31 | - var image = api.about.obs.latestValue(msg.key, 'image') | |
32 | - var title = api.about.obs.latestValue(msg.key, 'title') | |
33 | - var description = api.about.obs.latestValue(msg.key, 'description') | |
34 | - var location = api.about.obs.latestValue(msg.key, 'location') | |
35 | - var startDateTime = api.about.obs.latestValue(msg.key, 'startDateTime') | |
36 | - var endDateTime = api.about.obs.latestValue(msg.key, 'endDateTime') | |
37 | - var attendees = computed([api.about.obs.groupedValues(msg.key, 'attendee')], getAttendees) | |
38 | - if (!following) { | |
39 | - following = api.contact.obs.following(yourId) | |
40 | - } | |
30 | + return nest('message.html', { | |
31 | + canRender: isRenderable, | |
32 | + render: function(msg, opts) { | |
33 | + if (!isRenderable(msg)) return | |
41 | 34 | |
42 | - var imageUrl = computed(image, (id) => api.blob.sync.url(id)) | |
43 | - var imageId = computed(image, (link) => link && link.link || link) | |
44 | - var content = h('GatheringCard', [ | |
45 | - h('div.title', [ | |
46 | - h('a', {href: msg.key}, title), | |
47 | - h('button', { | |
48 | - 'ev-click': send(api.gathering.sheet.edit, msg.key) | |
49 | - }, 'Edit Details') | |
50 | - ]), | |
51 | - h('div.time', computed(startDateTime, formatTime)), | |
52 | - when(image, h('a.image', { | |
53 | - href: imageId, | |
54 | - style: { | |
55 | - 'background-image': computed(imageUrl, (url) => `url(${url})`) | |
56 | - } | |
57 | - })), | |
58 | - h('div.attending', [ | |
59 | - h('div.title', ['Attendees', ' (', computed(attendees, (x) => x.length), ')']), | |
60 | - h('div.attendees', [ | |
61 | - map(attendees, (attendee) => { | |
62 | - return h('a.attendee', { | |
63 | - href: attendee, | |
64 | - title: nameAndFollowWarning(attendee) | |
65 | - }, api.about.html.image(attendee)) | |
66 | - }) | |
35 | + var yourId = api.keys.sync.id() | |
36 | + var hidden = api.about.obs.valueFrom(msg.key, 'hidden', yourId) | |
37 | + var image = api.about.obs.latestValue(msg.key, 'image') | |
38 | + var title = api.about.obs.latestValue(msg.key, 'title') | |
39 | + var description = api.about.obs.latestValue(msg.key, 'description') | |
40 | + var location = api.about.obs.latestValue(msg.key, 'location') | |
41 | + var startDateTime = api.about.obs.latestValue(msg.key, 'startDateTime') | |
42 | + var endDateTime = api.about.obs.latestValue(msg.key, 'endDateTime') | |
43 | + var attendees = computed([api.about.obs.groupedValues(msg.key, 'attendee')], getAttendees) | |
44 | + if (!following) { | |
45 | + following = api.contact.obs.following(yourId) | |
46 | + } | |
47 | + | |
48 | + var imageUrl = computed(image, (id) => api.blob.sync.url(id)) | |
49 | + var imageId = computed(image, (link) => link && link.link || link) | |
50 | + var content = h('GatheringCard', [ | |
51 | + h('div.title', [ | |
52 | + h('a', { | |
53 | + href: msg.key | |
54 | + }, title), | |
55 | + h('button', { | |
56 | + 'ev-click': send(api.gathering.sheet.edit, msg.key) | |
57 | + }, 'Edit Details') | |
67 | 58 | ]), |
68 | - h('div.actions', [ | |
69 | - h('button -attend', { | |
70 | - 'ev-click': send(publishAttending, msg.key) | |
71 | - }, `Attending`), | |
72 | - h('button -attend', { | |
73 | - 'ev-click': send(publishNotAttending, msg.key) | |
74 | - }, `Can't Attend`) | |
75 | - ]) | |
76 | - ]), | |
77 | - h('div.location', markdown(location)), | |
78 | - when(description, h('div.description', markdown(description))) | |
79 | - ]) | |
59 | + h('div.time', computed(startDateTime, formatTime)), | |
60 | + when(image, h('a.image', { | |
61 | + href: imageId, | |
62 | + style: { | |
63 | + 'background-image': computed(imageUrl, (url) => `url(${url})`) | |
64 | + } | |
65 | + })), | |
66 | + h('div.attending', [ | |
67 | + h('div.title', ['Attendees', ' (', computed(attendees, (x) => x.length), ')']), | |
68 | + h('div.attendees', [ | |
69 | + map(attendees, (attendee) => { | |
70 | + return h('a.attendee', { | |
71 | + href: attendee, | |
72 | + title: nameAndFollowWarning(attendee) | |
73 | + }, api.about.html.image(attendee)) | |
74 | + }) | |
75 | + ]), | |
76 | + h('div.actions', [ | |
77 | + h('button -attend', { | |
78 | + 'ev-click': send(publishAttending, msg.key) | |
79 | + }, `Attending`), | |
80 | + h('button -attend', { | |
81 | + 'ev-click': send(publishNotAttending, msg.key) | |
82 | + }, `Can't Attend`) | |
83 | + ]) | |
84 | + ]), | |
85 | + h('div.location', markdown(location)), | |
86 | + when(description, h('div.description', markdown(description))) | |
87 | + ]) | |
80 | 88 | |
81 | - var element = api.message.html.layout(msg, extend({ | |
82 | - content, | |
83 | - miniContent: 'Added a gathering', | |
84 | - layout: 'mini' | |
85 | - }, opts)) | |
89 | + var element = api.message.html.layout(msg, extend({ | |
90 | + content, | |
91 | + miniContent: 'Added a gathering', | |
92 | + layout: 'mini' | |
93 | + }, opts)) | |
86 | 94 | |
87 | - // hide if no title set or hidden | |
88 | - var visible = computed([title, hidden], (title, hidden) => { | |
89 | - return title && !hidden | |
90 | - }) | |
95 | + // hide if no title set or hidden | |
96 | + var visible = computed([title, hidden], (title, hidden) => { | |
97 | + return title && !hidden | |
98 | + }) | |
91 | 99 | |
92 | - return when(visible, api.message.html.decorate(element, { msg })) | |
100 | + return when(visible, api.message.html.decorate(element, { | |
101 | + msg | |
102 | + })) | |
103 | + } | |
93 | 104 | }) |
94 | 105 | |
95 | - function publishAttending (id) { | |
106 | + function publishAttending(id) { | |
96 | 107 | var yourId = api.keys.sync.id() |
97 | 108 | |
98 | 109 | // publish with confirm |
99 | 110 | api.message.async.publish({ |
@@ -104,9 +115,9 @@ | ||
104 | 115 | } |
105 | 116 | }) |
106 | 117 | } |
107 | 118 | |
108 | - function publishNotAttending (id) { | |
119 | + function publishNotAttending(id) { | |
109 | 120 | var yourId = api.keys.sync.id() |
110 | 121 | |
111 | 122 | // publish with confirm |
112 | 123 | api.message.async.publish({ |
@@ -118,11 +129,11 @@ | ||
118 | 129 | } |
119 | 130 | }) |
120 | 131 | } |
121 | 132 | |
122 | - function nameAndFollowWarning (id) { | |
133 | + function nameAndFollowWarning(id) { | |
123 | 134 | var yourId = api.keys.sync.id() |
124 | - return computed([api.about.obs.name(id), id, following], function nameAndFollowWarning (name, id, following) { | |
135 | + return computed([api.about.obs.name(id), id, following], function nameAndFollowWarning(name, id, following) { | |
125 | 136 | if (id === yourId) { |
126 | 137 | return `${name} (you)` |
127 | 138 | } else if (following.includes(id)) { |
128 | 139 | return `${name}` |
@@ -131,20 +142,24 @@ | ||
131 | 142 | } |
132 | 143 | }) |
133 | 144 | } |
134 | 145 | |
135 | - function markdown (obs) { | |
146 | + function markdown(obs) { | |
136 | 147 | return computed(obs, (text) => { |
137 | 148 | if (typeof text === 'string') return api.message.html.markdown(text) |
138 | 149 | }) |
139 | 150 | } |
140 | 151 | } |
141 | 152 | |
142 | -function formatTime (time) { | |
153 | +function formatTime(time) { | |
143 | 154 | if (time && time.epoch) { |
144 | 155 | return moment(time.epoch).format('LLLL') |
145 | 156 | } |
146 | 157 | } |
147 | 158 | |
148 | -function getAttendees (lookup) { | |
159 | +function getAttendees(lookup) { | |
149 | 160 | return Object.keys(lookup) |
150 | 161 | } |
162 | + | |
163 | +function isRenderable(msg) { | |
164 | + return (msg.value.content.type === 'gathering') ? true : undefined | |
165 | +} |
Built with git-ssb-web