# HG changeset patch # User Goffi # Date 1691533336 -7200 # Node ID 66aa6e140ebb68a8dcc6bb0a65939e6de010a872 # Parent 383e1fee29f6e5ac136dbb9767ef7d6a31f6cb13 browser: make `jid_search` more generic: rel 423 diff -r 383e1fee29f6 -r 66aa6e140ebb libervia/web/pages/_browser/jid_search.py --- a/libervia/web/pages/_browser/jid_search.py Thu Jul 06 12:12:07 2023 +0200 +++ b/libervia/web/pages/_browser/jid_search.py Wed Aug 09 00:22:16 2023 +0200 @@ -1,34 +1,101 @@ +import json +from urllib.parse import quote, urljoin + from bridge import AsyncBridge as Bridge from browser import aio, console as log, window from cache import cache -import json +from template import Template log.warning = log.warn profile = window.profile or "" bridge = Bridge() - class JidSearch: - def __init__(self, search_elt, callback, empty_cb=None): + def __init__( + self, + search_elt, + container_elt=None, + filter_cb=None, + empty_cb=None, + get_url=None, + click_cb=None + ): + """Initialize the JidSearch instance + + @param search_elt: The HTML element for search + @param container_elt: The HTML container to display the search results + @param filter_cb: The callback to filter the search results + @param empty_cb: The callback when the search box is empty + @param get_url: The function to get URL for each entity in the search result + @param click_cb: The function to handle the click event on each entity in the + search result + """ + self.search_item_tpl = Template("components/search_item.html") self.search_elt = search_elt self.search_elt.bind("input", self.on_search_input) self.last_query = None self.current_query = None - self.callback = callback - self.empty_cb = empty_cb + self.container_elt = container_elt + + if click_cb is not None and get_url is None: + self.get_url = lambda _: "#" + else: + self.get_url = get_url if get_url is not None else self.default_get_url + self.click_cb = click_cb + + if filter_cb is None: + if container_elt is None: + raise ValueError("container_elt must be set if filter_cb is not set") + filter_cb = self.show_items + self.filter_cb = filter_cb + + self.empty_cb = empty_cb or self.on_empty_search + current_search = search_elt.value.strip() or None if current_search is not None: aio.run(self.perform_search(current_search)) + def default_get_url(self, item): + """Default method to get the URL for a given entity + + @param item: The item (entity) for which the URL is required + """ + return urljoin(f"{window.location.href}/", quote(item["entity"])) + + def show_items(self, items): + """Display the search items in the specified container + + @param items: The list of search items to be displayed + """ + assert self.container_elt is not None + self.container_elt.clear() + for item in items: + search_item_elt = self.search_item_tpl.get_elt({ + "url": self.get_url(item), + "item": item, + "identities": cache.identities + }) + if self.click_cb is not None: + search_item_elt.bind('click', lambda evt, item=item: self.click_cb(item)) + self.container_elt <= search_item_elt + def on_search_input(self, evt): + """Handle the 'input' event for the search element + + @param evt: The event object + """ search_text = evt.target.value.strip() - if not search_text and self.empty_cb is not None: + if not search_text: self.empty_cb() elif len(search_text) > 2: aio.run(self.perform_search(search_text)) async def perform_search(self, query): + """Perform the search operation for a given query + + @param query: The search query + """ if self.current_query is None: log.debug(f"performing search: {query=}") self.current_query = query @@ -41,4 +108,16 @@ if current_query != query: await self.perform_search(current_query) return - self.callback(jid_items) + self.filter_cb(jid_items) + + def on_empty_search(self): + """Handle the situation when the search box is empty""" + assert self.container_elt is not None + items = [ + { + "entity": jid_, + "groups": data["groups"] + } + for jid_, data in cache.roster.items() + ] + self.show_items(items) diff -r 383e1fee29f6 -r 66aa6e140ebb libervia/web/pages/chat/select/_browser/__init__.py --- a/libervia/web/pages/chat/select/_browser/__init__.py Thu Jul 06 12:12:07 2023 +0200 +++ b/libervia/web/pages/chat/select/_browser/__init__.py Wed Aug 09 00:22:16 2023 +0200 @@ -1,51 +1,13 @@ + from bridge import AsyncBridge as Bridge -from browser import aio, bind, console as log, document, window -from urllib.parse import urljoin, quote +from browser import console as log, document, window +from cache import cache from jid_search import JidSearch -from template import Template -from cache import cache -from pprint import pp log.warning = log.warn -profile = window.profile or "" -bridge = Bridge() -class ChatSelect: - - def __init__(self): - self.search_item_tpl = Template("chat/search_item.html") - self.chat_items_elt = document["chat_items"] - - def show_items(self, items) -> None: - for item in items: - search_item_elt = self.search_item_tpl.get_elt({ - "url": urljoin(f"{window.location.href}/", quote(item["entity"])), - "item": item, - "identities": cache.identities - }) - self.chat_items_elt <= search_item_elt - - def on_empty_search(self): - items = [ - { - "entity": jid_, - "groups": data["groups"] - } - for jid_, data in cache.roster.items() - ] - self.chat_items_elt.clear() - self.show_items(items) - - def on_search_filter(self, search_items): - self.chat_items_elt.clear() - pp(search_items) - self.show_items(search_items) - - -chat_select = ChatSelect() jid_search = JidSearch( document["search"], - chat_select.on_search_filter, - chat_select.on_empty_search + document["chat_items"], )