comparison libervia/pages/photos/album/_browser/__init__.py @ 1320:0cbf86b1dcca

browser (photos/album): invitation manager first draft.
author Goffi <goffi@goffi.org>
date Sat, 01 Aug 2020 16:47:24 +0200
parents 39a87d9099c4
children b525fdcb393b
comparison
equal deleted inserted replaced
1319:6e2821e78489 1320:0cbf86b1dcca
1 from browser import document, window, bind, html, DOMNode 1 from browser import document, window, bind, html, DOMNode, timer
2 from javascript import JSON 2 from javascript import JSON
3 from bridge import Bridge 3 from bridge import Bridge
4 from template import Template 4 from template import Template
5 import dialog 5 import dialog
6 from slideshow import SlideShow 6 from slideshow import SlideShow
7 7
8 files_service = window.files_service 8 files_service = window.files_service
9 files_path = window.files_path 9 files_path = window.files_path
10 bridge = Bridge() 10 bridge = Bridge()
11 11
12 # file upload
12 13
13 def on_progress(ev, photo_elt): 14 def on_progress(ev, photo_elt):
14 if ev.lengthComputable: 15 if ev.lengthComputable:
15 percent = int(ev.loaded/ev.total*100) 16 percent = int(ev.loaded/ev.total*100)
16 update_progress(photo_elt, percent) 17 update_progress(photo_elt, percent)
102 @bind("#file_input", "change") 103 @bind("#file_input", "change")
103 def on_file_input_change(evt): 104 def on_file_input_change(evt):
104 files = evt.currentTarget.files 105 files = evt.currentTarget.files
105 upload_files(files) 106 upload_files(files)
106 107
108 # delete
107 109
108 def file_delete_cb(item_elt, item): 110 def file_delete_cb(item_elt, item):
109 item_elt.classList.add("state_deleted") 111 item_elt.classList.add("state_deleted")
110 item_elt.bind("transitionend", lambda evt: item_elt.remove()) 112 item_elt.bind("transitionend", lambda evt: item_elt.remove())
111 print(f"deleted {item['name']}") 113 print(f"deleted {item['name']}")
144 ).show( 146 ).show(
145 ok_cb=lambda evt, notif_elt: delete_ok(evt, notif_elt, item_elt, item), 147 ok_cb=lambda evt, notif_elt: delete_ok(evt, notif_elt, item_elt, item),
146 cancel_cb=lambda evt, notif_elt: delete_cancel(evt, notif_elt, item_elt, item), 148 cancel_cb=lambda evt, notif_elt: delete_cancel(evt, notif_elt, item_elt, item),
147 ) 149 )
148 150
151 # slideshow
149 152
150 @bind(".photo_thumb_click", "click") 153 @bind(".photo_thumb_click", "click")
151 def photo_click(evt): 154 def photo_click(evt):
152 evt.stopPropagation() 155 evt.stopPropagation()
153 evt.preventDefault() 156 evt.preventDefault()
163 slideshow.index = idx 166 slideshow.index = idx
164 167
165 168
166 for elt in document.select('.action_delete'): 169 for elt in document.select('.action_delete'):
167 elt.bind("click", on_delete) 170 elt.bind("click", on_delete)
171
172 # manage
173
174 def on_manager_close(manager_panel_elt):
175 side_panel = manager_panel_elt.select_one('.invitation_manager_side_panel')
176 side_panel.classList.remove('open')
177 side_panel.bind("transitionend", lambda evt: manager_panel_elt.remove())
178
179 def _on_invitation_cb(field_elt, entity):
180 print(f"invitation for {entity!r} sent successfully")
181 submit_elt = document['invitation_submit']
182 submit_elt.disabled = False
183 form_elt = document['invitation_form']
184 form_elt.disabled = False
185 jids_elt = form_elt.select_one('*[name="jids"]')
186 emails_elt = form_elt.select_one('*[name="emails"]')
187 new = [d.strip() for d in field_elt.value.split('\n') if d and d.strip() != entity]
188 field_elt.value = '\n'.join(new)
189 if not jids_elt.value.strip() and not emails_elt.value.strip():
190 # FIXME: Q&D notification, needs to do this properly in a separated module with
191 # some animations
192 notifs_elt = document['invitation_notifications']
193 notification_elt = html.DIV(Class="notification is-success has-text-centered")
194 notification_elt <= "invitations sent successfully"
195 notifs_elt <= notification_elt
196 timer.set_timeout(lambda: notification_elt.remove(), 5000)
197
198
199 def invitationSimpleCreateCb(invitation_data, email):
200 invitee_jid = invitation_data['jid']
201 album_name = files_path.rsplit('/')[-1]
202 form_elt = document['invitation_form']
203 emails_elt = form_elt.select_one('*[name="emails"]')
204 bridge.FISInvite(
205 invitee_jid,
206 files_service,
207 "photos",
208 "",
209 files_path,
210 album_name,
211 '',
212 callback=lambda: _on_invitation_cb(emails_elt, email),
213 errback=lambda e: window.alert(f"invitation failed for {email}: {e}")
214 )
215
216
217 def invite_by_email(email):
218 guest_url_tpl = f'{window.URL.new("/g", document.baseURI).href}/{{uuid}}'
219 bridge.invitationSimpleCreate(
220 email,
221 guest_url_tpl,
222 '',
223 callback=lambda data: invitationSimpleCreateCb(data, email),
224 errback=lambda e: window.alert(f"can't send email invitation: {e}")
225 )
226
227
228 def on_invitation_submit(evt, manager_panel_elt):
229 evt.stopPropagation()
230 evt.preventDefault()
231 submit_elt = document['invitation_submit']
232 submit_elt.disabled = True
233 form_elt = document['invitation_form']
234 form_elt.disabled = True
235 jids_elt = form_elt.select_one('*[name="jids"]')
236 emails_elt = form_elt.select_one('*[name="emails"]')
237 jids = [j.strip() for j in jids_elt.value.split('\n') if j.strip()]
238 emails = [e.strip() for e in emails_elt.value.split('\n') if e.strip()]
239 album_name = files_path.rsplit('/')[-1]
240 for entity_jid in jids:
241 print(f"inviting {entity_jid}")
242 bridge.FISInvite(
243 entity_jid,
244 files_service,
245 "photos",
246 "",
247 files_path,
248 album_name,
249 '',
250 callback=lambda entity=entity_jid: _on_invitation_cb(jids_elt, entity),
251 errback=lambda e: window.alert(f"invitation failed: {e}")
252 )
253
254 for email in emails:
255 invite_by_email(email)
256
257 print(f"{jids=}, {emails=}")
258
259
260 def _FISAffiliationSetCb(affiliation_elt):
261 affiliation_elt.remove()
262
263
264 def on_affiliation_remove(entity_jid, affiliation_elt):
265 bridge.FISAffiliationsSet(
266 files_service,
267 "",
268 files_path,
269 {entity_jid: "none"},
270 callback=lambda: _FISAffiliationSetCb(affiliation_elt),
271 errback=lambda e: window.alert(f"can't remove affiliation: {e}")
272 )
273
274
275 @bind("#button_manage", "click")
276 def manage_click(evt):
277 evt.stopPropagation()
278 evt.preventDefault()
279 manager_panel_tpl = Template('invitation/manager.html')
280 manager_panel_elt = manager_panel_tpl.get_elt()
281 document.body <= manager_panel_elt
282 document['invitation_submit'].bind(
283 "click", lambda evt: on_invitation_submit(evt, manager_panel_elt))
284 side_panel = manager_panel_elt.select_one('.invitation_manager_side_panel')
285 timer.set_timeout(lambda: side_panel.classList.add("open"), 0)
286 for close_elt in manager_panel_elt.select('.click_to_close'):
287 close_elt.bind("click", lambda evt: on_manager_close(manager_panel_elt))
288 side_panel.bind("click", lambda evt: evt.stopPropagation())
289 affiliations = window.affiliations.to_dict()
290 affiliation_tpl = Template('invitation/affiliation_item.html')
291 for entity_jid, affiliation in affiliations.items():
292 affiliation_elt = affiliation_tpl.get_elt({
293 "entity_jid": entity_jid,
294 "affiliation": affiliation,
295 })
296 document['affiliations'] <= affiliation_elt
297 for elt in affiliation_elt.select(".click_to_delete"):
298 elt.bind(
299 "click",
300 lambda evt,
301 entity_jid=entity_jid,
302 affiliation_elt=affiliation_elt: on_affiliation_remove(
303 entity_jid,
304 affiliation_elt
305 )
306 )