comparison libervia/web/pages/calls/_browser/__init__.py @ 1557:855729ef75f2

browser (calls): improve call buttons: - following template change, there are now a call button for video and one for audio, and no more "switch" button, this is more intuitive - search items have been customised with a 3 dots menu to show a dropdown, which let select the "video" or "audio" call mode. By defaut, a click on a search item will do a video call.
author Goffi <goffi@goffi.org>
date Tue, 15 Aug 2023 17:16:45 +0200
parents 83c2a6faa2ae
children 84f312be53b4
comparison
equal deleted inserted replaced
1556:5c4703870088 1557:855729ef75f2
43 bridge.register_signal("call_setup", self._on_call_setup) 43 bridge.register_signal("call_setup", self._on_call_setup)
44 bridge.register_signal("call_ended", self._on_call_ended) 44 bridge.register_signal("call_ended", self._on_call_ended)
45 45
46 # call/hang up buttons 46 # call/hang up buttons
47 self._call_mode = VIDEO 47 self._call_mode = VIDEO
48 self.call_button_tpl = Template("call/call_button.html") 48 document["video_call_btn"].bind(
49 self._update_call_button() 49 "click",
50 document["toggle_call_mode_btn"].bind("click", self.switch_call_mode) 50 lambda __: aio.run(self.make_call())
51
52 )
53 document["audio_call_btn"].bind(
54 "click",
55 lambda __: aio.run(self.make_call(video=False))
56
57 )
51 document["hangup_btn"].bind("click", lambda __: aio.run(self.hang_up())) 58 document["hangup_btn"].bind("click", lambda __: aio.run(self.hang_up()))
52 59
53 # other buttons 60 # other buttons
54 document["full_screen_btn"].bind("click", lambda __: self.toggle_fullscreen()) 61 document["full_screen_btn"].bind("click", lambda __: self.toggle_fullscreen())
55 document["exit_full_screen_btn"].bind( 62 document["exit_full_screen_btn"].bind(
65 else: 72 else:
66 self.share_desktop_btn_elt.classList.add("is-hidden") 73 self.share_desktop_btn_elt.classList.add("is-hidden")
67 74
68 # search 75 # search
69 self.jid_search = JidSearch( 76 self.jid_search = JidSearch(
70 document["search"], document["contacts"], click_cb=self._on_entity_click 77 document["search"],
78 document["contacts"],
79 click_cb=self._on_entity_click,
80 template="call/search_item.html",
81 options={
82 "no_group": True,
83 "extra_cb": {
84 ".dropdown-trigger": lambda evt, item: aio.run(
85 self.on_entity_action(evt, "menu", item)
86 ),
87 ".click-to-video": lambda evt, item: aio.run(
88 self.on_entity_action(evt, VIDEO, item)
89 ),
90 ".click-to-audio": lambda evt, item: aio.run(
91 self.on_entity_action(evt, AUDIO, item)
92 ),
93 }
94 }
71 ) 95 )
72 96
73 # incoming call dialog 97 # incoming call dialog
74 self.incoming_call_dialog_elt = None 98 self.incoming_call_dialog_elt = None
75 99
112 def call_mode(self, mode): 136 def call_mode(self, mode):
113 if mode in ALLOWED_CALL_MODES: 137 if mode in ALLOWED_CALL_MODES:
114 if self._call_mode == mode: 138 if self._call_mode == mode:
115 return 139 return
116 self._call_mode = mode 140 self._call_mode = mode
117 self._update_call_button()
118 with_video = mode == VIDEO 141 with_video = mode == VIDEO
119 for elt in self.call_box_elt.select(".is-video-only"): 142 for elt in self.call_box_elt.select(".is-video-only"):
120 if with_video: 143 if with_video:
121 elt.classList.remove("is-hidden") 144 elt.classList.remove("is-hidden")
122 else: 145 else:
123 elt.classList.add("is-hidden") 146 elt.classList.add("is-hidden")
124 else: 147 else:
125 raise ValueError("Invalid call mode") 148 raise ValueError("Invalid call mode")
126
127 def switch_call_mode(self, ev):
128 self.call_mode = AUDIO if self.call_mode == VIDEO else VIDEO
129
130 def _update_call_button(self):
131 new_button = self.call_button_tpl.get_elt({"call_mode": self.call_mode})
132 new_button.bind(
133 "click", lambda __: aio.run(self.make_call(video=not self.call_mode == AUDIO))
134 )
135 document["call_btn"].replaceWith(new_button)
136 149
137 def _on_action_new( 150 def _on_action_new(
138 self, action_data_s: str, action_id: str, security_limit: int, profile: str 151 self, action_data_s: str, action_id: str, security_limit: int, profile: str
139 ) -> None: 152 ) -> None:
140 """Called when a call is received 153 """Called when a call is received
259 """Start a WebRTC call 272 """Start a WebRTC call
260 273
261 @param audio: True if an audio flux is required 274 @param audio: True if an audio flux is required
262 @param video: True if a video flux is required 275 @param video: True if a video flux is required
263 """ 276 """
277 self.call_mode = VIDEO if video else AUDIO
264 try: 278 try:
265 callee_jid = JID(document["search"].value.strip()) 279 callee_jid = JID(document["search"].value.strip())
266 if not callee_jid.is_valid: 280 if not callee_jid.is_valid:
267 raise ValueError 281 raise ValueError
268 except ValueError: 282 except ValueError:
465 """Set entity JID to search bar, and start the call""" 479 """Set entity JID to search bar, and start the call"""
466 document["search"].value = item["entity"] 480 document["search"].value = item["entity"]
467 481
468 await self.make_call() 482 await self.make_call()
469 483
484 async def on_entity_action(self, evt, action: str, item: dict) -> None:
485 """Handle extra actions on search items"""
486 evt.stopPropagation()
487 if action == "menu":
488 evt.currentTarget.parent.classList.toggle("is-active")
489 elif action in (VIDEO, AUDIO):
490 document["search"].value = item["entity"]
491 # we want the dropdown to be inactive
492 evt.currentTarget.closest(".dropdown").classList.remove("is-active")
493 await self.make_call(video=action==VIDEO)
494
470 495
471 CallUI() 496 CallUI()
472 loading.remove_loading_screen() 497 loading.remove_loading_screen()