Commit ed9add9c301f7f06b62492824e07772071cc5719
Discover via depject if patchwork knows how to render a given message. We use this to determine whether to count a message in the 'uneen messages'
Gordon Martin committed on 10/14/2017, 11:21:49 PMParent: c0e5334e0811d15dbcbc0b86a35ba498c3e9640d
Files changed
modules/feed/html/rollup.js | ||
---|---|---|
@@ -21,8 +21,9 @@ | ||
21 | 21 | |
22 | 22 | exports.needs = nest({ |
23 | 23 | 'about.obs.name': 'first', |
24 | 24 | 'app.sync.externalHandler': 'first', |
25 | + 'message.html.canRender': 'first', | |
25 | 26 | 'message.html.render': 'first', |
26 | 27 | 'profile.html.person': 'first', |
27 | 28 | 'message.html.link': 'first', |
28 | 29 | 'message.sync.root': 'first', |
@@ -121,19 +122,9 @@ | ||
121 | 122 | |
122 | 123 | return result |
123 | 124 | |
124 | 125 | function canRenderMessage(msg) { |
125 | - | |
126 | - // TODO: This implementation of 'canRenderMessage' is just for a proof of | |
127 | - // concept. I will add an alternative that just returns 'true' rather | |
128 | - // than rendering if the provider handles the message type | |
129 | - | |
130 | - var isRenderableByPatchbay = api.message.html.render(msg, { | |
131 | - inContext: true, | |
132 | - priority: highlightItems.has(msg.key) ? 2 : 0 | |
133 | - }); | |
134 | - | |
135 | - return isRenderableByPatchbay; | |
126 | + return api.message.html.canRender(msg); | |
136 | 127 | } |
137 | 128 | |
138 | 129 | function refresh () { |
139 | 130 | onceTrue(waitFor, () => { |
plugs/message/html/render/about.js | ||
---|---|---|
@@ -16,68 +16,81 @@ | ||
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: function (msg) { | |
29 | + return isRenderable(msg); | |
30 | + }, | |
31 | + render: function (msg, opts) { | |
32 | + if (!isRenderable(msg)) return; | |
27 | 33 | |
28 | - var c = msg.value.content | |
29 | - var self = msg.value.author === c.about | |
34 | + var c = msg.value.content | |
35 | + var self = msg.value.author === c.about | |
30 | 36 | |
31 | - var miniContent = [] | |
32 | - var content = [] | |
37 | + var miniContent = [] | |
38 | + var content = [] | |
33 | 39 | |
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, '"'] | |
40 | + if (c.name) { | |
41 | + var target = api.profile.html.person(c.about, c.name) | |
42 | + miniContent.push(computed([self, api.about.obs.name(c.about), c.name], (self, a, b) => { | |
43 | + if (self) { | |
44 | + return [i18n('self identifies as "'), target, '"'] | |
45 | + } else if (a === b) { | |
46 | + return [i18n('identified '), api.profile.html.person(c.about)] | |
47 | + } else { | |
48 | + return [i18n('identifies '), api.profile.html.person(c.about), i18n(' as "'), target, '"'] | |
49 | + } | |
50 | + })) | |
51 | + } | |
52 | + | |
53 | + if (c.image) { | |
54 | + if (!miniContent.length) { | |
55 | + var imageAction = self ? i18n('self assigned a display image') : [i18n('assigned a display image to '), api.profile.html.person(c.about)] | |
56 | + miniContent.push(imageAction) | |
43 | 57 | } |
44 | - })) | |
45 | - } | |
46 | 58 | |
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) | |
59 | + content.push(h('a AboutImage', { | |
60 | + href: c.about | |
61 | + }, [ | |
62 | + h('img', {src: api.blob.sync.url(c.image)}) | |
63 | + ])) | |
51 | 64 | } |
52 | 65 | |
53 | - content.push(h('a AboutImage', { | |
54 | - href: c.about | |
55 | - }, [ | |
56 | - h('img', {src: api.blob.sync.url(c.image)}) | |
57 | - ])) | |
58 | - } | |
66 | + var elements = [] | |
59 | 67 | |
60 | - var elements = [] | |
68 | + if (miniContent.length) { | |
69 | + var element = api.message.html.layout(msg, extend({ | |
70 | + showActions: true, | |
71 | + miniContent, | |
72 | + content, | |
73 | + layout: 'mini' | |
74 | + }, opts)) | |
75 | + elements.push(api.message.html.decorate(element, { msg })) | |
76 | + } | |
61 | 77 | |
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 | - } | |
78 | + if (c.description) { | |
79 | + elements.push(api.message.html.decorate(api.message.html.layout(msg, extend({ | |
80 | + showActions: true, | |
81 | + miniContent: self ? i18n('self assigned a description') : [i18n('assigned a description to '), api.profile.html.person(c.about)], | |
82 | + content: api.message.html.markdown(c.description), | |
83 | + layout: 'mini' | |
84 | + }, opts)), { msg })) | |
85 | + } | |
71 | 86 | |
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 })) | |
87 | + return elements | |
79 | 88 | } |
89 | + }) | |
80 | 90 | |
81 | - return elements | |
82 | - }) | |
91 | + function isRenderable(msg) { | |
92 | + if (msg.value.content.type !== 'about') return false | |
93 | + else if (!ref.isFeed(msg.value.content.about)) return false | |
94 | + return true | |
95 | + } | |
83 | 96 | } |
plugs/message/html/render/attending.js | ||
---|---|---|
@@ -10,25 +10,42 @@ | ||
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: function(msg) { | |
22 | + return isRenderable(msg) | |
23 | + }, | |
24 | + render: function about(msg, opts) { | |
25 | + if (!isRenderable(msg)) return | |
22 | 26 | |
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)) | |
27 | + var action = msg.value.content.attendee.remove ? `can't attend` : 'is attending' | |
28 | + var target = msg.value.content.about | |
29 | + var title = api.about.obs.latestValue(target, 'title') | |
30 | + var element = api.message.html.layout(msg, extend({ | |
31 | + showActions: true, | |
32 | + miniContent: [action, ' ', h('a', { | |
33 | + href: target | |
34 | + }, title)], | |
35 | + layout: 'mini' | |
36 | + }, opts)) | |
31 | 37 | |
32 | - return api.message.html.decorate(element, { msg }) | |
38 | + return api.message.html.decorate(element, { | |
39 | + msg | |
40 | + }) | |
41 | + } | |
33 | 42 | }) |
43 | + | |
44 | + function isRenderable(msg) { | |
45 | + if (msg.value.content.type !== 'about') return false | |
46 | + else if (!ref.isMsg(msg.value.content.about)) return false | |
47 | + else if (!msg.value.content.attendee) return false | |
48 | + else if (msg.value.content.attendee.link !== msg.value.author) return false | |
49 | + else return true | |
50 | + } | |
34 | 51 | } |
plugs/message/html/render/channel.js | ||
---|---|---|
@@ -6,30 +6,46 @@ | ||
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: function (msg) { | |
22 | + return isRenderable(msg); | |
23 | + }, | |
24 | + render: function (msg, opts) { | |
25 | + if (!isRenderable(msg)) return | |
26 | + var element = api.message.html.layout(msg, extend({ | |
27 | + miniContent: messageContent(msg), | |
28 | + layout: 'mini' | |
29 | + }, opts)) | |
23 | 30 | |
24 | - return api.message.html.decorate(element, { msg }) | |
31 | + return api.message.html.decorate(element, { | |
32 | + msg | |
33 | + }) | |
34 | + } | |
25 | 35 | }) |
26 | 36 | |
27 | - function messageContent (msg) { | |
37 | + function messageContent(msg) { | |
28 | 38 | var channel = `#${msg.value.content.channel}` |
29 | 39 | var subscribed = msg.value.content.subscribed |
30 | 40 | return [ |
31 | 41 | subscribed ? i18n('subscribed to ') : i18n('unsubscribed from '), |
32 | - h('a', {href: channel}, channel) | |
42 | + h('a', { | |
43 | + href: channel | |
44 | + }, channel) | |
33 | 45 | ] |
34 | 46 | } |
35 | 47 | } |
48 | + | |
49 | +function isRenderable(msg) { | |
50 | + return msg.value.content.type === 'channel' | |
51 | +} |
plugs/message/html/render/following.js | ||
---|---|---|
@@ -11,23 +11,31 @@ | ||
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: function(msg) { | |
24 | + return isRenderable(msg); | |
25 | + }, | |
26 | + render: function (msg, opts) { | |
27 | + if (!isRenderable(msg)) return | |
23 | 28 | |
24 | - var element = api.message.html.layout(msg, extend({ | |
25 | - miniContent: messageContent(msg), | |
26 | - layout: 'mini' | |
27 | - }, opts)) | |
29 | + var element = api.message.html.layout(msg, extend({ | |
30 | + miniContent: messageContent(msg), | |
31 | + layout: 'mini' | |
32 | + }, opts)) | |
28 | 33 | |
29 | - return api.message.html.decorate(element, { msg }) | |
34 | + return api.message.html.decorate(element, { | |
35 | + msg | |
36 | + }) | |
37 | + } | |
30 | 38 | }) |
31 | 39 | |
32 | 40 | function messageContent (msg) { |
33 | 41 | var following = msg.value.content.following |
@@ -44,5 +52,13 @@ | ||
44 | 52 | api.profile.html.person(msg.value.content.contact) |
45 | 53 | ] |
46 | 54 | } |
47 | 55 | } |
56 | + | |
57 | +function isRenderable(msg) { | |
58 | + if (msg.value.content.type !== 'contact') return | |
59 | + else if (!ref.isFeed(msg.value.content.contact)) return | |
60 | + else if (typeof msg.value.content.following !== 'boolean' && typeof msg.value.content.blocking !== 'boolean') return | |
61 | + return true; | |
48 | 62 | } |
63 | + | |
64 | +} |
plugs/message/html/render/gathering.js | ||
---|---|---|
@@ -1,5 +1,11 @@ | ||
1 | -var {h, computed, when, map, send} = require('mutant') | |
1 | +var { | |
2 | + h, | |
3 | + computed, | |
4 | + when, | |
5 | + map, | |
6 | + send | |
7 | +} = require('mutant') | |
2 | 8 | var nest = require('depnest') |
3 | 9 | var extend = require('xtend') |
4 | 10 | var moment = require('moment') |
5 | 11 | |
@@ -18,81 +24,94 @@ | ||
18 | 24 | 'blob.sync.url': 'first', |
19 | 25 | 'gathering.sheet.edit': 'first' |
20 | 26 | }) |
21 | 27 | |
22 | -exports.gives = nest('message.html.render') | |
28 | +exports.gives = nest('message.html', { | |
29 | + canRender: true, | |
30 | + render: true | |
31 | +}) | |
23 | 32 | |
24 | -exports.create = function (api) { | |
33 | +exports.create = function(api) { | |
25 | 34 | var following = null |
26 | 35 | |
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 | - } | |
36 | + return nest('message.html', { | |
37 | + canRender: function(msg) { | |
38 | + return isRenderable(msg) | |
39 | + }, | |
40 | + render: function (msg, opts) { | |
41 | + if (!isRenderable(msg)) return | |
41 | 42 | |
42 | - var imageUrl = computed(image, (id) => api.blob.sync.url(id)) | |
43 | - var content = h('GatheringCard', [ | |
44 | - h('div.title', [ | |
45 | - h('a', {href: msg.key}, title), | |
46 | - h('button', { | |
47 | - 'ev-click': send(api.gathering.sheet.edit, msg.key) | |
48 | - }, 'Edit Details') | |
49 | - ]), | |
50 | - h('div.time', computed(startDateTime, formatTime)), | |
51 | - when(image, h('a.image', { | |
52 | - href: imageUrl, | |
53 | - style: { | |
54 | - 'background-image': computed(imageUrl, (url) => `url(${url})`) | |
55 | - } | |
56 | - })), | |
57 | - h('div.attending', [ | |
58 | - h('div.title', ['Attendees', ' (', computed(attendees, (x) => x.length), ')']), | |
59 | - h('div.attendees', [ | |
60 | - map(attendees, (attendee) => { | |
61 | - return h('a.attendee', { | |
62 | - href: attendee, | |
63 | - title: nameAndFollowWarning(attendee) | |
64 | - }, api.about.html.image(attendee)) | |
65 | - }) | |
43 | + var yourId = api.keys.sync.id() | |
44 | + var hidden = api.about.obs.valueFrom(msg.key, 'hidden', yourId) | |
45 | + var image = api.about.obs.latestValue(msg.key, 'image') | |
46 | + var title = api.about.obs.latestValue(msg.key, 'title') | |
47 | + var description = api.about.obs.latestValue(msg.key, 'description') | |
48 | + var location = api.about.obs.latestValue(msg.key, 'location') | |
49 | + var startDateTime = api.about.obs.latestValue(msg.key, 'startDateTime') | |
50 | + var endDateTime = api.about.obs.latestValue(msg.key, 'endDateTime') | |
51 | + var attendees = computed([api.about.obs.groupedValues(msg.key, 'attendee')], getAttendees) | |
52 | + if (!following) { | |
53 | + following = api.contact.obs.following(yourId) | |
54 | + } | |
55 | + | |
56 | + var imageUrl = computed(image, (id) => api.blob.sync.url(id)) | |
57 | + var content = h('GatheringCard', [ | |
58 | + h('div.title', [ | |
59 | + h('a', { | |
60 | + href: msg.key | |
61 | + }, title), | |
62 | + h('button', { | |
63 | + 'ev-click': send(api.gathering.sheet.edit, msg.key) | |
64 | + }, 'Edit Details') | |
66 | 65 | ]), |
67 | - h('div.actions', [ | |
68 | - h('button -attend', { | |
69 | - 'ev-click': send(publishAttending, msg.key) | |
70 | - }, `Attending`), | |
71 | - h('button -attend', { | |
72 | - 'ev-click': send(publishNotAttending, msg.key) | |
73 | - }, `Can't Attend`) | |
74 | - ]) | |
75 | - ]), | |
76 | - h('div.location', markdown(location)), | |
77 | - when(description, h('div.description', markdown(description))) | |
78 | - ]) | |
66 | + h('div.time', computed(startDateTime, formatTime)), | |
67 | + when(image, h('a.image', { | |
68 | + href: imageUrl, | |
69 | + style: { | |
70 | + 'background-image': computed(imageUrl, (url) => `url(${url})`) | |
71 | + } | |
72 | + })), | |
73 | + h('div.attending', [ | |
74 | + h('div.title', ['Attendees', ' (', computed(attendees, (x) => x.length), ')']), | |
75 | + h('div.attendees', [ | |
76 | + map(attendees, (attendee) => { | |
77 | + return h('a.attendee', { | |
78 | + href: attendee, | |
79 | + title: nameAndFollowWarning(attendee) | |
80 | + }, api.about.html.image(attendee)) | |
81 | + }) | |
82 | + ]), | |
83 | + h('div.actions', [ | |
84 | + h('button -attend', { | |
85 | + 'ev-click': send(publishAttending, msg.key) | |
86 | + }, `Attending`), | |
87 | + h('button -attend', { | |
88 | + 'ev-click': send(publishNotAttending, msg.key) | |
89 | + }, `Can't Attend`) | |
90 | + ]) | |
91 | + ]), | |
92 | + h('div.location', markdown(location)), | |
93 | + when(description, h('div.description', markdown(description))) | |
94 | + ]) | |
79 | 95 | |
80 | - var element = api.message.html.layout(msg, extend({ | |
81 | - content, | |
82 | - miniContent: 'Added a gathering', | |
83 | - layout: 'mini' | |
84 | - }, opts)) | |
96 | + var element = api.message.html.layout(msg, extend({ | |
97 | + content, | |
98 | + miniContent: 'Added a gathering', | |
99 | + layout: 'mini' | |
100 | + }, opts)) | |
85 | 101 | |
86 | - // hide if no title set or hidden | |
87 | - var visible = computed([title, hidden], (title, hidden) => { | |
88 | - return title && !hidden | |
89 | - }) | |
102 | + // hide if no title set or hidden | |
103 | + var visible = computed([title, hidden], (title, hidden) => { | |
104 | + return title && !hidden | |
105 | + }) | |
90 | 106 | |
91 | - return when(visible, api.message.html.decorate(element, { msg })) | |
107 | + return when(visible, api.message.html.decorate(element, { | |
108 | + msg | |
109 | + })) | |
110 | + } | |
92 | 111 | }) |
93 | 112 | |
94 | - function publishAttending (id) { | |
113 | + function publishAttending(id) { | |
95 | 114 | var yourId = api.keys.sync.id() |
96 | 115 | |
97 | 116 | // publish with confirm |
98 | 117 | api.message.async.publish({ |
@@ -103,9 +122,9 @@ | ||
103 | 122 | } |
104 | 123 | }) |
105 | 124 | } |
106 | 125 | |
107 | - function publishNotAttending (id) { | |
126 | + function publishNotAttending(id) { | |
108 | 127 | var yourId = api.keys.sync.id() |
109 | 128 | |
110 | 129 | // publish with confirm |
111 | 130 | api.message.async.publish({ |
@@ -117,11 +136,11 @@ | ||
117 | 136 | } |
118 | 137 | }) |
119 | 138 | } |
120 | 139 | |
121 | - function nameAndFollowWarning (id) { | |
140 | + function nameAndFollowWarning(id) { | |
122 | 141 | var yourId = api.keys.sync.id() |
123 | - return computed([api.about.obs.name(id), id, following], function nameAndFollowWarning (name, id, following) { | |
142 | + return computed([api.about.obs.name(id), id, following], function nameAndFollowWarning(name, id, following) { | |
124 | 143 | if (id === yourId) { |
125 | 144 | return `${name} (you)` |
126 | 145 | } else if (following.includes(id)) { |
127 | 146 | return `${name}` |
@@ -130,20 +149,24 @@ | ||
130 | 149 | } |
131 | 150 | }) |
132 | 151 | } |
133 | 152 | |
134 | - function markdown (obs) { | |
153 | + function markdown(obs) { | |
135 | 154 | return computed(obs, (text) => { |
136 | 155 | if (typeof text === 'string') return api.message.html.markdown(text) |
137 | 156 | }) |
138 | 157 | } |
139 | 158 | } |
140 | 159 | |
141 | -function formatTime (time) { | |
160 | +function isRenderable(msg) { | |
161 | + return (msg.value.content.type === 'gathering') | |
162 | +} | |
163 | + | |
164 | +function formatTime(time) { | |
142 | 165 | if (time && time.epoch) { |
143 | 166 | return moment(time.epoch).format('LLLL') |
144 | 167 | } |
145 | 168 | } |
146 | 169 | |
147 | -function getAttendees (lookup) { | |
170 | +function getAttendees(lookup) { | |
148 | 171 | return Object.keys(lookup) |
149 | 172 | } |
Built with git-ssb-web