git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

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 AM
Parent: d03a610c77cee73a156ebe6e4fc1f7369d27fe9d
Parent: 56ec071bbd3b367a7e702487f671bc947642e52c

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
@@ -20,8 +20,9 @@
2020
2121 exports.needs = nest({
2222 'about.obs.name': 'first',
2323 'app.sync.externalHandler': 'first',
24+ 'message.html.canRender': 'first',
2425 'message.html.render': 'first',
2526 'profile.html.person': 'first',
2627 'message.html.link': 'first',
2728 'message.sync.root': 'first',
@@ -95,10 +96,14 @@
9596 }),
9697 pull.drain((msg) => {
9798 if (msg.value.content.type === 'vote') return
9899 if (api.app.sync.externalHandler(msg)) return
99- newSinceRefresh.add(msg.key)
100100
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+
101106 if (updates() === 0 && msg.value.author === yourId && container.scrollTop < 20) {
102107 refresh()
103108 } else {
104109 updates.set(newSinceRefresh.size)
@@ -116,8 +121,12 @@
116121 result.reload = refresh
117122
118123 return result
119124
125+ function canRenderMessage(msg) {
126+ return api.message.html.canRender(msg);
127+ }
128+
120129 function refresh () {
121130 onceTrue(waitFor, () => {
122131 if (abortLastFeed) abortLastFeed()
123132 updates.set(0)
plugs/message/html/render/about.jsView
@@ -16,68 +16,79 @@
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: isRenderable,
29+ render: function (msg, opts) {
30+ if (!isRenderable(msg)) return;
2731
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
3034
31- var miniContent = []
32- var content = []
35+ var miniContent = []
36+ var content = []
3337
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)
4355 }
44- }))
45- }
4656
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+ ]))
5162 }
5263
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 = []
5965
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+ }
6175
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+ }
7184
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
7986 }
87+ })
8088
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+ }
8394 }
plugs/message/html/render/attending.jsView
@@ -10,25 +10,40 @@
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: isRenderable,
22+ render: function about(msg, opts) {
23+ if (!isRenderable(msg)) return
2224
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))
3135
32- return api.message.html.decorate(element, { msg })
36+ return api.message.html.decorate(element, {
37+ msg
38+ })
39+ }
3340 })
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+ }
3449 }
plugs/message/html/render/channel.jsView
@@ -6,30 +6,44 @@
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: 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))
2328
24- return api.message.html.decorate(element, { msg })
29+ return api.message.html.decorate(element, {
30+ msg
31+ })
32+ }
2533 })
2634
27- function messageContent (msg) {
35+ function messageContent(msg) {
2836 var channel = `#${msg.value.content.channel}`
2937 var subscribed = msg.value.content.subscribed
3038 return [
3139 subscribed ? i18n('subscribed to ') : i18n('unsubscribed from '),
32- h('a', {href: channel}, channel)
40+ h('a', {
41+ href: channel
42+ }, channel)
3343 ]
3444 }
3545 }
46+
47+function isRenderable(msg) {
48+ return msg.value.content.type === 'channel' ? true : undefined
49+}
plugs/message/html/render/following.jsView
@@ -11,26 +11,32 @@
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: isRenderable,
24+ render: function(msg, opts) {
25+ if (!isRenderable(msg)) return
2326
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))
2831
29- return api.message.html.decorate(element, { msg })
32+ return api.message.html.decorate(element, {
33+ msg
34+ })
35+ }
3036 })
3137
32- function messageContent (msg) {
38+ function messageContent(msg) {
3339 var following = msg.value.content.following
3440 var blocking = msg.value.content.blocking
3541
3642 if (blocking === true) {
@@ -47,5 +53,13 @@
4753 i18n('unblocked '), api.profile.html.person(msg.value.content.contact)
4854 ]
4955 }
5056 }
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+
5165 }
plugs/message/html/render/gathering.jsView
@@ -1,5 +1,5 @@
1-var {h, computed, when, map, send} = require('mutant')
1+var { h, computed, when, map, send } = require('mutant')
22 var nest = require('depnest')
33 var extend = require('xtend')
44 var moment = require('moment')
55
@@ -18,82 +18,93 @@
1818 'blob.sync.url': 'first',
1919 'gathering.sheet.edit': 'first'
2020 })
2121
22-exports.gives = nest('message.html.render')
22+exports.gives = nest('message.html', {
23+ canRender: true,
24+ render: true
25+})
2326
24-exports.create = function (api) {
27+exports.create = function(api) {
2528 var following = null
2629
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
4134
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')
6758 ]),
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+ ])
8088
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))
8694
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+ })
9199
92- return when(visible, api.message.html.decorate(element, { msg }))
100+ return when(visible, api.message.html.decorate(element, {
101+ msg
102+ }))
103+ }
93104 })
94105
95- function publishAttending (id) {
106+ function publishAttending(id) {
96107 var yourId = api.keys.sync.id()
97108
98109 // publish with confirm
99110 api.message.async.publish({
@@ -104,9 +115,9 @@
104115 }
105116 })
106117 }
107118
108- function publishNotAttending (id) {
119+ function publishNotAttending(id) {
109120 var yourId = api.keys.sync.id()
110121
111122 // publish with confirm
112123 api.message.async.publish({
@@ -118,11 +129,11 @@
118129 }
119130 })
120131 }
121132
122- function nameAndFollowWarning (id) {
133+ function nameAndFollowWarning(id) {
123134 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) {
125136 if (id === yourId) {
126137 return `${name} (you)`
127138 } else if (following.includes(id)) {
128139 return `${name}`
@@ -131,20 +142,24 @@
131142 }
132143 })
133144 }
134145
135- function markdown (obs) {
146+ function markdown(obs) {
136147 return computed(obs, (text) => {
137148 if (typeof text === 'string') return api.message.html.markdown(text)
138149 })
139150 }
140151 }
141152
142-function formatTime (time) {
153+function formatTime(time) {
143154 if (time && time.epoch) {
144155 return moment(time.epoch).format('LLLL')
145156 }
146157 }
147158
148-function getAttendees (lookup) {
159+function getAttendees(lookup) {
149160 return Object.keys(lookup)
150161 }
162+
163+function isRenderable(msg) {
164+ return (msg.value.content.type === 'gathering') ? true : undefined
165+}

Built with git-ssb-web