Mercurial > libervia-web
diff libervia/web/pages/forums/view/page_meta.py @ 1642:c03297bb8d19
server, browser (forums): Redesign of the forum feature:
Forum has been fully redesigned, it now uses pubsub relationships and pubsub extended
discovery to handle the hierarchy.
Categories lead to topics (which are the name of the items of a blog-like nodes). Topics
have comment nodes which are used to show the topic messages.
Subscription state is retrieve when a thread is shown, and can be changed easily with as
ingle button click.
Quill editor is used, and is extended with Quill-Mention to easily send a mention to an
XMPP entity.
Attachments and tags are handled with buttons added to Quill editor.
Search in a thread is using Pubsub MAM, is the same way as for blogs.
rel 463
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 06 Sep 2025 16:30:46 +0200 |
parents | 301fe2f1a34a |
children |
line wrap: on
line diff
--- a/libervia/web/pages/forums/view/page_meta.py Sat Sep 06 12:12:42 2025 +0200 +++ b/libervia/web/pages/forums/view/page_meta.py Sat Sep 06 16:30:46 2025 +0200 @@ -10,22 +10,104 @@ name = "forum_view" label = D_("View") -access = C.PAGES_ACCESS_PUBLIC -template = "forum/view.html" +access = C.PAGES_ACCESS_PROFILE +template = "forum/view_messages.html" def parse_url(self, request): - self.get_path_args(request, ["service", "node"], 2, service="jid") + self.get_path_args(request, ["service", "node", "item"], 3, service="jid") + + +def add_breadcrumb(self, request, breadcrumbs): + return None async def prepare_render(self, request): + profile = self.get_profile(request) or C.SERVICE_PROFILE data = self.get_r_data(request) - data["show_comments"] = False - blog_page = self.get_page_by_name("blog_view") - request.args[b"before"] = [b""] - request.args[b"reverse"] = [b"1"] - await blog_page.prepare_render(self, request) - request.template_data["login_url"] = self.get_page_redirect_url(request) + parent_service, parent_node, parent_item_id = ( + data["service"], + data["node"], + data["item"], + ) + parent_item_data = data_format.deserialise( + await self.host.bridge_call( + "mb_get", + parent_service.userhost(), + parent_node, + C.NO_LIMIT, + [parent_item_id], + data_format.serialise({}), + profile, + ) + ) + parent_item = parent_item_data["items"][0] + try: + service_s = parent_item["comments"][0]["service"] + node = parent_item["comments"][0]["node"] + except (KeyError, IndexError) as e: + log.warning(f"No comment node found {e}:\n{parent_item=}") + self.page_error(request, C.HTTP_SERVICE_UNAVAILABLE) + return + + page_max = data.get("page_max", 20) + extra = self.get_pubsub_extra(request, page_max=page_max) + self.handle_search(request, extra) + if not self.use_cache(request): + extra[C.KEY_USE_CACHE] = False + blog_data = data_format.deserialise( + await self.host.bridge_call( + "mb_get", + service_s, + node, + C.NO_LIMIT, + [], + data_format.serialise(extra), + profile, + ) + ) + for parent_item in blog_data["items"]: + try: + comments_service = parent_item["comments"][0]["service"] + comments_node = parent_item["comments"][0]["node"] + except (KeyError, IndexError): + log.warning(f"Can't get comments node for item: {parent_item}") + continue + else: + parent_item["http_url"] = self.get_page_by_name("forum_view").get_url( + comments_service, comments_node + ) + self.set_pagination(request, blog_data) + await self.fill_missing_identities( + request, [i["author_jid"] for i in blog_data["items"]] + ) + + # We check if we are subscribed to the service. + try: + subscriptions = data_format.deserialise( + await self.host.bridge_call( + "ps_subscriptions_get", + service_s, + node, + profile, + ) + ) + except Exception as e: + log.warning("Can't retrieve subscriptions, assuming that we are not subscribed.") + subscribed = False + else: + subscribed = any(s.get("state") == "subscribed" for s in subscriptions) + + request.template_data.update( + { + "topic_title": parent_item["title"], + "service": service_s, + "node": node, + "blog_items": blog_data, + "subscribed": subscribed, + } + ) + self.expose_to_scripts(request, node=node, service=service_s, subscribed=subscribed) async def on_data_post(self, request): @@ -41,7 +123,8 @@ mb_data = {"service": service, "node": node, "content_rich": body} try: await self.host.bridge_call( - "mb_send", data_format.serialise(mb_data), profile) + "mb_send", data_format.serialise(mb_data), profile + ) except Exception as e: if "forbidden" in str(e): self.page_error(request, 401)