Mercurial > libervia-web
comparison libervia/web/pages/calls/_browser/__init__.py @ 1563:e3449beac8d8
browser (calls): Add clear search + formatting
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 17 Aug 2023 16:23:01 +0200 |
parents | 4afafce0c4c9 |
children | bd3c880f4a47 |
comparison
equal
deleted
inserted
replaced
1562:4afafce0c4c9 | 1563:e3449beac8d8 |
---|---|
12 | 12 |
13 log.warning = log.warn | 13 log.warning = log.warn |
14 profile = window.profile or "" | 14 profile = window.profile or "" |
15 bridge = Bridge() | 15 bridge = Bridge() |
16 GATHER_TIMEOUT = 10000 | 16 GATHER_TIMEOUT = 10000 |
17 ALLOWED_STATUSES = (None, "dialing", "ringing", "in-call", "on-hold", "connecting", "connection-lost", "reconnecting") | 17 ALLOWED_STATUSES = ( |
18 None, | |
19 "dialing", | |
20 "ringing", | |
21 "in-call", | |
22 "on-hold", | |
23 "connecting", | |
24 "connection-lost", | |
25 "reconnecting", | |
26 ) | |
18 AUDIO = "audio" | 27 AUDIO = "audio" |
19 VIDEO = "video" | 28 VIDEO = "video" |
20 ALLOWED_CALL_MODES = {AUDIO, VIDEO} | 29 ALLOWED_CALL_MODES = {AUDIO, VIDEO} |
21 INACTIVE_CLASS = "inactive" | 30 INACTIVE_CLASS = "inactive" |
22 MUTED_CLASS = "muted" | 31 MUTED_CLASS = "muted" |
47 bridge.register_signal("call_setup", self._on_call_setup) | 56 bridge.register_signal("call_setup", self._on_call_setup) |
48 bridge.register_signal("call_ended", self._on_call_ended) | 57 bridge.register_signal("call_ended", self._on_call_ended) |
49 | 58 |
50 # call/hang up buttons | 59 # call/hang up buttons |
51 self._call_mode = VIDEO | 60 self._call_mode = VIDEO |
52 document["video_call_btn"].bind( | 61 document["video_call_btn"].bind("click", lambda __: aio.run(self.make_call())) |
53 "click", | |
54 lambda __: aio.run(self.make_call()) | |
55 | |
56 ) | |
57 document["audio_call_btn"].bind( | 62 document["audio_call_btn"].bind( |
58 "click", | 63 "click", lambda __: aio.run(self.make_call(video=False)) |
59 lambda __: aio.run(self.make_call(video=False)) | |
60 | |
61 ) | 64 ) |
62 document["hangup_btn"].bind("click", lambda __: aio.run(self.hang_up())) | 65 document["hangup_btn"].bind("click", lambda __: aio.run(self.hang_up())) |
63 | 66 |
64 # other buttons | 67 # other buttons |
65 document["full_screen_btn"].bind("click", lambda __: self.toggle_fullscreen()) | 68 document["full_screen_btn"].bind("click", lambda __: self.toggle_fullscreen()) |
75 self.share_desktop_btn_elt.bind("click", self.toggle_screen_sharing) | 78 self.share_desktop_btn_elt.bind("click", self.toggle_screen_sharing) |
76 else: | 79 else: |
77 self.share_desktop_btn_elt.classList.add("is-hidden") | 80 self.share_desktop_btn_elt.classList.add("is-hidden") |
78 | 81 |
79 # search | 82 # search |
83 self.search_elt = document["search"] | |
80 self.jid_search = JidSearch( | 84 self.jid_search = JidSearch( |
81 document["search"], | 85 self.search_elt, |
82 document["contacts"], | 86 document["contacts"], |
83 click_cb=self._on_entity_click, | 87 click_cb=self._on_entity_click, |
84 template="call/search_item.html", | 88 template="call/search_item.html", |
85 options={ | 89 options={ |
86 "no_group": True, | 90 "no_group": True, |
92 self.on_entity_action(evt, VIDEO, item) | 96 self.on_entity_action(evt, VIDEO, item) |
93 ), | 97 ), |
94 ".click-to-audio": lambda evt, item: aio.run( | 98 ".click-to-audio": lambda evt, item: aio.run( |
95 self.on_entity_action(evt, AUDIO, item) | 99 self.on_entity_action(evt, AUDIO, item) |
96 ), | 100 ), |
97 } | 101 }, |
98 } | 102 }, |
99 ) | 103 ) |
104 document["clear_search_btn"].bind("click", self.on_clear_search) | |
100 | 105 |
101 # incoming call dialog | 106 # incoming call dialog |
102 self.incoming_call_dialog_elt = None | 107 self.incoming_call_dialog_elt = None |
103 | 108 |
104 @property | 109 @property |
149 else: | 154 else: |
150 elt.classList.add("is-hidden") | 155 elt.classList.add("is-hidden") |
151 else: | 156 else: |
152 raise ValueError("Invalid call mode") | 157 raise ValueError("Invalid call mode") |
153 | 158 |
154 def set_avatar(self, entity_jid: JID|str) -> None: | 159 def set_avatar(self, entity_jid: JID | str) -> None: |
155 """Set the avatar element from entity_jid | 160 """Set the avatar element from entity_jid |
156 | 161 |
157 @param entity_jid: bare jid of the entity | 162 @param entity_jid: bare jid of the entity |
158 """ | 163 """ |
159 call_avatar_elt = self.call_avatar_tpl.get_elt( | 164 call_avatar_elt = self.call_avatar_tpl.get_elt( |
310 @param audio: True if an audio flux is required | 315 @param audio: True if an audio flux is required |
311 @param video: True if a video flux is required | 316 @param video: True if a video flux is required |
312 """ | 317 """ |
313 self.call_mode = VIDEO if video else AUDIO | 318 self.call_mode = VIDEO if video else AUDIO |
314 try: | 319 try: |
315 callee_jid = JID(document["search"].value.strip()) | 320 callee_jid = JID(self.search_elt.value.strip()) |
316 if not callee_jid.is_valid: | 321 if not callee_jid.is_valid: |
317 raise ValueError | 322 raise ValueError |
318 except ValueError: | 323 except ValueError: |
319 dialog.notification.show( | 324 dialog.notification.show( |
320 "Invalid identifier, please use a valid callee identifier", level="error" | 325 "Invalid identifier, please use a valid callee identifier", level="error" |
429 ) | 434 ) |
430 self.mode = mode | 435 self.mode = mode |
431 else: | 436 else: |
432 log.error(f"Internal Error: Unknown call mode: {mode}") | 437 log.error(f"Internal Error: Unknown call mode: {mode}") |
433 | 438 |
439 def on_clear_search(self, ev) -> None: | |
440 """Clear the search input and trigger its 'input' event. | |
441 | |
442 @param ev: the event object from the button click. | |
443 """ | |
444 if not self.search_elt.value: | |
445 return | |
446 # clear the search field | |
447 self.search_elt.value = '' | |
448 # and dispatch the input event so items are updated | |
449 self.search_elt.dispatchEvent(window.Event.new("input")) | |
450 | |
434 def toggle_fullscreen(self, fullscreen: bool | None = None): | 451 def toggle_fullscreen(self, fullscreen: bool | None = None): |
435 """Toggle fullscreen mode for video elements. | 452 """Toggle fullscreen mode for video elements. |
436 | 453 |
437 @param fullscreen: if set, determine the fullscreen state; otherwise, | 454 @param fullscreen: if set, determine the fullscreen state; otherwise, |
438 the fullscreen mode will be toggled. | 455 the fullscreen mode will be toggled. |
439 """ | 456 """ |
440 do_fullscreen = ( | 457 do_fullscreen = ( |
441 document.fullscreenElement is None if fullscreen is None else fullscreen | 458 document.fullscreenElement is None if fullscreen is None else fullscreen |
442 ) | 459 ) |
443 | 460 |
504 def _on_entity_click(self, item: dict) -> None: | 521 def _on_entity_click(self, item: dict) -> None: |
505 aio.run(self.on_entity_click(item)) | 522 aio.run(self.on_entity_click(item)) |
506 | 523 |
507 async def on_entity_click(self, item: dict) -> None: | 524 async def on_entity_click(self, item: dict) -> None: |
508 """Set entity JID to search bar, and start the call""" | 525 """Set entity JID to search bar, and start the call""" |
509 document["search"].value = item["entity"] | 526 self.search_elt.value = item["entity"] |
510 | 527 |
511 await self.make_call() | 528 await self.make_call() |
512 | 529 |
513 async def on_entity_action(self, evt, action: str, item: dict) -> None: | 530 async def on_entity_action(self, evt, action: str, item: dict) -> None: |
514 """Handle extra actions on search items""" | 531 """Handle extra actions on search items""" |
515 evt.stopPropagation() | 532 evt.stopPropagation() |
516 if action == "menu": | 533 if action == "menu": |
517 evt.currentTarget.parent.classList.toggle("is-active") | 534 evt.currentTarget.parent.classList.toggle("is-active") |
518 elif action in (VIDEO, AUDIO): | 535 elif action in (VIDEO, AUDIO): |
519 document["search"].value = item["entity"] | 536 self.search_elt.value = item["entity"] |
520 # we want the dropdown to be inactive | 537 # we want the dropdown to be inactive |
521 evt.currentTarget.closest(".dropdown").classList.remove("is-active") | 538 evt.currentTarget.closest(".dropdown").classList.remove("is-active") |
522 await self.make_call(video=action==VIDEO) | 539 await self.make_call(video=action == VIDEO) |
523 | 540 |
524 | 541 |
525 CallUI() | 542 CallUI() |
526 loading.remove_loading_screen() | 543 loading.remove_loading_screen() |