git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Tree: 973b79e581dbc98d1e008cb5cbdf69714b168342

Files: 973b79e581dbc98d1e008cb5cbdf69714b168342 / modules / gathering / sheet / edit.js

5690 bytesRaw
1var nest = require('depnest')
2var extend = require('xtend')
3var Pickr = require('flatpickr')
4var spacetime = require('spacetime')
5
6var {Value, h, computed, when} = require('mutant')
7
8exports.gives = nest('gathering.sheet.edit')
9
10exports.needs = nest({
11 'sheet.display': 'first',
12 'keys.sync.id': 'first',
13 'sbot.async.publish': 'first',
14 'about.obs.latestValue': 'first',
15 'blob.html.input': 'first',
16 'blob.sync.url': 'first',
17 'intl.sync.i18n': 'first'
18})
19
20exports.create = function (api) {
21 const i18n = api.intl.sync.i18n
22 return nest('gathering.sheet.edit', function (id) {
23 api.sheet.display(close => {
24 var current = id ? {
25 title: api.about.obs.latestValue(id, 'title'),
26 startDateTime: api.about.obs.latestValue(id, 'startDateTime'),
27 image: api.about.obs.latestValue(id, 'image'),
28 description: api.about.obs.latestValue(id, 'description')
29 } : {
30 title: Value(),
31 startDateTime: Value(),
32 image: Value(),
33 description: Value()
34 }
35
36 var publishing = Value(false)
37
38 var chosen = {
39 title: Value(current.title()),
40 startDateTime: Value(current.startDateTime()),
41 image: Value(current.image()),
42 description: Value(current.description())
43 }
44
45 var imageUrl = computed(chosen.image, (id) => id && api.blob.sync.url(id))
46
47 return {
48 content: h('div', {
49 style: {
50 padding: '20px',
51 'text-align': 'center'
52 }
53 }, [
54 h('h2', {
55 style: {
56 'font-weight': 'normal'
57 }
58 }, [id ? i18n('Edit') : i18n('Create'), i18n(' Gathering')]),
59 h('GatheringEditor', [
60 h('input.title', {
61 placeholder: i18n('Choose a title'),
62 hooks: [ValueHook(chosen.title), FocusHook()]
63 }),
64 h('input.date', {
65 placeholder: i18n('Choose date and time'),
66 hooks: [
67 PickrHook(chosen.startDateTime)
68 ]
69 }),
70 h('ImageInput .banner', {
71 style: { 'background-image': computed(imageUrl, x => `url(${x})`) }
72 }, [
73 h('span', ['🖼 ', i18n('Choose Banner Image...')]),
74 api.blob.html.input(file => {
75 chosen.image.set(file)
76 }, {
77 accept: 'image/*'
78 })
79 ]),
80 h('textarea.description', {
81 placeholder: i18n('Describe the gathering (if you want)'),
82 hooks: [ValueHook(chosen.description)]
83 })
84 ])
85 ]),
86 footer: [
87 h('button -save', {
88 'ev-click': save,
89 'disabled': publishing
90 }, when(publishing, i18n('Publishing...'), i18n('Publish'))),
91 h('button -cancel', {
92 'ev-click': close
93 }, i18n('Cancel'))
94 ]
95 }
96
97 function ensureExists (cb) {
98 if (!id) {
99 api.sbot.async.publish({
100 type: 'gathering'
101 }, (err, msg) => {
102 if (err) return cb(err)
103 cb(null, msg.key)
104 })
105 } else {
106 cb(null, id)
107 }
108 }
109
110 function save () {
111 // no confirm
112 var update = {}
113
114 if (!compareImage(chosen.image(), current.image())) update.image = chosen.image()
115 if (!compareTime(chosen.startDateTime(), current.startDateTime())) update.startDateTime = chosen.startDateTime()
116 if (chosen.title() !== current.title()) update.title = chosen.title() || i18n('Untitled Gathering')
117 if (chosen.description() !== current.description()) update.description = chosen.description()
118
119 if (Object.keys(update).length) {
120 publishing.set(true)
121 ensureExists((err, id) => {
122 if (err) throw err
123 api.sbot.async.publish(extend({
124 type: 'about',
125 about: id
126 }, update), (err) => {
127 if (err) {
128 publishing.set(false)
129 showDialog({
130 type: 'error',
131 title: i18n('Error'),
132 buttons: ['OK'],
133 message: i18n('An error occurred while attempting to publish gathering.'),
134 detail: err.message
135 })
136 } else {
137 close()
138 }
139 })
140 })
141 } else {
142 close()
143 }
144 }
145 })
146 })
147}
148
149function compareTime (a, b) {
150 if (!a && !b) {
151 return true
152 } else if (!a || !b) {
153 return false
154 } else {
155 return a.epoch === b.epoch
156 }
157}
158
159function compareImage (a, b) {
160 a = isObject(a) ? a.link : a
161 b = isObject(b) ? b.link : b
162 return a === b
163}
164
165function isObject (value) {
166 return value && typeof value === 'object'
167}
168
169function FocusHook () {
170 return function (element) {
171 setTimeout(() => {
172 element.focus()
173 element.select()
174 }, 5)
175 }
176}
177
178function ValueHook (obs) {
179 return function (element) {
180 element.value = obs()
181 element.oninput = function () {
182 obs.set(element.value.trim())
183 }
184 }
185}
186
187function showDialog (opts) {
188 var electron = require('electron')
189 electron.remote.dialog.showMessageBox(electron.remote.getCurrentWindow(), opts)
190}
191
192function PickrHook (obs) {
193 return function (element) {
194 var picker = new Pickr(element, {
195 enableTime: true,
196 altInput: true,
197 dateFormat: 'U',
198 onChange: function (dates) {
199 obs.set(spacetime(parseInt(element.value, 10) * 1000))
200 }
201 })
202
203 var value = obs()
204 if (value) {
205 picker.setDate(value.epoch)
206 }
207 return () => picker.destroy()
208 }
209}
210

Built with git-ssb-web