annotate libervia/web/pages/calls/_browser/__init__.py @ 1618:5d9889f14012 default tip @

server: start major redesign - Add icons to menu items - Switch menu items representation from tuple to dictionary for future extensibility: - Include icon information - Prepare for additional data - Remove "login" from main menu, add login page URL to template data, as it is now a separate right-aligned item
author Goffi <goffi@goffi.org>
date Sat, 26 Oct 2024 23:07:01 +0200
parents 6bfeb9f0fb84
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 import json
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 from bridge import AsyncBridge as Bridge
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
4 from browser import aio, console as log, document, window
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
5 from cache import cache
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
6 import dialog
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
7 from javascript import JSObject, NULL
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
8 from jid import JID
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
9 from jid_search import JidSearch
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 import loading
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
11 from template import Template
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
12 from webrtc import WebRTC
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 log.warning = log.warn
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 profile = window.profile or ""
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
16 own_jid = JID(window.own_jid)
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 bridge = Bridge()
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 GATHER_TIMEOUT = 10000
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
19 ALLOWED_STATUSES = (
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
20 None,
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
21 "dialing",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
22 "ringing",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
23 "in-call",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
24 "on-hold",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
25 "connecting",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
26 "connection-lost",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
27 "reconnecting",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
28 )
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
29 AUDIO = "audio"
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
30 VIDEO = "video"
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
31 REMOTE = "remote-control"
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
32 ALLOWED_CALL_MODES = {AUDIO, VIDEO, REMOTE}
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
33 INACTIVE_CLASS = "inactive"
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
34 MUTED_CLASS = "muted"
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
35 SCREEN_OFF_CLASS = "screen-off"
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
36 MUJI_PREFIX = "_muji_"
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
39 class CallUI:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 def __init__(self):
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
41 self.webrtc = WebRTC(
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
42 screen_sharing_cb=self.on_sharing_screen,
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
43 on_connection_established_cb=self.on_connection_established,
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
44 on_reconnect_cb=self.on_reconnect,
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
45 on_connection_lost_cb=self.on_connection_lost,
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
46 on_video_devices=self.on_video_devices,
1565
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
47 on_reset_cb=self.on_reset_cb,
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
48 local_video_elt=document["local_video"],
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
49 remote_video_elt=document["remote_video"]
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
50 )
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
51 # mapping of file sending
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
52 self.files_webrtc: list[dict] = []
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
53 self.mode = "search"
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
54 self._status = None
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
55 self._callee: JID|None = None
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
56 self._group_call_room: JID|None = None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
57 self._group_call_peers: dict = {}
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
58 self.is_conference = False
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
59 self.contacts_elt = document["contacts"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
60 self.search_container_elt = document["search_container"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
61 self.call_container_elt = document["call_container"]
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
62 self.group_call_container_elt = document["group_call_container"]
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
63 self.call_box_elt = document["call_box"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
64 self.call_avatar_wrapper_elt = document["call_avatar_wrapper"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
65 self.call_status_wrapper_elt = document["call_status_wrapper"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
66 self.call_avatar_tpl = Template("call/call_avatar.html")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
67 self.call_status_tpl = Template("call/call_status.html")
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
68 self.group_peer_tpl = Template("call/group_peer.html")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
69 self.audio_player_elt = document["audio_player"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
70 bridge.register_signal("action_new", self._on_action_new)
1560
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
71 bridge.register_signal("call_info", self._on_call_info)
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
72 bridge.register_signal("call_setup", self._on_call_setup)
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
73 bridge.register_signal("call_ended", self._on_call_ended)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
74 bridge.register_signal("call_group_setup", self._on_call_group_setup)
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
75
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
76 # call/hang up buttons
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
77 self._call_mode = VIDEO
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
78 document["video_call_btn"].bind("click", lambda __: aio.run(self.make_call()))
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
79 document["audio_call_btn"].bind(
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
80 "click", lambda __: aio.run(self.make_call(video=False))
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
81 )
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
82 document["group_call_btn"].bind(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
83 "click",
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
84 lambda __: aio.run(self.make_group_call())
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
85 )
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
86 document["hangup_btn"].bind("click", lambda __: aio.run(self.hang_up()))
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
87 document["group_hangup_btn"].bind("click", lambda __: aio.run(self.group_hang_up()))
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
88
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
89 # other buttons
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
90 document["full_screen_btn"].bind("click", lambda __: self.toggle_fullscreen())
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
91 document["exit_full_screen_btn"].bind(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
92 "click", lambda __: self.toggle_fullscreen()
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 )
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
94 document["group_full_screen_btn"].bind(
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
95 "click",
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
96 lambda __: self.toggle_fullscreen(group=True)
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
97 )
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
98 document["group_exit_full_screen_btn"].bind(
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
99 "click",
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
100 lambda __: self.toggle_fullscreen(group=True)
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
101 )
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
102 document["mute_audio_btn"].bind("click", self.toggle_audio_mute)
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
103 document["mute_video_btn"].bind("click", self.toggle_video_mute)
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
104 self.share_desktop_col_elt = document["share_desktop_column"]
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
105 if hasattr(window.navigator.mediaDevices, "getDisplayMedia"):
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
106 self.share_desktop_col_elt.classList.remove("is-hidden-touch")
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
107 # screen sharing is supported
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
108 document["share_desktop_btn"].bind("click", self.toggle_screen_sharing)
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
109 else:
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
110 self.share_desktop_col_elt.classList.add("is-hidden")
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
111 document["switch_camera_btn"].bind("click", self.on_switch_camera)
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
112 document["send_file_btn"].bind("click", self.on_send_file)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
113 document["send_file_input"].bind("change", self._on_send_input_change)
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
114
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
115 # search
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
116 self.search_elt = document["search"]
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
117 self.jid_search = JidSearch(
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
118 self.search_elt,
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
119 document["contacts"],
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
120 click_cb=self._on_entity_click,
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
121 allow_multiple_selection=True,
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
122 template="call/search_item.html",
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
123 selection_state_callback=self._on_search_selection,
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
124 options={
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
125 "no_group": True,
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
126 "extra_cb": {
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
127 ".dropdown-trigger": lambda evt, item: aio.run(
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
128 self.on_entity_action(evt, "menu", item)
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
129 ),
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
130 ".click-to-video": lambda evt, item: aio.run(
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
131 self.on_entity_action(evt, VIDEO, item)
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
132 ),
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
133 ".click-to-audio": lambda evt, item: aio.run(
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
134 self.on_entity_action(evt, AUDIO, item)
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
135 ),
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
136 ".click-to-remote-control": lambda evt, item: aio.run(
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
137 self.on_entity_action(evt, REMOTE, item)
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
138 ),
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
139 },
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
140 },
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 )
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
142 document["clear_search_btn"].bind("click", self.on_clear_search)
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
143
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
144 # incoming call dialog
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
145 self.incoming_call_dialog_elt = None
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
146
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
147 @property
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
148 def sid(self) -> str | None:
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
149 return self.webrtc.sid
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
150
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
151 @sid.setter
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
152 def sid(self, new_sid) -> None:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
153 self.webrtc.sid = new_sid
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
154
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
155 @property
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
156 def status(self):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
157 return self._status
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
158
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
159 @status.setter
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
160 def status(self, new_status):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
161 if new_status != self._status:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
162 if new_status not in ALLOWED_STATUSES:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
163 raise Exception(
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
164 f"INTERNAL ERROR: this status is not allowed: {new_status!r}"
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
165 )
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
166 tpl_data = {"entity": self._callee, "status": new_status}
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
167 if self._callee is not None:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
168 try:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
169 tpl_data["name"] = cache.identities[self._callee]["nicknames"][0]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
170 except (KeyError, IndexError):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
171 tpl_data["name"] = str(self._callee)
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
172 status_elt = self.call_status_tpl.get_elt(tpl_data)
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
173 self.call_status_wrapper_elt.clear()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
174 self.call_status_wrapper_elt <= status_elt
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
175
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
176 self._status = new_status
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
177
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
178 @property
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
179 def call_mode(self):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
180 return self._call_mode
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
181
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
182 @call_mode.setter
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
183 def call_mode(self, mode):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
184 if mode in ALLOWED_CALL_MODES:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
185 if self._call_mode == mode:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
186 return
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
187 log.debug("Switching to {mode} call mode.")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
188 self._call_mode = mode
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
189 selector = ".is-video-only, .is-not-remote"
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
190 for elt in self.call_box_elt.select(selector):
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
191 if mode == VIDEO:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
192 # In video, all elements are visible.
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
193 elt.classList.remove("is-hidden")
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
194 elif mode == AUDIO:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
195 # In audio, we hide video-only elements.
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
196 if elt.classList.contains("is-video-only"):
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
197 elt.classList.add("is-hidden")
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
198 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
199 elt.classList.remove("is-hidden")
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
200 elif mode == REMOTE:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
201 # In remote, we show all video element, except if they are
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
202 # `is-not-remote`
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
203 if elt.classList.contains("is-not-remote"):
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
204 elt.classList.add("is-hidden")
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
205 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
206 elt.classList.remove("is-hidden")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
207 else:
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
208 raise Exception("This line should never be reached.")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
209 else:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
210 raise ValueError("Invalid call mode")
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
211
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
212 def set_avatar(self, entity_jid: JID | str) -> None:
1562
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
213 """Set the avatar element from entity_jid
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
214
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
215 @param entity_jid: bare jid of the entity
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
216 """
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
217 call_avatar_elt = self.call_avatar_tpl.get_elt(
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
218 {
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
219 "entity": str(entity_jid),
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
220 "identities": cache.identities,
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
221 }
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
222 )
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
223 self.call_avatar_wrapper_elt.clear()
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
224 self.call_avatar_wrapper_elt <= call_avatar_elt
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
225
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
226 def _on_action_new(
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 self, action_data_s: str, action_id: str, security_limit: int, profile: str
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 ) -> None:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 """Called when a call is received
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
230
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 @param action_data_s: Action data serialized
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 @param action_id: Unique identifier for the action
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 @param security_limit: Security limit for the action
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 @param profile: Profile associated with the action
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 """
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 action_data = json.loads(action_data_s)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
237 type_ = action_data.get("type")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
238 subtype = action_data.get("subtype")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
239 if type_ in ("confirm", "not_in_roster_leak") and subtype == "file":
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
240 aio.run(self.on_file_preflight(action_data, action_id))
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
241 elif type_ == "file":
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
242 aio.run(self.on_file_proposal(action_data, action_id))
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
243 elif (
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
244 type_ == "confirm"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
245 and subtype == "muc-invitation"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
246 # FIXME: Q&D hack until there is a proper group call invitation solution.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
247 and MUJI_PREFIX in action_data.get("room_jid", "")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
248 ):
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
249 aio.run(self.on_group_call_proposal(action_data, action_id))
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
250 elif type_ != "call":
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 return
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
252 elif MUJI_PREFIX in action_data.get("from_jid", ""):
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
253 aio.run(self.on_group_call_join(action_data, action_id))
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
254 elif self.is_conference and action_data["from_jid"] == self._callee:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
255 aio.run(self.on_conference_call_join(action_data, action_id))
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
256 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
257 aio.run(self.on_action_new(action_data, action_id))
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
258
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
259 def get_human_size(self, size: int|float) -> str:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
260 """Return size in human-friendly size using SI units"""
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
261 units = ["o","Kio","Mio","Gio"]
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
262 for idx, unit in enumerate(units):
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
263 if size < 1024.0 or idx == len(units)-1:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
264 return f"{size:.2f}{unit}"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
265 size /= 1024.0
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
266 raise Exception("Internal Error: this line should never be reached.")
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
267
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
268 async def request_file_permission(self, action_data: dict) -> bool:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
269 """Request permission to download a file."""
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
270 peer_jid = JID(action_data["from_jid"]).bare
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
271 await cache.fill_identities([peer_jid])
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
272 try:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
273 identity = cache.identities[peer_jid]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
274 except KeyError:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
275 peer_name = peer_jid.local
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
276 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
277 peer_name = identity["nicknames"][0]
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
278
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
279 file_data = action_data.get("file_data", {})
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
280
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
281 file_name = file_data.get('name')
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
282 file_size = file_data.get('size')
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
283
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
284 if file_name:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
285 file_name_msg = 'wants to send you the file "{file_name}"'.format(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
286 file_name=file_name
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
287 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
288 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
289 file_name_msg = 'wants to send you an unnamed file'
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
290
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
291 if file_size is not None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
292 file_size_msg = "which has a size of {file_size_human}".format(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
293 file_size_human=self.get_human_size(file_size)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
294 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
295 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
296 file_size_msg = "which has an unknown size"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
297
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
298 file_description = file_data.get('desc')
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
299 if file_description:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
300 description_msg = " Description: {}.".format(file_description)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
301 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
302 description_msg = ""
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
303
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
304 file_data = action_data.get("file_data", {})
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
305
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
306 file_accept_dlg = dialog.Confirm(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
307 "{peer_name} ({peer_jid}) {file_name_msg} {file_size_msg}.{description_msg} Do you "
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
308 "accept?".format(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
309 peer_name=peer_name,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
310 peer_jid=peer_jid,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
311 file_name_msg=file_name_msg,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
312 file_size_msg=file_size_msg,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
313 description_msg=description_msg
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
314 ),
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
315 ok_label="Download",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
316 cancel_label="Reject"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
317 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
318 return await file_accept_dlg.ashow()
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
319
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
320 async def on_file_preflight(self, action_data: dict, action_id: str) -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
321 """Handle a file preflight (proposal made to all devices)."""
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
322 # FIXME: temporarily done in call page, will be moved to notifications handler to
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
323 # make it work anywhere.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
324 accepted = await self.request_file_permission(action_data)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
325
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
326 await bridge.action_launch(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
327 action_id, json.dumps({"answer": str(accepted).lower()})
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
328 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
329
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
330 async def on_file_proposal(self, action_data: dict, action_id: str) -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
331 """Handle a file proposal.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
332
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
333 This is a proposal made specifically to this device, a opposed to
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
334 ``on_file_preflight``. File may already have been accepted during preflight.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
335 """
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
336 # FIXME: as for on_file_preflight, this will be moved to notification handler.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
337 if not action_data.get("webrtc", False):
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
338 peer_jid = JID(action_data["from_jid"]).bare
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
339 # We try to do a not-too-technical warning about webrtc not being supported.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
340 dialog.notification.show(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
341 f"A file sending from {peer_jid} can't be accepted because it is not "
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
342 "compatible with web browser direct transfer (WebRTC).",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
343 level="warning",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
344 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
345 # We don't explicitly refuse the file proposal, because it may be accepted and
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
346 # supported by other frontends.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
347 # TODO: Check if any other frontend is connected for this profile, and refuse
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
348 # the file if none is.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
349 return
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
350 if action_data.get("pre_accepted", False):
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
351 # File proposal has already been accepted in preflight.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
352 accepted = True
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
353 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
354 accepted = await self.request_file_permission(action_data)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
355
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
356 if accepted:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
357 sid = action_data["session_id"]
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
358 webrtc = WebRTC(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
359 file_only=True,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
360 extra_data={"file_data": action_data.get("file_data", {})}
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
361 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
362 webrtc.sid = sid
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
363 self.files_webrtc.append({
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
364 "webrtc": webrtc,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
365 })
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
366
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
367 await bridge.action_launch(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
368 action_id, json.dumps({"answer": str(accepted).lower()})
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
369 )
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
370
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
371 async def on_group_call_proposal(self, action_data: dict, action_id: str) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
372 """Handle a group call proposal."""
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
373 peer_jid = JID(action_data["from_jid"]).bare
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
374 await cache.fill_identities([peer_jid])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
375 identity = cache.identities[peer_jid]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
376 peer_name = identity["nicknames"][0]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
377
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
378 group_call_accept_dlg = dialog.Confirm(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
379 "{peer_name} ({peer_jid}) proposes a group call to you. Do you accept?"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
380 .format(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
381 peer_name=peer_name,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
382 peer_jid=peer_jid,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
383 ),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
384 ok_label="Accept Group Call",
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
385 cancel_label="Reject"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
386 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
387 accepted = await group_call_accept_dlg.ashow()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
388 if accepted:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
389 self.switch_mode("group_call")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
390 await bridge.action_launch(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
391 action_id, json.dumps({"answer": str(accepted).lower()})
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
392 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
393
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
394 async def on_group_call_join(self, action_data: dict, action_id: str) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
395 peer_jid = JID(action_data["from_jid"])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
396 if peer_jid.bare != self._group_call_room:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
397 log.warning(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
398 f"Refusing group call join as were are not expecting any from this room.\n"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
399 f"{peer_jid.bare=} {self._group_call_room=}"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
400 )
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
401 return
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
402 log.info(f"{peer_jid} joined the group call.")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
403
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
404 group_video_grid_elt = document["group_video_grid"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
405 await cache.fill_identities([peer_jid])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
406
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
407 group_peer_elt = self.group_peer_tpl.get_elt({
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
408 "entity": str(peer_jid),
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
409 "identities": cache.identities,
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
410 })
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
411 for pin_item in group_peer_elt.select('.action_pin'):
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
412 pin_item.bind('click', self.toggle_pin)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
413 group_video_grid_elt <= group_peer_elt
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
414
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
415 peer_video_stream_elt = group_peer_elt.select_one(".peer_video_stream")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
416 assert peer_video_stream_elt is not None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
417 webrtc = WebRTC(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
418 remote_video_elt=peer_video_stream_elt
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
419 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
420 sid = webrtc.sid = action_data["session_id"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
421 self._group_call_peers[peer_jid] = {
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
422 "webrtc": webrtc,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
423 "element": group_peer_elt,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
424 "sid": sid
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
425 }
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
426
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
427 log.debug(f"Call SID: {sid}")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
428
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
429 await bridge.action_launch(action_id, json.dumps({"cancelled": False}))
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
430
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
431 async def on_conference_call_join(self, action_data: dict, action_id: str) -> None:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
432 log.debug(f"on_conference_call_join {action_data=}")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
433 peer_jid = JID(action_data["from_jid"])
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
434 try:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
435 user_jid = JID(action_data["metadata"]["user"])
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
436 except KeyError:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
437 user_jid = peer_jid
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
438 log.info(f"{user_jid} joined the conference call.")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
439
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
440 group_video_grid_elt = document["group_video_grid"]
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
441 await cache.fill_identities([str(user_jid)])
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
442
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
443 group_peer_elt = self.group_peer_tpl.get_elt({
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
444 "entity": str(user_jid),
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
445 "identities": cache.identities,
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
446 })
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
447 for pin_item in group_peer_elt.select('.action_pin'):
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
448 pin_item.bind('click', self.toggle_pin)
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
449 group_video_grid_elt <= group_peer_elt
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
450 peer_video_stream_elt = group_peer_elt.select_one(".peer_video_stream")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
451 assert peer_video_stream_elt is not None
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
452 log.debug(f"starting webrtc for {peer_jid} on {peer_video_stream_elt}")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
453 webrtc = WebRTC(
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
454 remote_video_elt=peer_video_stream_elt
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
455 )
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
456 sid = webrtc.sid = action_data["session_id"]
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
457 self._group_call_peers[peer_jid] = {
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
458 "webrtc": webrtc,
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
459 "element": group_peer_elt,
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
460 "sid": sid
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
461 }
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
462
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
463 log.debug(f"Somebody joined conference call. SID: {sid}")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
464
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
465 await bridge.action_launch(action_id, json.dumps({"cancelled": False}))
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
466
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
467 async def on_action_new(self, action_data: dict, action_id: str) -> None:
1562
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
468 peer_jid = JID(action_data["from_jid"]).bare
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
469 call_type = action_data["sub_type"]
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
470 call_emoji = "📹" if call_type == VIDEO else "📞"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
471 log.info(f"{peer_jid} wants to start a call ({call_type}).")
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
472 if self.sid is not None:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
473 log.warning(
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
474 f"already in a call ({self.sid}), can't receive a new call from "
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
475 f"{peer_jid}"
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
476 )
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
477 return
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
478 sid = self.sid = action_data["session_id"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
479 await cache.fill_identities([peer_jid])
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
480 try:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
481 identity = cache.identities[peer_jid]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
482 except KeyError:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
483 peer_name = peer_jid.local
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
484 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
485 peer_name = identity["nicknames"][0]
1562
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
486 self._callee = peer_jid
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
487
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
488 # we start the ring
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
489 self.audio_player_elt.play()
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
490
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
491 # and ask user if we take the call
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
492 try:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
493 self.incoming_call_dialog_elt = dialog.Confirm(
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
494 f"{peer_name} is calling you ({call_emoji}{call_type}).", ok_label="Answer", cancel_label="Reject"
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
495 )
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
496 accepted = await self.incoming_call_dialog_elt.ashow()
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
497 except dialog.CancelError as e:
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
498 log.info("Call has been cancelled")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
499 self.incoming_call_dialog_elt = None
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
500 self.sid = None
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
501 match e.reason:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
502 case "busy":
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
503 dialog.notification.show(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
504 f"{peer_name} can't answer your call",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
505 level="info",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
506 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
507 case "taken_by_other_device":
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
508 device = e.text
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
509 dialog.notification.show(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
510 f"The call has been taken on another device ({device}).",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
511 level="info",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
512 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
513 case _:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
514 dialog.notification.show(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
515 f"{peer_name} has cancelled the call",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
516 level="info"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
517 )
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
518 return
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
519
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
520 self.incoming_call_dialog_elt = None
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
521
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
522 # we stop the ring
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
523 self.audio_player_elt.pause()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
524 self.audio_player_elt.currentTime = 0
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
525
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
526 if accepted:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
527 log.debug(f"Call SID: {sid}")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
528
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
529 # Answer the call
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
530 self.call_mode = call_type
1562
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
531 self.set_avatar(peer_jid)
1561
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
532 self.status = "connecting"
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
533 self.switch_mode("call")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
534 else:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
535 log.info(f"your are declining the call from {peer_jid}")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
536 self.sid = None
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
537 await bridge.action_launch(action_id, json.dumps({"cancelled": not accepted}))
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
538
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
539 def _on_call_ended(self, session_id: str, data_s: str, profile: str) -> None:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
540 """Call has been terminated
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
541
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
542 @param session_id: Session identifier
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
543 @param data_s: Serialised additional data on why the call has ended
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
544 @param profile: Profile associated
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
545 """
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
546 if self.sid is None:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
547 log.debug("there are no calls in progress")
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
548 return
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
549 if session_id != self.sid:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
550 log.debug(
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
551 f"ignoring call_ended not linked to our call ({self.sid}): {session_id}"
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
552 )
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
553 return
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
554 aio.run(self.end_call(json.loads(data_s)))
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
555
1560
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
556 def _on_call_info(self, session_id: str, info_type, info_data_s: str, profile: str):
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
557 if self.sid != session_id:
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
558 return
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
559 if info_type == "ringing":
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
560 self.status = "ringing"
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
561
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
562 def _on_call_setup(self, session_id: str, setup_data_s: str, profile: str) -> None:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
563 """Called when we have received answer SDP from responder
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
564
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
565 @param session_id: Session identifier
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
566 @param sdp: Session Description Protocol data
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
567 @param profile: Profile associated with the action
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
568 """
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
569 aio.run(self.on_call_setup(session_id, json.loads(setup_data_s), profile))
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
570
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
571 async def on_call_setup(
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
572 self, session_id: str, setup_data: dict, profile: str
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
573 ) -> None:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
574 """Call has been accepted, connection can be established
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
575
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
576 @param session_id: Session identifier
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
577 @param setup_data: Data with following keys:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
578 role: initiator or responser
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
579 sdp: Session Description Protocol data
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
580 @param profile: Profile associated
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
581 """
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
582 if self.sid == session_id:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
583 webrtc = self.webrtc
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
584 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
585 for file_webrtc in self.files_webrtc:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
586 webrtc = file_webrtc["webrtc"]
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
587 if webrtc.sid == session_id:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
588 break
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
589 else:
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
590 for peer_data in self._group_call_peers.values():
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
591 webrtc = peer_data["webrtc"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
592 if webrtc.sid == session_id:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
593 break
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
594 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
595 log.debug(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
596 f"Call ignored due to different session ID ({self.sid=} "
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
597 f"{session_id=})"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
598 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
599 return
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
600 try:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
601 role = setup_data["role"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
602 sdp = setup_data["sdp"]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
603 except KeyError:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
604 dialog.notification.show(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
605 f"Invalid setup data received: {setup_data}", level="error"
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
606 )
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
607 return
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
608 if role == "initiator":
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
609 await webrtc.accept_call(session_id, sdp, profile)
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
610 elif role == "responder":
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
611 await webrtc.answer_call(
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
612 session_id, sdp, profile, conference=self.is_conference
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
613 )
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
614 else:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
615 dialog.notification.show(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
616 f"Invalid role received during setup: {setup_data}", level="error"
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
617 )
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
618 return
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
619
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
620 def _on_call_group_setup(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
621 self,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
622 room_jid_s: str,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
623 setup_data_s: str,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
624 profile: str
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
625 ) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
626 """Called when we are finishing preparation of a group call.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
627
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
628 @param room_jid_s: JID of the room used for group call coordination.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
629 @param setup_data_s: serialised data of group call options, such as codec
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
630 restrictions.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
631 @param profile: Profile associated with the action
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
632 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
633 if setup_data_s:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
634 setup_data = json.loads(setup_data_s)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
635 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
636 setup_data = {}
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
637 aio.run(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
638 self.on_call_group_setup(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
639 JID(room_jid_s),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
640 setup_data,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
641 profile
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
642 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
643 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
644
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
645 async def on_call_group_setup(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
646 self, room_jid: JID, setup_data: dict, profile: str
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
647 ) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
648 """Call has been accepted, connection can be established
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
649
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
650 @param session_id: Session identifier
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
651 @param setup_data: Data with following keys:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
652 role: initiator or responser
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
653 sdp: Session Description Protocol data
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
654 @param profile: Profile associated
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
655 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
656 log.info(f"Setting up group call at {room_jid}.")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
657 try:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
658 to_call = setup_data["to_call"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
659 except KeyError:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
660 dialog.notification.show(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
661 'Internal error: missing "to_call" data.', level="error"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
662 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
663 return
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
664
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
665 # we need a remote_video_elt to instantiate, but it won't be used.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
666 webrtc = WebRTC(remote_video_elt=document["remote_video"])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
667 call_data = await webrtc.prepare_call()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
668
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
669 # we have just used this WebRTC instance to get calling data.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
670 await webrtc.end_call()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
671 del webrtc
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
672 await bridge.call_group_data_set(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
673 str(room_jid),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
674 json.dumps(call_data),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
675 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
676 # At this point, we can initiate the call.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
677 # As per specification, we call each entity which was preparing when we started
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
678 # our own preparation.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
679 group_video_grid_elt = document["group_video_grid"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
680 local_stream = None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
681 for entity_jid_s in to_call:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
682 entity_jid = JID(entity_jid_s)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
683 log.info(f"Calling {entity_jid_s}.")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
684 await cache.fill_identities([entity_jid])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
685 group_peer_elt = self.group_peer_tpl.get_elt({
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
686 "entity": str(entity_jid),
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
687 "identities": cache.identities,
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
688 })
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
689 for pin_item in group_peer_elt.select('.action_pin'):
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
690 pin_item.bind('click', self.toggle_pin)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
691 group_video_grid_elt <= group_peer_elt
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
692 peer_video_stream_elt = group_peer_elt.select_one(".peer_video_stream")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
693 assert peer_video_stream_elt is not None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
694 webrtc = WebRTC(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
695 remote_video_elt=peer_video_stream_elt,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
696 local_stream=local_stream
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
697 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
698
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
699 self._group_call_peers[JID(entity_jid)] = {
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
700 "webrtc": webrtc
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
701 }
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
702 await webrtc.make_call(entity_jid)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
703 # we save the local stream to re-use it with next WebRTC instance.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
704 if local_stream is None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
705 local_stream = webrtc.local_stream
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
706
1561
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
707 def on_connection_established(self):
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
708 self.status = "in-call"
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
709
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
710 def on_reconnect(self):
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
711 self.status = "reconnecting"
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
712
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
713 def on_connection_lost(self):
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
714 self.status = "connection-lost"
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
715
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
716 def on_video_devices(self, has_multiple_cameras: bool) -> None:
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
717 switch_camera_col_elt = document["switch_camera_column"]
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
718 if has_multiple_cameras:
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
719 switch_camera_col_elt.classList.remove("is-hidden", "is-hidden-desktop")
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
720 else:
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
721 switch_camera_col_elt.classList.add("is-hidden")
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
722
1565
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
723 def on_reset_cb(self) -> None:
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
724 """Call when webRTC connection is reset, we reset buttons statuses"""
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
725 document["full_screen_btn"].classList.remove("is-hidden")
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
726 document["exit_full_screen_btn"].classList.add("is-hidden")
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
727 document["group_full_screen_btn"].classList.remove("is-hidden")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
728 document["group_exit_full_screen_btn"].classList.add("is-hidden")
1565
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
729 for btn_elt in document["mute_audio_btn"], document["mute_video_btn"]:
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
730 btn_elt.classList.remove(INACTIVE_CLASS, MUTED_CLASS, "is-warning")
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
731 btn_elt.classList.add("is-success")
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
732
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
733 async def make_call(
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
734 self,
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
735 audio: bool = True,
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
736 video: bool = True,
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
737 remote: bool = False
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
738 ) -> None:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
739 """Start a WebRTC call
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
740
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
741 @param audio: True if an audio flux is required
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
742 @param video: True if a video flux is required
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
743 @param remote: True if this is a Remote Control session.
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
744 """
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
745 if remote:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
746 self.call_mode = REMOTE
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
747 elif video:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
748 self.call_mode = VIDEO
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
749 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
750 self.call_mode = AUDIO
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
751 try:
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
752 callee_jid = JID(self.search_elt.value.strip())
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
753 if not callee_jid.is_valid:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
754 raise ValueError
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
755 except ValueError:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
756 dialog.notification.show(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
757 "Invalid identifier, please use a valid callee identifier", level="error"
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
758 )
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
759 return
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
760
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
761 self._callee = callee_jid
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
762 await cache.fill_identities([callee_jid])
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
763
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
764 self.is_conference = False
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
765 try:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
766 disco_identities = cache.identities[callee_jid]["identities"]
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
767 except KeyError:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
768 pass
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
769 else:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
770 for disco_identity in disco_identities:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
771 if (
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
772 disco_identity.get("category") == "conference"
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
773 and disco_identity.get("type") == "audio-video"
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
774 ):
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
775 self.is_conference = True
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
776 log.info(f"{callee_jid} is an A/V Conference room.")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
777
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
778
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
779 self.status = "dialing"
1562
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
780 self.set_avatar(callee_jid)
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
781
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
782 self.switch_mode("group_call" if self.is_conference else "call" )
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
783 if remote:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
784 await self.webrtc.start_remote_control(
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
785 callee_jid, audio, video
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
786 )
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
787 else:
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
788 if self.is_conference:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
789 direction = "sendonly"
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
790 group_video_grid_elt = document["group_video_grid"]
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
791 await cache.fill_identities([str(own_jid.bare)])
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
792 group_peer_elt = self.group_peer_tpl.get_elt({
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
793 "entity": str(own_jid.bare),
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
794 "identities": cache.identities,
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
795 })
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
796 for pin_item in group_peer_elt.select('.action_pin'):
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
797 pin_item.bind('click', self.toggle_pin)
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
798 group_video_grid_elt <= group_peer_elt
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
799 peer_video_stream_elt = group_peer_elt.select_one(".peer_video_stream")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
800 assert peer_video_stream_elt is not None
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
801 self.webrtc.local_video_elt = peer_video_stream_elt
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
802 else:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
803 direction = "sendrecv"
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
804 self.webrtc.local_video_elt = document["local_video"]
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
805
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
806 await self.webrtc.make_call(
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
807 callee_jid,
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
808 audio,
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
809 video,
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
810 direction
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
811 )
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
812
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
813 async def make_group_call(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
814 self,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
815 ) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
816 """Start a group call.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
817
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
818 This will run a call for small group, using MUJI (XEP-0272).
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
819 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
820 group_video_grid_elt = document["group_video_grid"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
821 group_video_grid_elt.clear()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
822 self._group_call_peers.clear()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
823 selected_jids = self.jid_search.selected_jids
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
824
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
825 await cache.fill_identities(selected_jids)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
826
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
827 self.switch_mode("group_call")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
828 group_call_data = json.loads(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
829 await bridge.call_group_start(self.jid_search.selected_jids, "")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
830 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
831 self._group_call_room = JID(group_call_data["room_jid"])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
832
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
833 async def end_call(self, data: dict) -> None:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
834 """Stop streaming and clean instance"""
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
835 # if there is any ringing, we stop it
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
836 self.audio_player_elt.pause()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
837 self.audio_player_elt.currentTime = 0
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
838 reason = data.get("reason", "")
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
839 text = data.get("text", "")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
840
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
841 if self.incoming_call_dialog_elt is not None:
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
842 self.incoming_call_dialog_elt.cancel(reason, text)
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
843 self.incoming_call_dialog_elt = None
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
844
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
845 self.switch_mode("search")
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
846
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
847 await self.webrtc.end_call()
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
848
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
849 async def hang_up(self) -> None:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
850 """Terminate the call"""
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
851 session_id = self.sid
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
852 if not session_id:
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
853 log.warning("Can't hand_up, no call in progress")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
854 return
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
855 await self.end_call({"reason": "terminated"})
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
856 await bridge.call_end(session_id, "")
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
857
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
858 async def group_hang_up(self) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
859 """Terminate the group_call"""
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
860 self.switch_mode("search")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
861 group_video_grid_elt = document["group_video_grid"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
862 group_video_grid_elt.clear()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
863 for peer_data in self._group_call_peers.values():
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
864 webrtc = peer_data["webrtc"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
865 await webrtc.end_call()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
866 self._group_call_peers.clear()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
867 self._group_call_room = None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
868
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
869 def _handle_animation_end(
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
870 self,
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
871 element,
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
872 remove=None,
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
873 add=None,
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
874 ):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
875 """Return a handler that removes specified classes and the event handler.
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
876
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
877 @param element: The element to operate on.
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
878 @param remove: List of class names to remove from the element.
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
879 @param add: List of class names to add to the element.
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
880 """
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
881
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
882 def handler(__, remove=remove, add=add):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
883 log.info(f"animation end OK {element=}")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
884 if add:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
885 if isinstance(add, str):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
886 add = [add]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
887 element.classList.add(*add)
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
888 if remove:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
889 if isinstance(remove, str):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
890 remove = [remove]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
891 element.classList.remove(*remove)
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
892 element.unbind("animationend", handler)
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
893
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
894 return handler
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
895
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
896 def switch_mode(self, mode: str) -> None:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
897 """Handles the user interface changes"""
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
898 if mode == self.mode:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
899 return
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
900
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
901 # Exiting from any other modes
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
902 exit_animate_list = [
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
903 (self.search_container_elt, "fade-out-y", "is-hidden"),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
904 (self.call_container_elt, "slide-in", "is-hidden"),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
905 (self.group_call_container_elt, "slide-in", "is-hidden"),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
906 ]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
907
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
908 for elt, anim, hide in exit_animate_list:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
909 if not elt.classList.contains(hide): # Only animate if visible
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
910 elt.classList.add(anim)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
911 elt.bind("animationend", self._handle_animation_end(elt, remove=anim, add=hide))
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
912
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
913 # Entering into the new mode
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
914 if mode == "call":
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
915 self.call_container_elt.classList.remove("is-hidden")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
916 self.call_container_elt.classList.add("slide-in")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
917 self.call_container_elt.bind(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
918 "animationend",
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
919 self._handle_animation_end(self.call_container_elt, remove="slide-in"),
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
920 )
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
921
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
922 elif mode == "group_call":
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
923 self.group_call_container_elt.classList.remove("is-hidden")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
924 self.group_call_container_elt.classList.add("slide-in")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
925 self.group_call_container_elt.bind(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
926 "animationend",
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
927 self._handle_animation_end(self.group_call_container_elt, remove="slide-in"),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
928 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
929
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
930 elif mode == "search":
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
931 self.toggle_fullscreen(False)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
932 self.search_container_elt.classList.remove("is-hidden")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
933 self.search_container_elt.classList.add("fade-out-y", "animation-reverse")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
934 self.search_container_elt.bind(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
935 "animationend",
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
936 self._handle_animation_end(
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
937 self.search_container_elt,
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
938 remove=["fade-out-y", "animation-reverse"],
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
939 ),
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
940 )
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
941
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
942 else:
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
943 log.error(f"Internal Error: Unknown mode: {mode}")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
944 return
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
945
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
946 self.mode = mode
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
947
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
948 def on_clear_search(self, ev) -> None:
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
949 """Clear the search input and trigger its 'input' event.
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
950
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
951 @param ev: the event object from the button click.
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
952 """
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
953 if not self.search_elt.value:
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
954 return
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
955 # clear the search field
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
956 self.search_elt.value = ""
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
957 # and dispatch the input event so items are updated
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
958 self.search_elt.dispatchEvent(window.Event.new("input"))
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
959
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
960 def _on_search_selection(self, has_selection: bool) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
961 """Hide show buttons from search bar according to selection.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
962
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
963 If at least one search item is selected, the "group call" button will be shown,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
964 otherwise the "video call" and "audio call" button will be shown
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
965 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
966 if has_selection:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
967 to_hide = ["video_call_btn", "audio_call_btn"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
968 to_show = ["group_call_btn"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
969 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
970 to_hide = ["group_call_btn"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
971 to_show = ["video_call_btn", "audio_call_btn"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
972 for elt_id in to_hide:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
973 document[elt_id].parent.classList.add("is-hidden")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
974 for elt_id in to_show:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
975 document[elt_id].parent.classList.remove("is-hidden")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
976
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
977 def toggle_fullscreen(self, fullscreen: bool | None = None, group=False):
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
978 """Toggle fullscreen mode for video elements.
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
979
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
980 @param fullscreen: if set, determine the fullscreen state; otherwise,
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
981 the fullscreen mode will be toggled.
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
982 """
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
983 if fullscreen is None:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
984 fullscreen = document.fullscreenElement is NULL
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
985 log.debug(f"toggle_fullscreen {fullscreen=} {group=}")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
986
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
987 full_screen_cls = "full_screen_btn"
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
988 exit_full_screen_cls = "exit_full_screen_btn"
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
989 if group:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
990 full_screen_cls = f"group_{full_screen_cls}"
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
991 exit_full_screen_cls = f"group_{exit_full_screen_cls}"
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
992 parent_elt = self.group_call_container_elt
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
993 else:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
994 parent_elt = self.call_box_elt
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
995
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
996 try:
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
997 if fullscreen:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
998 if document.fullscreenElement is NULL:
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
999 parent_elt.requestFullscreen()
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1000 document[full_screen_cls].classList.add("is-hidden")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1001 document[exit_full_screen_cls].classList.remove("is-hidden")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1002 else:
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
1003 if document.fullscreenElement is not NULL:
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1004 document.exitFullscreen()
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1005 document[full_screen_cls].classList.remove("is-hidden")
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1006 document[exit_full_screen_cls].classList.add("is-hidden")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1007
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1008 except Exception as e:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1009 dialog.notification.show(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1010 f"An error occurred while toggling fullscreen: {e}", level="error"
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1011 )
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1012
1616
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1013 def toggle_pin(self, event):
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1014 peer_container = event.target.closest('.peer_video_container')
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1015 is_pinned = peer_container.dataset.pinned == 'true'
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1016
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1017 # Unpin all peers
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1018 for container in self.group_call_container_elt.select('.peer_video_container'):
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1019 container.dataset.pinned = 'false'
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1020 container.classList.remove('is-12')
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1021 container.classList.add('is-3-widescreen', 'is-4-desktop', 'is-6-tablet')
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1022
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1023 if not is_pinned:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1024 # Pin the selected peer
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1025 peer_container.dataset.pinned = 'true'
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1026 peer_container.classList.remove('is-3-widescreen', 'is-4-desktop', 'is-6-tablet')
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1027 peer_container.classList.add('is-12')
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1028
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1029 # Rearrange the grid
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1030 grid = document['group_video_grid']
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1031 pinned = [peer for peer in grid.children if peer.dataset.pinned == 'true']
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1032 unpinned = [peer for peer in grid.children if peer.dataset.pinned != 'true']
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1033
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1034 grid.clear()
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1035 for peer in pinned + unpinned:
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1036 grid <= peer
6bfeb9f0fb84 browser (calls): conferences implementation:
Goffi <goffi@goffi.org>
parents: 1604
diff changeset
1037
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1038 def toggle_audio_mute(self, evt):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1039 is_muted = self.webrtc.toggle_audio_mute()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1040 btn_elt = evt.currentTarget
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1041 if is_muted:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1042 btn_elt.classList.remove("is-success")
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1043 btn_elt.classList.add(INACTIVE_CLASS, MUTED_CLASS, "is-warning")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1044 dialog.notification.show(
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1045 f"audio is now muted",
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1046 level="info",
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1047 delay=2,
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1048 )
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1049 else:
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1050 btn_elt.classList.remove(INACTIVE_CLASS, MUTED_CLASS, "is-warning")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1051 btn_elt.classList.add("is-success")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1052
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1053 def toggle_video_mute(self, evt):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1054 is_muted = self.webrtc.toggle_video_mute()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1055 btn_elt = evt.currentTarget
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1056 if is_muted:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1057 btn_elt.classList.remove("is-success")
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1058 btn_elt.classList.add(INACTIVE_CLASS, MUTED_CLASS, "is-warning")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1059 dialog.notification.show(
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1060 f"video is now muted",
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1061 level="info",
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1062 delay=2,
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1063 )
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1064 else:
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1065 btn_elt.classList.remove(INACTIVE_CLASS, MUTED_CLASS, "is-warning")
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1066 btn_elt.classList.add("is-success")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1067
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1068 def toggle_screen_sharing(self, evt):
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1069 aio.run(self.webrtc.toggle_screen_sharing())
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1070
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1071 def on_sharing_screen(self, sharing: bool) -> None:
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1072 """Called when screen sharing state changes"""
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
1073 share_desktop_btn_elt = document["share_desktop_btn"]
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1074 if sharing:
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1075 share_desktop_btn_elt.classList.add("is-danger")
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1076 share_desktop_btn_elt.classList.remove(INACTIVE_CLASS, SCREEN_OFF_CLASS)
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1077 else:
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1078 share_desktop_btn_elt.classList.remove("is-danger")
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1079 share_desktop_btn_elt.classList.add(INACTIVE_CLASS, SCREEN_OFF_CLASS)
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
1080
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
1081 def on_switch_camera(self, __) -> None:
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
1082 aio.run(self.webrtc.switch_camera())
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
1083
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1084 def on_send_file(self, __) -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1085 document["send_file_input"].click()
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1086
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1087 def _on_send_input_change(self, evt) -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1088 aio.run(self.on_send_input_change(evt))
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1089
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1090 async def on_send_input_change(self, evt) -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1091 assert self._callee is not None
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1092 files = evt.currentTarget.files
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1093 for file in files:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1094 webrtc = WebRTC(file_only=True)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1095 self.files_webrtc.append({
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1096 "file": file,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1097 "webrtc": webrtc
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1098 })
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1099 await webrtc.send_file(self._callee, file)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
1100
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1101 def _on_entity_click(self, evt: JSObject, item: dict) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1102 aio.run(self.on_entity_click(evt, item))
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1103
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1104 async def on_entity_click(self, evt: JSObject, item: dict) -> None:
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1105 """Set entity JID to search bar, and start the call"""
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1106 # we don't want to start a call when there is a selection, has a group call is
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1107 # expected, and a click may just be accidental.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1108 if self.jid_search.has_selection:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1109 checkbox_elt = evt.currentTarget.select_one("input[type='checkbox']")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1110 if checkbox_elt is not None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1111 checkbox_elt.checked = not checkbox_elt.checked
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1112 checkbox_elt.dispatchEvent(window.Event.new("change"))
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1113 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1114 self.search_elt.value = item["entity"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
1115 await self.make_call()
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1116
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1117 async def on_entity_action(self, evt, action: str, item: dict) -> None:
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1118 """Handle extra actions on search items"""
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1119 evt.stopPropagation()
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1120 if action == "menu":
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1121 evt.currentTarget.parent.classList.toggle("is-active")
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
1122 elif action in (VIDEO, AUDIO, REMOTE):
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
1123 self.search_elt.value = item["entity"]
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1124 # we want the dropdown to be inactive
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1125 evt.currentTarget.closest(".dropdown").classList.remove("is-active")
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
1126 if action == REMOTE:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
1127 await self.make_call(audio=False, video=True, remote=True)
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
1128
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
1129 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
1130 await self.make_call(video=action == VIDEO)
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1131
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1132
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1133 CallUI()
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1134 loading.remove_loading_screen()