UNPKG

patchbay-gatherings

Version:
131 lines (114 loc) 4.05 kB
const { h, Value, computed } = require('mutant') const spacetime = require('spacetime') const pull = require('pull-stream') const getTimezone = require('../lib/get-timezone') const getTimezoneOffset = require('../lib/get-timezone-offset') const imageString = require('../lib/image-string') module.exports = function GatheringShow (opts) { const { gathering, // String: Message of form { key, value } scuttle, // Object: instantiated scuttle-gathering helper avatar = i => h('div', i), // Function: takes FeedId, returns observerable DOM element blobUrl = i => i, // Function: takes BlodId, returns url location for blob markdown = i => i, // Function: takes text, returns rendered markdown editBtn, // DOM element: a button which can be inserted to trigger some edit action updateStream, // Source: an optional stream which triggers refresh of view myKey // FeedId } = opts const state = Value() const isPublishing = Value(false) refreshState() if (updateStream) pull(updateStream, pull.drain(refreshState)) return h('GatheringShow', computed(state, state => { if (!state) return h('div.loading', 'Loading...') const { title, description, location, startDateTime, image, isAttendee, attendees, notAttendees } = state return [ Banner(image), h('section.about', [ h('h1', title), h('div.description', markdown(description)), editBtn ? h('div.edit', editBtn) : null ]), h('section.spacetime', [ startDateTime && startDateTime.epoch ? [ h('label', 'time'), Time(new Date(startDateTime.epoch)) ] : null, location ? [ h('label', 'location'), h('div.location', markdown(location)) ] : null ]), h('section.attendance', [ h('div.attendanceButtons', [ AttendBtn(isAttendee, attendees), CantAttendBtn(myKey, notAttendees) ]), h('label', `Attending (${attendees.length})`), h('div.attendees', attendees.map(avatar)), h('label', `Not Attending (${notAttendees.length})`), h('div.notAttendees', notAttendees.map(avatar)) ]) ] })) function Banner (image) { if (!(image && image.link)) return const url = blobUrl(imageString(image)) return h('section.image', { style: { 'background-image': `url('${url}')` } }, [ h('img', { src: url, style: { visibility: 'hidden' } }) ]) } function AttendBtn (isAttendee, attendees) { return h('button', { 'disabled': computed([isPublishing], isPublishing => isPublishing || isAttendee), 'className': isAttendee ? '' : '-primary', 'ev-click': () => { isPublishing.set(true) scuttle.attending(gathering.key, true, (err, data) => { if (err) return console.error(err) // TODO display error refreshState() }) } }, 'Attend' ) } function CantAttendBtn (myKey, notAttendees) { const isNotAttendee = notAttendees.includes(myKey) return h('button', { 'disabled': computed([isPublishing], isPublishing => isPublishing || isNotAttendee), 'ev-click': () => { isPublishing.set(true) scuttle.attending(gathering.key, false, (err, data) => { if (err) return console.error(err) // TODO display error refreshState() }) } }, 'Can\'t Attend' ) } // helpers function refreshState () { scuttle.get(gathering.key, (err, data) => { if (err) return console.error(err) // TODO display something to user state.set(data) isPublishing.set(false) }) } } function Time (date) { const t = spacetime(date) return h('div.time', [ t.format('nice'), h('div.zone', { title: 'timezone' }, [ getTimezone() || '??', h('span', ['(UTC ', getTimezoneOffset(), ')']) ]) ]) }