Files: f673ec400fd6aac5f54664a90b9d9fc631bab957 / plugs / message / html / render / gathering.js
4462 bytesRaw
1 | var {h, computed, when, map, send} = require('mutant') |
2 | var nest = require('depnest') |
3 | var extend = require('xtend') |
4 | var moment = require('moment') |
5 | |
6 | exports.needs = nest({ |
7 | 'message.html.markdown': 'first', |
8 | 'message.html.layout': 'first', |
9 | 'message.html.decorate': 'reduce', |
10 | 'message.async.publish': 'first', |
11 | 'keys.sync.id': 'first', |
12 | 'about.html.image': 'first', |
13 | 'about.obs.latestValue': 'first', |
14 | 'about.obs.groupedValues': 'first', |
15 | 'about.obs.valueFrom': 'first', |
16 | 'about.obs.name': 'first', |
17 | 'contact.obs.following': 'first', |
18 | 'blob.sync.url': 'first', |
19 | 'gathering.sheet.edit': 'first' |
20 | }) |
21 | |
22 | exports.gives = nest('message.html.render') |
23 | |
24 | exports.create = function (api) { |
25 | var following = null |
26 | |
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 | } |
41 | |
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 | }) |
67 | ]), |
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 | ]) |
80 | |
81 | var element = api.message.html.layout(msg, extend({ |
82 | content, |
83 | miniContent: 'Added a gathering', |
84 | layout: 'mini' |
85 | }, opts)) |
86 | |
87 | // hide if no title set or hidden |
88 | var visible = computed([title, hidden], (title, hidden) => { |
89 | return title && !hidden |
90 | }) |
91 | |
92 | return when(visible, api.message.html.decorate(element, { msg })) |
93 | }) |
94 | |
95 | function publishAttending (id) { |
96 | var yourId = api.keys.sync.id() |
97 | |
98 | // publish with confirm |
99 | api.message.async.publish({ |
100 | type: 'about', |
101 | about: id, |
102 | attendee: { |
103 | link: yourId |
104 | } |
105 | }) |
106 | } |
107 | |
108 | function publishNotAttending (id) { |
109 | var yourId = api.keys.sync.id() |
110 | |
111 | // publish with confirm |
112 | api.message.async.publish({ |
113 | type: 'about', |
114 | about: id, |
115 | attendee: { |
116 | link: yourId, |
117 | remove: true |
118 | } |
119 | }) |
120 | } |
121 | |
122 | function nameAndFollowWarning (id) { |
123 | var yourId = api.keys.sync.id() |
124 | return computed([api.about.obs.name(id), id, following], function nameAndFollowWarning (name, id, following) { |
125 | if (id === yourId) { |
126 | return `${name} (you)` |
127 | } else if (following.includes(id)) { |
128 | return `${name}` |
129 | } else { |
130 | return `${name} (not following)` |
131 | } |
132 | }) |
133 | } |
134 | |
135 | function markdown (obs) { |
136 | return computed(obs, (text) => { |
137 | if (typeof text === 'string') return api.message.html.markdown(text) |
138 | }) |
139 | } |
140 | } |
141 | |
142 | function formatTime (time) { |
143 | if (time && time.epoch) { |
144 | return moment(time.epoch).format('LLLL') |
145 | } |
146 | } |
147 | |
148 | function getAttendees (lookup) { |
149 | return Object.keys(lookup) |
150 | } |
151 |
Built with git-ssb-web