annotate libervia/web/pages/calls/_browser/__init__.py @ 1607:64bfb6554131

doc (installation): add missing pipx link
author Goffi <goffi@goffi.org>
date Thu, 30 May 2024 23:56:05 +0200
parents 4a9679369856
children 6bfeb9f0fb84
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 ""
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 bridge = Bridge()
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 GATHER_TIMEOUT = 10000
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
18 ALLOWED_STATUSES = (
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
19 None,
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
20 "dialing",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
21 "ringing",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
22 "in-call",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
23 "on-hold",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
24 "connecting",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
25 "connection-lost",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
26 "reconnecting",
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
27 )
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
28 AUDIO = "audio"
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
29 VIDEO = "video"
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
30 REMOTE = "remote-control"
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
31 ALLOWED_CALL_MODES = {AUDIO, VIDEO, REMOTE}
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
32 INACTIVE_CLASS = "inactive"
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
33 MUTED_CLASS = "muted"
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
34 SCREEN_OFF_CLASS = "screen-off"
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
35 MUJI_PREFIX = "_muji_"
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
38 class CallUI:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 def __init__(self):
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
40 self.webrtc = WebRTC(
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
41 screen_sharing_cb=self.on_sharing_screen,
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
42 on_connection_established_cb=self.on_connection_established,
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
43 on_reconnect_cb=self.on_reconnect,
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
44 on_connection_lost_cb=self.on_connection_lost,
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
45 on_video_devices=self.on_video_devices,
1565
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
46 on_reset_cb=self.on_reset_cb,
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
47 local_video_elt=document["local_video"],
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
48 remote_video_elt=document["remote_video"]
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
49 )
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
50 # mapping of file sending
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
51 self.files_webrtc: list[dict] = []
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
52 # WebRTC instances used for group calls.
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 = {}
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
58 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
59 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
60 self.call_container_elt = document["call_container"]
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
61 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
62 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
63 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
64 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
65 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
66 self.call_status_tpl = Template("call/call_status.html")
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
67 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
68 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
69 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
70 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
71 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
72 bridge.register_signal("call_ended", self._on_call_ended)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
73 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
74
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
75 # 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
76 self._call_mode = VIDEO
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
77 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
78 document["audio_call_btn"].bind(
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
79 "click", lambda __: aio.run(self.make_call(video=False))
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
80 )
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
81 document["group_call_btn"].bind(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
82 "click",
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
83 lambda __: aio.run(self.make_group_call())
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
84 )
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
85 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
86 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
87
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
88 # other buttons
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
89 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
90 document["exit_full_screen_btn"].bind(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
91 "click", lambda __: self.toggle_fullscreen()
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 )
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
93 document["mute_audio_btn"].bind("click", self.toggle_audio_mute)
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
94 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
95 self.share_desktop_col_elt = document["share_desktop_column"]
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
96 if hasattr(window.navigator.mediaDevices, "getDisplayMedia"):
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
97 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
98 # screen sharing is supported
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
99 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
100 else:
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
101 self.share_desktop_col_elt.classList.add("is-hidden")
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
102 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
103 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
104 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
105
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
106 # search
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
107 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
108 self.jid_search = JidSearch(
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
109 self.search_elt,
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
110 document["contacts"],
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
111 click_cb=self._on_entity_click,
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
112 allow_multiple_selection=True,
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
113 template="call/search_item.html",
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
114 selection_state_callback=self._on_search_selection,
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
115 options={
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
116 "no_group": True,
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
117 "extra_cb": {
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
118 ".dropdown-trigger": lambda evt, item: aio.run(
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
119 self.on_entity_action(evt, "menu", item)
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
120 ),
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
121 ".click-to-video": lambda evt, item: aio.run(
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
122 self.on_entity_action(evt, VIDEO, item)
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
123 ),
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
124 ".click-to-audio": lambda evt, item: aio.run(
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
125 self.on_entity_action(evt, AUDIO, item)
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
126 ),
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
127 ".click-to-remote-control": lambda evt, item: aio.run(
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
128 self.on_entity_action(evt, REMOTE, item)
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
129 ),
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
130 },
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
131 },
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 )
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
133 document["clear_search_btn"].bind("click", self.on_clear_search)
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
134
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
135 # 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
136 self.incoming_call_dialog_elt = None
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
137
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
138 @property
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
139 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
140 return self.webrtc.sid
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
141
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
142 @sid.setter
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
143 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
144 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
145
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
146 @property
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
147 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
148 return self._status
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
149
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
150 @status.setter
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
151 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
152 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
153 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
154 raise Exception(
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
155 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
156 )
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
157 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
158 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
159 try:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
160 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
161 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
162 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
163 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
164 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
165 self.call_status_wrapper_elt <= status_elt
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
166
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
167 self._status = new_status
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
168
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
169 @property
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
170 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
171 return self._call_mode
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
172
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
173 @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
174 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
175 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
176 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
177 return
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
178 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
179 self._call_mode = mode
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
180 selector = ".is-video-only, .is-not-remote"
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
181 for elt in self.call_box_elt.select(selector):
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
182 if mode == VIDEO:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
183 # 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
184 elt.classList.remove("is-hidden")
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
185 elif mode == AUDIO:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
186 # In audio, we hide video-only elements.
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
187 if elt.classList.contains("is-video-only"):
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
188 elt.classList.add("is-hidden")
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
189 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
190 elt.classList.remove("is-hidden")
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
191 elif mode == REMOTE:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
192 # In remote, we show all video element, except if they are
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
193 # `is-not-remote`
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
194 if elt.classList.contains("is-not-remote"):
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
195 elt.classList.add("is-hidden")
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
196 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
197 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
198 else:
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
199 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
200 else:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
201 raise ValueError("Invalid call mode")
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
202
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
203 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
204 """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
205
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
206 @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
207 """
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
208 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
209 {
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
210 "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
211 "identities": cache.identities,
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
212 }
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
213 )
4afafce0c4c9 browser (calls): correctly display avatar and entity in status on incoming call
Goffi <goffi@goffi.org>
parents: 1561
diff changeset
214 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
215 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
216
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
217 def _on_action_new(
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 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
219 ) -> None:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 """Called when a call is received
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
221
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 @param action_data_s: Action data serialized
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 @param action_id: Unique identifier for the action
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 @param security_limit: Security limit for the action
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 @param profile: Profile associated with the action
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 """
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 action_data = json.loads(action_data_s)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
228 type_ = action_data.get("type")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
229 subtype = action_data.get("subtype")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
230 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
231 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
232 elif type_ == "file":
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
233 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
234 elif (
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
235 type_ == "confirm"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
236 and subtype == "muc-invitation"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
237 # 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
238 and MUJI_PREFIX in action_data.get("room_jid", "")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
239 ):
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
240 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
241 elif type_ != "call":
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 return
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
243 elif MUJI_PREFIX in action_data.get("from_jid", ""):
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
244 aio.run(self.on_group_call_join(action_data, action_id))
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
245 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
246 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
247
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
248 def get_human_size(self, size: int|float) -> str:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
249 """Return size in human-friendly size using SI units"""
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
250 units = ["o","Kio","Mio","Gio"]
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
251 for idx, unit in enumerate(units):
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
252 if size < 1024.0 or idx == len(units)-1:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
253 return f"{size:.2f}{unit}"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
254 size /= 1024.0
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
255 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
256
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
257 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
258 """Request permission to download a file."""
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
259 peer_jid = JID(action_data["from_jid"]).bare
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
260 await cache.fill_identities([peer_jid])
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
261 try:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
262 identity = cache.identities[peer_jid]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
263 except KeyError:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
264 peer_name = peer_jid.local
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
265 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
266 peer_name = identity["nicknames"][0]
1600
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 file_data = action_data.get("file_data", {})
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
269
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
270 file_name = file_data.get('name')
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
271 file_size = file_data.get('size')
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
272
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
273 if file_name:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
274 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
275 file_name=file_name
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
276 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
277 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
278 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
279
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
280 if file_size is not None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
281 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
282 file_size_human=self.get_human_size(file_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 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
285 file_size_msg = "which has an unknown size"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
286
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
287 file_description = file_data.get('desc')
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
288 if file_description:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
289 description_msg = " Description: {}.".format(file_description)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
290 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
291 description_msg = ""
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
292
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
293 file_data = action_data.get("file_data", {})
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 file_accept_dlg = dialog.Confirm(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
296 "{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
297 "accept?".format(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
298 peer_name=peer_name,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
299 peer_jid=peer_jid,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
300 file_name_msg=file_name_msg,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
301 file_size_msg=file_size_msg,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
302 description_msg=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 ok_label="Download",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
305 cancel_label="Reject"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
306 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
307 return await file_accept_dlg.ashow()
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
308
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
309 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
310 """Handle a file preflight (proposal made to all devices)."""
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
311 # 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
312 # make it work anywhere.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
313 accepted = await self.request_file_permission(action_data)
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 await bridge.action_launch(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
316 action_id, json.dumps({"answer": str(accepted).lower()})
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
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
319 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
320 """Handle a file proposal.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
321
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
322 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
323 ``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
324 """
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
325 # 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
326 if not action_data.get("webrtc", False):
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
327 peer_jid = JID(action_data["from_jid"]).bare
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
328 # 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
329 dialog.notification.show(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
330 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
331 "compatible with web browser direct transfer (WebRTC).",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
332 level="warning",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
333 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
334 # 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
335 # supported by other frontends.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
336 # 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
337 # the file if none is.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
338 return
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
339 if action_data.get("pre_accepted", False):
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
340 # File proposal has already been accepted in preflight.
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
341 accepted = True
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
342 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
343 accepted = await self.request_file_permission(action_data)
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 if accepted:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
346 sid = action_data["session_id"]
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
347 webrtc = WebRTC(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
348 file_only=True,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
349 extra_data={"file_data": action_data.get("file_data", {})}
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
350 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
351 webrtc.sid = sid
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
352 self.files_webrtc.append({
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
353 "webrtc": webrtc,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
354 })
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 await bridge.action_launch(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
357 action_id, json.dumps({"answer": str(accepted).lower()})
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
358 )
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
359
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
360 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
361 """Handle a group call proposal."""
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
362 peer_jid = JID(action_data["from_jid"]).bare
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
363 await cache.fill_identities([peer_jid])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
364 identity = cache.identities[peer_jid]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
365 peer_name = identity["nicknames"][0]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
366
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
367 group_call_accept_dlg = dialog.Confirm(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
368 "{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
369 .format(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
370 peer_name=peer_name,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
371 peer_jid=peer_jid,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
372 ),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
373 ok_label="Accept Group Call",
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
374 cancel_label="Reject"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
375 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
376 accepted = await group_call_accept_dlg.ashow()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
377 if accepted:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
378 self.switch_mode("group_call")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
379 await bridge.action_launch(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
380 action_id, json.dumps({"answer": str(accepted).lower()})
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
381 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
382
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
383 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
384 peer_jid = JID(action_data["from_jid"])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
385 if peer_jid.bare != self._group_call_room:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
386 log.warning(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
387 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
388 f"{peer_jid.bare=} {self._group_call_room=}"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
389 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
390 log.info(f"{peer_jid} joined the group call.")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
391
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
392 group_video_grid_elt = document["group_video_grid"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
393 await cache.fill_identities([peer_jid])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
394
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
395 group_peer_elt = self.group_peer_tpl.get_elt({
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
396 "entity": str(peer_jid),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
397 # "identities": cache.identities,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
398 })
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
399 group_video_grid_elt <= group_peer_elt
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
400 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
401 assert peer_video_stream_elt is not None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
402 webrtc = WebRTC(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
403 remote_video_elt=peer_video_stream_elt
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
404 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
405 sid = webrtc.sid = action_data["session_id"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
406 self._group_call_peers[peer_jid] = {
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
407 "webrtc": webrtc,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
408 "element": group_peer_elt,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
409 "sid": sid
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
410 }
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
411
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
412 log.debug(f"Call SID: {sid}")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
413
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
414 await bridge.action_launch(action_id, json.dumps({"cancelled": False}))
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
415
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
416 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
417 peer_jid = JID(action_data["from_jid"]).bare
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
418 call_type = action_data["sub_type"]
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
419 call_emoji = "📹" if call_type == VIDEO else "📞"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
420 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
421 if self.sid is not None:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
422 log.warning(
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
423 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
424 f"{peer_jid}"
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
425 )
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
426 return
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
427 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
428 await cache.fill_identities([peer_jid])
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
429 try:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
430 identity = cache.identities[peer_jid]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
431 except KeyError:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
432 peer_name = peer_jid.local
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
433 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
434 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
435 self._callee = peer_jid
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
436
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
437 # 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
438 self.audio_player_elt.play()
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
439
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
440 # 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
441 try:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
442 self.incoming_call_dialog_elt = dialog.Confirm(
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
443 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
444 )
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
445 accepted = await self.incoming_call_dialog_elt.ashow()
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
446 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
447 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
448 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
449 self.sid = None
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
450 match e.reason:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
451 case "busy":
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
452 dialog.notification.show(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
453 f"{peer_name} can't answer your call",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
454 level="info",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
455 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
456 case "taken_by_other_device":
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
457 device = e.text
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
458 dialog.notification.show(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
459 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
460 level="info",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
461 )
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
462 case _:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
463 dialog.notification.show(
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
464 f"{peer_name} has cancelled the call",
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
465 level="info"
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
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 return
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
468
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
469 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
470
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
471 # 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
472 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
473 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
474
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
475 if accepted:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
476 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
477
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
478 # Answer the call
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
479 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
480 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
481 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
482 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
483 else:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
484 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
485 self.sid = None
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
486 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
487
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
488 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
489 """Call has been terminated
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
490
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
491 @param session_id: Session identifier
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
492 @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
493 @param profile: Profile associated
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
494 """
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
495 if self.sid is None:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
496 log.debug("there are no calls in progress")
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
497 return
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
498 if session_id != self.sid:
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
499 log.debug(
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
500 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
501 )
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
502 return
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
503 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
504
1560
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
505 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
506 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
507 return
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
508 if info_type == "ringing":
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
509 self.status = "ringing"
84f312be53b4 browser (calls): handle "ringing" info message and update status when received
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
510
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
511 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
512 """Called when we have received answer SDP from responder
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
513
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
514 @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
515 @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
516 @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
517 """
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
518 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
519
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
520 async def on_call_setup(
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
521 self, session_id: str, setup_data: dict, profile: str
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
522 ) -> None:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
523 """Call has been accepted, connection can be established
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
524
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
525 @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
526 @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
527 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
528 sdp: Session Description Protocol data
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
529 @param profile: Profile associated
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
530 """
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
531 if self.sid == session_id:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
532 webrtc = self.webrtc
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
533 else:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
534 for file_webrtc in self.files_webrtc:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
535 webrtc = file_webrtc["webrtc"]
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
536 if webrtc.sid == session_id:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
537 break
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
538 else:
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
539 for peer_data in self._group_call_peers.values():
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
540 webrtc = peer_data["webrtc"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
541 if webrtc.sid == session_id:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
542 break
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
543 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
544 log.debug(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
545 f"Call ignored due to different session ID ({self.sid=} "
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
546 f"{session_id=})"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
547 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
548 return
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
549 try:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
550 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
551 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
552 except KeyError:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
553 dialog.notification.show(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
554 f"Invalid setup data received: {setup_data}", level="error"
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
555 )
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
556 return
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
557 if role == "initiator":
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
558 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
559 elif role == "responder":
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
560 await webrtc.answer_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
561 else:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
562 dialog.notification.show(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
563 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
564 )
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
565 return
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
566
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
567 def _on_call_group_setup(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
568 self,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
569 room_jid_s: str,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
570 setup_data_s: str,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
571 profile: str
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
572 ) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
573 """Called when we are finishing preparation of a group call.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
574
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
575 @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
576 @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
577 restrictions.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
578 @param profile: Profile associated with the action
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
579 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
580 if setup_data_s:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
581 setup_data = json.loads(setup_data_s)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
582 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
583 setup_data = {}
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
584 aio.run(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
585 self.on_call_group_setup(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
586 JID(room_jid_s),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
587 setup_data,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
588 profile
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
589 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
590 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
591
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
592 async def on_call_group_setup(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
593 self, room_jid: JID, setup_data: dict, profile: str
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
594 ) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
595 """Call has been accepted, connection can be established
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
596
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
597 @param session_id: Session identifier
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
598 @param setup_data: Data with following keys:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
599 role: initiator or responser
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
600 sdp: Session Description Protocol data
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
601 @param profile: Profile associated
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
602 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
603 log.info(f"Setting up group call at {room_jid}.")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
604 try:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
605 to_call = setup_data["to_call"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
606 except KeyError:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
607 dialog.notification.show(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
608 'Internal error: missing "to_call" data.', level="error"
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
609 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
610 return
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
611
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
612 # 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
613 webrtc = WebRTC(remote_video_elt=document["remote_video"])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
614 call_data = await webrtc.prepare_call()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
615
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
616 # 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
617 await webrtc.end_call()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
618 del webrtc
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
619 await bridge.call_group_data_set(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
620 str(room_jid),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
621 json.dumps(call_data),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
622 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
623 # At this point, we can initiate the call.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
624 # 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
625 # our own preparation.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
626 group_video_grid_elt = document["group_video_grid"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
627 local_stream = None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
628 for entity_jid_s in to_call:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
629 entity_jid = JID(entity_jid_s)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
630 log.info(f"Calling {entity_jid_s}.")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
631 await cache.fill_identities([entity_jid])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
632 group_peer_elt = self.group_peer_tpl.get_elt({
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
633 "entity": str(entity_jid),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
634 # "identities": cache.identities,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
635 })
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
636 group_video_grid_elt <= group_peer_elt
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
637 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
638 assert peer_video_stream_elt is not None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
639 webrtc = WebRTC(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
640 remote_video_elt=peer_video_stream_elt,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
641 local_stream=local_stream
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 self._group_call_peers[JID(entity_jid)] = {
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
645 "webrtc": webrtc
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
646 }
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
647 await webrtc.make_call(entity_jid)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
648 # 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
649 if local_stream is None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
650 local_stream = webrtc.local_stream
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
651
1561
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
652 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
653 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
654
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
655 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
656 self.status = "reconnecting"
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
657
7dbb131bbb9e browser (calls): update status on various events (connection established, connection lost, etc.)
Goffi <goffi@goffi.org>
parents: 1560
diff changeset
658 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
659 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
660
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
661 def on_video_devices(self, has_multiple_cameras: bool) -> None:
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
662 switch_camera_col_elt = document["switch_camera_column"]
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
663 if has_multiple_cameras:
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
664 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
665 else:
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
666 switch_camera_col_elt.classList.add("is-hidden")
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
667
1565
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
668 def on_reset_cb(self) -> None:
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
669 """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
670 document["full_screen_btn"].classList.remove("is-hidden")
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
671 document["exit_full_screen_btn"].classList.add("is-hidden")
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
672 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
673 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
674 btn_elt.classList.add("is-success")
d282dbdd5ffd browser (calls): restore UI state on reset:
Goffi <goffi@goffi.org>
parents: 1564
diff changeset
675
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
676 async def make_call(
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
677 self,
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
678 audio: bool = True,
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
679 video: bool = True,
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
680 remote: bool = False
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
681 ) -> None:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
682 """Start a WebRTC call
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
683
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
684 @param audio: True if an audio flux is required
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
685 @param video: True if a video flux is required
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
686 @param remote: True if this is a Remote Control session.
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
687 """
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
688 if remote:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
689 self.call_mode = REMOTE
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
690 elif video:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
691 self.call_mode = VIDEO
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
692 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
693 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
694 try:
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
695 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
696 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
697 raise ValueError
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
698 except ValueError:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
699 dialog.notification.show(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
700 "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
701 )
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
702 return
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
703
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
704 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
705 await cache.fill_identities([callee_jid])
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
706 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
707 self.set_avatar(callee_jid)
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
708
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
709 self.switch_mode("call")
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
710 if remote:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
711 await self.webrtc.start_remote_control(
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
712 callee_jid, audio, video
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
713 )
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
714 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
715 await self.webrtc.make_call(callee_jid, audio, video)
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
716
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
717 async def make_group_call(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
718 self,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
719 ) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
720 """Start a group call.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
721
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
722 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
723 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
724 group_video_grid_elt = document["group_video_grid"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
725 group_video_grid_elt.clear()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
726 self._group_call_peers.clear()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
727 selected_jids = self.jid_search.selected_jids
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
728
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
729 await cache.fill_identities(selected_jids)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
730
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
731 self.switch_mode("group_call")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
732 group_call_data = json.loads(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
733 await bridge.call_group_start(self.jid_search.selected_jids, "")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
734 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
735 self._group_call_room = JID(group_call_data["room_jid"])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
736
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
737 async def end_call(self, data: dict) -> None:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
738 """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
739 # 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
740 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
741 self.audio_player_elt.currentTime = 0
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
742 reason = data.get("reason", "")
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
743 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
744
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
745 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
746 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
747 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
748
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
749 self.switch_mode("search")
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
750
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
751 await self.webrtc.end_call()
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
752
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
753 async def hang_up(self) -> None:
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
754 """Terminate the call"""
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
755 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
756 if not session_id:
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
757 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
758 return
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
759 await self.end_call({"reason": "terminated"})
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
760 await bridge.call_end(session_id, "")
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
761
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
762 async def group_hang_up(self) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
763 """Terminate the group_call"""
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
764 self.switch_mode("search")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
765 group_video_grid_elt = document["group_video_grid"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
766 group_video_grid_elt.clear()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
767 for peer_data in self._group_call_peers.values():
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
768 webrtc = peer_data["webrtc"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
769 await webrtc.end_call()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
770 self._group_call_peers.clear()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
771 self._group_call_room = None
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
772
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
773 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
774 self,
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
775 element,
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
776 remove=None,
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
777 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
778 ):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
779 """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
780
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
781 @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
782 @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
783 @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
784 """
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
785
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
786 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
787 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
788 if add:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
789 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
790 add = [add]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
791 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
792 if remove:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
793 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
794 remove = [remove]
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
795 element.classList.remove(*remove)
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
796 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
797
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
798 return handler
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
799
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
800 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
801 """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
802 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
803 return
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
804
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
805 # Exiting from any other modes
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
806 exit_animate_list = [
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
807 (self.search_container_elt, "fade-out-y", "is-hidden"),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
808 (self.call_container_elt, "slide-in", "is-hidden"),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
809 (self.group_call_container_elt, "slide-in", "is-hidden"),
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
810 ]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
811
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
812 for elt, anim, hide in exit_animate_list:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
813 if not elt.classList.contains(hide): # Only animate if visible
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
814 elt.classList.add(anim)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
815 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
816
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
817 # 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
818 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
819 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
820 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
821 self.call_container_elt.bind(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
822 "animationend",
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
823 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
824 )
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
825
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
826 elif mode == "group_call":
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
827 self.group_call_container_elt.classList.remove("is-hidden")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
828 self.group_call_container_elt.classList.add("slide-in")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
829 self.group_call_container_elt.bind(
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
830 "animationend",
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
831 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
832 )
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
833
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
834 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
835 self.toggle_fullscreen(False)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
836 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
837 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
838 self.search_container_elt.bind(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
839 "animationend",
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
840 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
841 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
842 remove=["fade-out-y", "animation-reverse"],
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
843 ),
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
844 )
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
845
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
846 else:
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
847 log.error(f"Internal Error: Unknown mode: {mode}")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
848 return
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
849
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
850 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
851
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
852 def on_clear_search(self, ev) -> None:
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
853 """Clear the search input and trigger its 'input' event.
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
854
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
855 @param ev: the event object from the button click.
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
856 """
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
857 if not self.search_elt.value:
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
858 return
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
859 # clear the search field
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
860 self.search_elt.value = ""
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
861 # and dispatch the input event so items are updated
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
862 self.search_elt.dispatchEvent(window.Event.new("input"))
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
863
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
864 def _on_search_selection(self, has_selection: bool) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
865 """Hide show buttons from search bar according to selection.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
866
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
867 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
868 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
869 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
870 if has_selection:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
871 to_hide = ["video_call_btn", "audio_call_btn"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
872 to_show = ["group_call_btn"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
873 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
874 to_hide = ["group_call_btn"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
875 to_show = ["video_call_btn", "audio_call_btn"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
876 for elt_id in to_hide:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
877 document[elt_id].parent.classList.add("is-hidden")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
878 for elt_id in to_show:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
879 document[elt_id].parent.classList.remove("is-hidden")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
880
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
881 def toggle_fullscreen(self, fullscreen: bool | None = None):
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
882 """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
883
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
884 @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
885 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
886 """
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
887 if fullscreen is None:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
888 fullscreen = document.fullscreenElement is NULL
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
889
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
890 try:
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
891 if fullscreen:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
892 if document.fullscreenElement is NULL:
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
893 self.call_box_elt.requestFullscreen()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
894 document["full_screen_btn"].classList.add("is-hidden")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
895 document["exit_full_screen_btn"].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
896 else:
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
897 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
898 document.exitFullscreen()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
899 document["full_screen_btn"].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
900 document["exit_full_screen_btn"].classList.add("is-hidden")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
901
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
902 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
903 dialog.notification.show(
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
904 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
905 )
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
906
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
907 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
908 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
909 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
910 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
911 btn_elt.classList.remove("is-success")
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
912 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
913 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
914 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
915 level="info",
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
916 delay=2,
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
917 )
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
918 else:
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
919 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
920 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
921
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
922 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
923 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
924 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
925 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
926 btn_elt.classList.remove("is-success")
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
927 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
928 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
929 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
930 level="info",
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
931 delay=2,
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
932 )
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
933 else:
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
934 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
935 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
936
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
937 def toggle_screen_sharing(self, evt):
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
938 aio.run(self.webrtc.toggle_screen_sharing())
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
939
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
940 def on_sharing_screen(self, sharing: bool) -> None:
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
941 """Called when screen sharing state changes"""
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
942 share_desktop_btn_elt = document["share_desktop_btn"]
1553
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
943 if sharing:
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
944 share_desktop_btn_elt.classList.add("is-danger")
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
945 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
946 else:
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
947 share_desktop_btn_elt.classList.remove("is-danger")
83c2a6faa2ae browser (calls): screen sharing implementation:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
948 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
949
1564
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
950 def on_switch_camera(self, __) -> None:
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
951 aio.run(self.webrtc.switch_camera())
bd3c880f4a47 browser (calls): add camera switching:
Goffi <goffi@goffi.org>
parents: 1563
diff changeset
952
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
953 def on_send_file(self, __) -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
954 document["send_file_input"].click()
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
955
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
956 def _on_send_input_change(self, evt) -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
957 aio.run(self.on_send_input_change(evt))
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
958
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
959 async def on_send_input_change(self, evt) -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
960 assert self._callee is not None
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
961 files = evt.currentTarget.files
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
962 for file in files:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
963 webrtc = WebRTC(file_only=True)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
964 self.files_webrtc.append({
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
965 "file": file,
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
966 "webrtc": webrtc
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
967 })
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
968 await webrtc.send_file(self._callee, file)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1565
diff changeset
969
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
970 def _on_entity_click(self, evt: JSObject, item: dict) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
971 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
972
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
973 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
974 """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
975 # 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
976 # expected, and a click may just be accidental.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
977 if self.jid_search.has_selection:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
978 checkbox_elt = evt.currentTarget.select_one("input[type='checkbox']")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
979 if checkbox_elt is not None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
980 checkbox_elt.checked = not checkbox_elt.checked
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
981 checkbox_elt.dispatchEvent(window.Event.new("change"))
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
982 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
983 self.search_elt.value = item["entity"]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1602
diff changeset
984 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
985
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
986 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
987 """Handle extra actions on search items"""
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
988 evt.stopPropagation()
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
989 if action == "menu":
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
990 evt.currentTarget.parent.classList.toggle("is-active")
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
991 elif action in (VIDEO, AUDIO, REMOTE):
1563
e3449beac8d8 browser (calls): Add clear search + formatting
Goffi <goffi@goffi.org>
parents: 1562
diff changeset
992 self.search_elt.value = item["entity"]
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
993 # we want the dropdown to be inactive
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
994 evt.currentTarget.closest(".dropdown").classList.remove("is-active")
1602
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
995 if action == REMOTE:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
996 await self.make_call(audio=False, video=True, remote=True)
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
997
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
998 else:
6feac4a25e60 browser: Remote Control implementation:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
999 await self.make_call(video=action == VIDEO)
1557
855729ef75f2 browser (calls): improve call buttons:
Goffi <goffi@goffi.org>
parents: 1553
diff changeset
1000
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1001
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
1002 CallUI()
1517
b8ed9726525b browser: "calls" implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1003 loading.remove_loading_screen()