annotate libervia/web/pages/_browser/jid_search.py @ 1616:6bfeb9f0fb84

browser (calls): conferences implementation: - Handle A/V conferences calls creation/joining by entering a conference room JID in the search box. - Group call box has been improved and is used both for group calls (small number of participants) and A/V conferences (larger number of participants). - Fullscreen button for group call is working. - Avatar/user nickname are shown in group call on peer user, as an overlay on video stream. - Use `user` metadata when present to display the right user avatar/name when receiving a stream from SFU (i.e. A/V conference). - Peer user have a new 3 dots menu with a `pin` item to (un)pin it (i.e. display it on full container with on top). - Updated webrtc to handle unidirectional streams correctly and to adapt to A/V conference specification. rel 448
author Goffi <goffi@goffi.org>
date Wed, 07 Aug 2024 00:01:57 +0200
parents 4a9679369856
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
1 import json
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
2 from urllib.parse import quote, urljoin
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
3
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
4 from bridge import AsyncBridge as Bridge
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
5 from browser import aio, console as log, window
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
6 from cache import cache
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
7 from template import Template
1573
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
8 import jid
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
9
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
10 log.warning = log.warn
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
11 profile = window.profile or ""
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
12 bridge = Bridge()
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
13
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
14 class JidSearch:
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
15
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
16 def __init__(
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
17 self,
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
18 search_elt,
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
19 container_elt=None,
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
20 filter_cb=None,
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
21 empty_cb=None,
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
22 get_url=None,
1556
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
23 click_cb=None,
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
24 options: dict|None = None,
1573
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
25 submit_filter: bool = True,
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
26 template: str = "components/search_item.html",
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
27 allow_multiple_selection: bool = False,
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
28 selected_item_class: str = 'is-selected-search_item',
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
29 selection_state_callback=None
1556
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
30 ) -> None:
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
31 """Initialize the JidSearch instance
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
32
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
33 @param search_elt: The HTML <input> element for search
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
34 @param container_elt: The HTML container to display the search results
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
35 @param filter_cb: The callback to filter the search results
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
36 @param empty_cb: The callback when the search box is empty
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
37 @param get_url: The function to get URL for each entity in the search result
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
38 @param click_cb: The function to handle the click event on each entity in the
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
39 search result
1556
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
40 @param options: extra options. Key can be:
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
41 no_group(bool)
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
42 True if groups should not be visible
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
43 extra_cb(dict)
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
44 a map from CSS selector to callback, the callback will be binded to the
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
45 "click" event, and will be called with the ``item`` as argument
1573
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
46 @param submit_filter: if True, only submit when a seemingly valid JID is entered
1556
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
47 @param template: template to use
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
48 @param allow_multiple_selection: If True, allows multiple search entities to be
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
49 selected with checkboxes.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
50 @param selected_item_class: The CSS class to apply when an item is selected. This
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
51 class should define distinctive styles to highlight selected items.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
52 @param selection_state_callback: A callback function to execute when selection
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
53 state changes. Takes one boolean parameter indicating if items are selected.
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
54 """
1556
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
55 self.search_item_tpl = Template(template)
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
56 self.search_elt = search_elt
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
57 self.search_elt.bind("input", self.on_search_input)
1573
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
58 if submit_filter:
1591
f1d09a4d38dc browser (jid_search): fix `submit_filter` when there is no parent `<form>`
Goffi <goffi@goffi.org>
parents: 1573
diff changeset
59 try:
f1d09a4d38dc browser (jid_search): fix `submit_filter` when there is no parent `<form>`
Goffi <goffi@goffi.org>
parents: 1573
diff changeset
60 form_elt = self.search_elt.closest("form")
f1d09a4d38dc browser (jid_search): fix `submit_filter` when there is no parent `<form>`
Goffi <goffi@goffi.org>
parents: 1573
diff changeset
61 except KeyError:
f1d09a4d38dc browser (jid_search): fix `submit_filter` when there is no parent `<form>`
Goffi <goffi@goffi.org>
parents: 1573
diff changeset
62 log.debug("No parent <form> found, can't apply submit filter.")
f1d09a4d38dc browser (jid_search): fix `submit_filter` when there is no parent `<form>`
Goffi <goffi@goffi.org>
parents: 1573
diff changeset
63 else:
f1d09a4d38dc browser (jid_search): fix `submit_filter` when there is no parent `<form>`
Goffi <goffi@goffi.org>
parents: 1573
diff changeset
64 form_elt.bind("submit", self.on_form_submit)
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
65 self.last_query = None
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
66 self.current_query = None
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
67 self.container_elt = container_elt
1556
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
68 if options is None:
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
69 options = {}
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
70 self.options = options
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
71
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
72 if click_cb is not None and get_url is None:
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
73 self.get_url = lambda _: "#"
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
74 else:
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
75 self.get_url = get_url if get_url is not None else self.default_get_url
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
76 self.click_cb = click_cb
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
77
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
78 if filter_cb is None:
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
79 if container_elt is None:
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
80 raise ValueError("container_elt must be set if filter_cb is not set")
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
81 filter_cb = self.show_items
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
82 self.filter_cb = filter_cb
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
83
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
84 self.empty_cb = empty_cb or self.on_empty_search
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
85
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
86 self.allow_multiple_selection = allow_multiple_selection
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
87 self.selected_item_class = selected_item_class
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
88 if selection_state_callback is None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
89 selection_state_callback = self.default_selection_state_callback
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
90 self.selection_state_callback = selection_state_callback
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
91 self._selected_jids = set()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
92 self.has_selection = False
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
93 self.update_selection_state()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
94
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
95 current_search = search_elt.value.strip() or None
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1548
diff changeset
96 if not current_search:
1593
c6976c5b85a1 browser (chat/select): add bookmarked entities on empty search
Goffi <goffi@goffi.org>
parents: 1591
diff changeset
97 aio.run(self.empty_cb(self))
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1548
diff changeset
98 else:
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
99 aio.run(self.perform_search(current_search))
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
100
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
101 @property
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
102 def selected_jids(self) -> list[str]:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
103 return list(self._selected_jids)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
104
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
105 def default_get_url(self, item):
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
106 """Default method to get the URL for a given entity
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
107
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
108 @param item: The item (entity) for which the URL is required
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
109 """
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
110 return urljoin(f"{window.location.href}/", quote(item["entity"]))
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
111
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
112 def default_selection_state_callback(self, has_selection: bool) -> None:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
113 """Default callback to handle selection state changes.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
114
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
115 @param has_selection: Boolean indicating if any items are currently selected.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
116 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
117 if has_selection:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
118 self.container_elt.classList.add('has-selected-items')
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
119 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
120 self.container_elt.classList.remove('has-selected-items')
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
121
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
122 def update_selection_state(self):
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
123 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
124 Checks the selection state and triggers the callback accordingly.
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
125 """
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
126 current_has_selection = bool(self._selected_jids)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
127 if current_has_selection != self.has_selection:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
128 self.has_selection = current_has_selection
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
129 self.selection_state_callback(self.has_selection)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
130
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
131 def show_items(self, items):
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
132 """Display the search items in the specified container
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
133
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
134 @param items: The list of search items to be displayed
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
135 """
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
136 assert self.container_elt is not None
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
137 self.container_elt.clear()
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
138 for item in items:
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
139 search_item_elt = self.search_item_tpl.get_elt({
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
140 "url": self.get_url(item),
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
141 "item": item,
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
142 "multiple_selection": self.allow_multiple_selection,
1556
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
143 "identities": cache.identities,
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
144 "options": self.options,
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
145 })
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
146
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
147 if self.allow_multiple_selection:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
148 # Include a checkbox and manage its state
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
149 checkbox = search_item_elt.select('.search-item__checkbox')[0]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
150 checkbox.checked = item['entity'] in self._selected_jids
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
151 checkbox.bind('change', lambda evt, item=item: self.on_checkbox_change(evt, item))
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
152 checkbox.bind('click', lambda evt: evt.stopPropagation())
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
153
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
154 # Highlight item if selected
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
155 if item['entity'] in self._selected_jids:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
156 card = search_item_elt.select('.card')[0]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
157 card.classList.add(self.selected_item_class)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
158
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
159 if self.click_cb is not None:
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
160 # Make the whole item clickable and perform the click callback function
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
161 search_item_elt.bind('click', lambda evt, item=item: self.click_cb(evt, item))
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
162
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
163 # Now append the whole element to the container
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
164 self.container_elt <= search_item_elt
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
165
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
166 # Apply extra callbacks if defined in options
1556
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
167 extra_cb = self.options.get("extra_cb")
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
168 if extra_cb:
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
169 for selector, cb in extra_cb.items():
5c4703870088 browser (jid_search): search items can now be customised:
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
170 for elt in search_item_elt.select(selector):
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
171 elt.bind("click", lambda evt, item=item, cb=cb: cb(evt, item))
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
172
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
173 def on_search_input(self, evt):
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
174 """Handle the 'input' event for the search element
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
175
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
176 @param evt: The event object
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
177 """
1573
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
178 evt.stopPropagation()
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
179 evt.preventDefault()
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
180 search_text = evt.target.value.strip()
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
181 if not search_text:
1593
c6976c5b85a1 browser (chat/select): add bookmarked entities on empty search
Goffi <goffi@goffi.org>
parents: 1591
diff changeset
182 aio.run(self.empty_cb(self))
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
183 elif len(search_text) > 2:
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
184 aio.run(self.perform_search(search_text))
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
185
1573
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
186 def on_form_submit(self, evt):
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
187 search_text = self.search_elt.value.strip()
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
188 search_jid = jid.JID(search_text)
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
189 if not search_jid.is_valid():
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
190 evt.stopPropagation()
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
191 evt.preventDefault()
02432346e9b2 browser (jid_search): `submit_filter` option:
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
192
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
193 async def perform_search(self, query):
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
194 if self.current_query is None:
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
195 log.debug(f"performing search: {query=}")
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
196 self.current_query = query
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
197 jid_items = json.loads(await bridge.jid_search(query, ""))
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
198 await cache.fill_identities(i["entity"] for i in jid_items)
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
199
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
200 self.last_query = query
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
201 self.current_query = None
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
202 current_query = self.search_elt.value.strip()
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
203
1546
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
204 if current_query != query:
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
205 await self.perform_search(current_query)
7f3f5ae7d65a browser (jid_search): implement a mechanism to get JIDs from search terms
Goffi <goffi@goffi.org>
parents:
diff changeset
206 return
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
207
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
208 # Include selected items in the search result regardless of the filter
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
209 jid_items_set = {item['entity']: item for item in jid_items}
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
210 for jid in self._selected_jids:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
211 if jid not in jid_items_set:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
212 jid_items_set[jid] = {"entity": jid}
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
213
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
214 # Union of search results and manually added selected items
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
215 filtered_items = [
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
216 jid_items_set[jid] for jid in jid_items_set
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
217 ]
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
218
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
219 self.filter_cb(filtered_items)
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
220
1593
c6976c5b85a1 browser (chat/select): add bookmarked entities on empty search
Goffi <goffi@goffi.org>
parents: 1591
diff changeset
221 async def on_empty_search(self, jid_search):
1548
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
222 """Handle the situation when the search box is empty"""
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
223 assert self.container_elt is not None
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
224 items = [
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
225 {
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
226 "entity": jid_,
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
227 "groups": data["groups"]
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
228 }
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
229 for jid_, data in cache.roster.items()
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
230 ]
66aa6e140ebb browser: make `jid_search` more generic:
Goffi <goffi@goffi.org>
parents: 1546
diff changeset
231 self.show_items(items)
1604
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
232
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
233 def on_checkbox_change(self, evt, item):
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
234 log.debug(f"checkbox_change {evt.target=} {item=}")
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
235 evt.stopPropagation()
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
236 cb = evt.target
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
237
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
238 if cb.checked:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
239 self._selected_jids.add(item['entity'])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
240 cb.closest('.card').classList.add(self.selected_item_class)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
241 else:
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
242 self._selected_jids.remove(item['entity'])
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
243 cb.closest('.card').classList.remove(self.selected_item_class)
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
244
4a9679369856 browser (call): implements group calls:
Goffi <goffi@goffi.org>
parents: 1593
diff changeset
245 self.update_selection_state()