git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

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 PM
Parent: c0e5334e0811d15dbcbc0b86a35ba498c3e9640d

Files changed

modules/feed/html/rollup.jschanged
plugs/message/html/render/about.jschanged
plugs/message/html/render/attending.jschanged
plugs/message/html/render/channel.jschanged
plugs/message/html/render/following.jschanged
plugs/message/html/render/gathering.jschanged
modules/feed/html/rollup.jsView
@@ -21,8 +21,9 @@
2121
2222 exports.needs = nest({
2323 'about.obs.name': 'first',
2424 'app.sync.externalHandler': 'first',
25+ 'message.html.canRender': 'first',
2526 'message.html.render': 'first',
2627 'profile.html.person': 'first',
2728 'message.html.link': 'first',
2829 'message.sync.root': 'first',
@@ -121,19 +122,9 @@
121122
122123 return result
123124
124125 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);
136127 }
137128
138129 function refresh () {
139130 onceTrue(waitFor, () => {
plugs/message/html/render/about.jsView
@@ -16,68 +16,81 @@
1616 'blob.sync.url': 'first',
1717 'intl.sync.i18n': 'first',
1818 })
1919
20-exports.gives = nest('message.html.render')
20+exports.gives = nest('message.html', {
21+ canRender: true,
22+ render: true
23+})
2124
2225 exports.create = function (api) {
2326 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;
2733
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
3036
31- var miniContent = []
32- var content = []
37+ var miniContent = []
38+ var content = []
3339
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)
4357 }
44- }))
45- }
4658
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+ ]))
5164 }
5265
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 = []
5967
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+ }
6177
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+ }
7186
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
7988 }
89+ })
8090
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+ }
8396 }
plugs/message/html/render/attending.jsView
@@ -10,25 +10,42 @@
1010 },
1111 'about.obs.latestValue': 'first'
1212 })
1313
14-exports.gives = nest('message.html.render')
14+exports.gives = nest('message.html', {
15+ canRender: true,
16+ render: true
17+})
1518
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
2226
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))
3137
32- return api.message.html.decorate(element, { msg })
38+ return api.message.html.decorate(element, {
39+ msg
40+ })
41+ }
3342 })
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+ }
3451 }
plugs/message/html/render/channel.jsView
@@ -6,30 +6,46 @@
66 'message.html': {
77 decorate: 'reduce',
88 layout: 'first'
99 },
10- 'intl.sync.i18n':'first',
10+ 'intl.sync.i18n': 'first',
1111 })
1212
13-exports.gives = nest('message.html.render')
13+exports.gives = nest('message.html', {
14+ canRender: true,
15+ render: true
16+})
1417
15-exports.create = function (api) {
18+exports.create = function(api) {
1619 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))
2330
24- return api.message.html.decorate(element, { msg })
31+ return api.message.html.decorate(element, {
32+ msg
33+ })
34+ }
2535 })
2636
27- function messageContent (msg) {
37+ function messageContent(msg) {
2838 var channel = `#${msg.value.content.channel}`
2939 var subscribed = msg.value.content.subscribed
3040 return [
3141 subscribed ? i18n('subscribed to ') : i18n('unsubscribed from '),
32- h('a', {href: channel}, channel)
42+ h('a', {
43+ href: channel
44+ }, channel)
3345 ]
3446 }
3547 }
48+
49+function isRenderable(msg) {
50+ return msg.value.content.type === 'channel'
51+}
plugs/message/html/render/following.jsView
@@ -11,23 +11,31 @@
1111 'profile.html.person': 'first',
1212 'intl.sync.i18n': 'first',
1313 })
1414
15-exports.gives = nest('message.html.render')
15+exports.gives = nest('message.html', {
16+ canRender: true,
17+ render: true
18+})
1619
17-exports.create = function (api) {
20+exports.create = function(api) {
1821 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
2328
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))
2833
29- return api.message.html.decorate(element, { msg })
34+ return api.message.html.decorate(element, {
35+ msg
36+ })
37+ }
3038 })
3139
3240 function messageContent (msg) {
3341 var following = msg.value.content.following
@@ -44,5 +52,13 @@
4452 api.profile.html.person(msg.value.content.contact)
4553 ]
4654 }
4755 }
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;
4862 }
63+
64+}
plugs/message/html/render/gathering.jsView
@@ -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')
28 var nest = require('depnest')
39 var extend = require('xtend')
410 var moment = require('moment')
511
@@ -18,81 +24,94 @@
1824 'blob.sync.url': 'first',
1925 'gathering.sheet.edit': 'first'
2026 })
2127
22-exports.gives = nest('message.html.render')
28+exports.gives = nest('message.html', {
29+ canRender: true,
30+ render: true
31+})
2332
24-exports.create = function (api) {
33+exports.create = function(api) {
2534 var following = null
2635
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
4142
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')
6665 ]),
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+ ])
7995
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))
85101
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+ })
90106
91- return when(visible, api.message.html.decorate(element, { msg }))
107+ return when(visible, api.message.html.decorate(element, {
108+ msg
109+ }))
110+ }
92111 })
93112
94- function publishAttending (id) {
113+ function publishAttending(id) {
95114 var yourId = api.keys.sync.id()
96115
97116 // publish with confirm
98117 api.message.async.publish({
@@ -103,9 +122,9 @@
103122 }
104123 })
105124 }
106125
107- function publishNotAttending (id) {
126+ function publishNotAttending(id) {
108127 var yourId = api.keys.sync.id()
109128
110129 // publish with confirm
111130 api.message.async.publish({
@@ -117,11 +136,11 @@
117136 }
118137 })
119138 }
120139
121- function nameAndFollowWarning (id) {
140+ function nameAndFollowWarning(id) {
122141 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) {
124143 if (id === yourId) {
125144 return `${name} (you)`
126145 } else if (following.includes(id)) {
127146 return `${name}`
@@ -130,20 +149,24 @@
130149 }
131150 })
132151 }
133152
134- function markdown (obs) {
153+ function markdown(obs) {
135154 return computed(obs, (text) => {
136155 if (typeof text === 'string') return api.message.html.markdown(text)
137156 })
138157 }
139158 }
140159
141-function formatTime (time) {
160+function isRenderable(msg) {
161+ return (msg.value.content.type === 'gathering')
162+}
163+
164+function formatTime(time) {
142165 if (time && time.epoch) {
143166 return moment(time.epoch).format('LLLL')
144167 }
145168 }
146169
147-function getAttendees (lookup) {
170+function getAttendees(lookup) {
148171 return Object.keys(lookup)
149172 }

Built with git-ssb-web