annotate libervia/web/pages/chat/_browser/__init__.py @ 1613:c4407befc52a

browser (chat): fix attachments URL for messages.
author Goffi <goffi@goffi.org>
date Mon, 17 Jun 2024 17:37:15 +0200
parents 19c83dd943df
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 import json
1541
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
2 import re
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 from bridge import AsyncBridge as Bridge
1585
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
5 from browser import DOMNode, aio, console as log, document, window
1541
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
6 from cache import cache, identities
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
7 import dialog
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
8 from file_uploader import FileUploader
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
9 import jid
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
10 from js_modules import emoji_picker_element
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
11 from js_modules.tippy_js import tippy
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
12 import popup
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 from template import Template, safe
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
14 from tools import is_touch_device
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 log.warning = log.warn
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 profile = window.profile or ""
1595
7941444c1671 pages: set `own_local_jid` to avoid confusion with `own_jid`:
Goffi <goffi@goffi.org>
parents: 1585
diff changeset
18 # JID used in the local chat (real JID for one2one, room JID otherwise)
7941444c1671 pages: set `own_local_jid` to avoid confusion with `own_jid`:
Goffi <goffi@goffi.org>
parents: 1585
diff changeset
19 own_local_jid = jid.JID(window.own_local_jid)
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 target_jid = jid.JID(window.target_jid)
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
21 chat_type = window.chat_type
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 bridge = Bridge()
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
23
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 # Sensible value to consider that user is at the bottom
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 SCROLL_SENSITIVITY = 200
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
26
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
27 INPUT_MODES = {"normal", "edit", "quote"}
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
28 MODE_CLASS = "mode_{}"
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
29
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
30
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 class LiberviaWebChat:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 def __init__(self):
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
33 self._input_mode = "normal"
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
34 self.input_data = {}
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 self.message_tpl = Template("chat/message.html")
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
36 self.extra_menu_tpl = Template("chat/extra_menu.html")
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
37 self.reactions_tpl = Template("chat/reactions.html")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
38 self.reactions_details_tpl = Template("chat/reactions_details.html")
1541
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
39 self.url_preview_control_tpl = Template("components/url_preview_control.html")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
40 self.url_preview_tpl = Template("components/url_preview.html")
1542
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
41 self.new_messages_marker_elt = Template("chat/new_messages_marker.html").get_elt()
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
42 self.editions_tpl = Template("chat/editions.html")
1541
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
43
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 self.messages_elt = document["messages"]
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
45
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 # attachments
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 self.file_uploader = FileUploader(
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 "", "chat/attachment_preview.html", on_delete_cb=self.on_attachment_delete
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 )
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 self.attachments_elt = document["attachments"]
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 self.message_input = document["message_input"]
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
52
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
53 close_button = document.select_one(".modal-close")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
54 close_button.bind("click", self.close_modal)
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
55
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 # hide/show attachments
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 MutationObserver = window.MutationObserver
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 observer = MutationObserver.new(lambda *__: self.update_attachments_visibility())
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 observer.observe(self.attachments_elt, {"childList": True})
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
60
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 # we want the message scroll to be initially at the bottom
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 self.messages_elt.scrollTop = self.messages_elt.scrollHeight
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
63
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
64 # listeners/dynamic updates
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
65 self.add_message_event_listeners()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
66 self.handle_url_previews()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
67 self.add_reactions_listeners()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
68
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
69 # input
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
70 self.auto_resize_message_input()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
71 self.message_input.focus()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
72
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
73 @property
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
74 def input_mode(self) -> str:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
75 return self._input_mode
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
76
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
77 @input_mode.setter
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
78 def input_mode(self, new_mode: str) -> None:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
79 if new_mode == self.input_mode:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
80 return
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
81 if new_mode not in INPUT_MODES:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
82 raise ValueError(f"Invalid input mode: {new_mode!r}")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
83 target_elt = self.message_input
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
84 target_elt.classList.remove(MODE_CLASS.format(self._input_mode))
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
85 self._input_mode = new_mode
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
86 target_elt.classList.add(MODE_CLASS.format(new_mode))
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
87 self.input_data.clear()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
88
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 @property
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 def is_at_bottom(self):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 return (
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 self.messages_elt.scrollHeight
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 - self.messages_elt.scrollTop
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 - self.messages_elt.clientHeight
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 <= SCROLL_SENSITIVITY
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 )
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
97
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
98 async def send_message(self):
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 """Send message currently in input area
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
100
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 The message and corresponding attachment will be sent
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 """
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 message = self.message_input.value.rstrip()
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 log.info(f"{message=}")
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
105
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 # attachments
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 attachments = []
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 for attachment_elt in self.attachments_elt.children:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 file_data = json.loads(attachment_elt.getAttribute("data-file"))
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 attachments.append(file_data)
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
111
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 if message or attachments:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 extra = {}
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
114
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 if attachments:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 extra["attachments"] = attachments
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
117
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 # now we send the message
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 try:
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
120 if self.input_mode == "edit":
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
121 message_id = self.input_data["id"]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
122 edit_data = {
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
123 "message": {"": message},
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
124 "extra": extra
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
125 }
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
126 await bridge.message_edit(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
127 message_id, json.dumps(edit_data, ensure_ascii=False)
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
128 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
129 else:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
130 await bridge.message_send(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
131 str(target_jid),
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
132 {"": message}, {}, "auto", json.dumps(extra, ensure_ascii=False)
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 )
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 except Exception as e:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
135 dialog.notification.show(f"Can't send message: {e}", "error")
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 else:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 self.message_input.value = ""
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 self.attachments_elt.clear()
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
139 self.input_mode = "normal"
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
140
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 def _on_message_new(
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 self,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 uid: str,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 timestamp: float,
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
145 from_jid_s: str,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
146 to_jid_s: str,
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 message: dict,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 subject: dict,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 mess_type: str,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 extra_s: str,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 profile: str,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 ) -> None:
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
153 from_jid = jid.JID(from_jid_s)
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
154 to_jid = jid.JID(to_jid_s)
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 if (
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
156 from_jid.bare == window.target_jid
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
157 or to_jid.bare == window.target_jid
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 ):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 aio.run(
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
160 self.on_message_new(
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 uid,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 timestamp,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 from_jid,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 to_jid,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 message,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 subject,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 mess_type,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 json.loads(extra_s),
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 profile,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 )
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 )
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
172
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
173 def _on_message_update(
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
174 self, uid: str, type_: str, update_data_s: str, profile: str
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
175 ) -> None:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
176 aio.run(self.on_message_update(uid, type_, update_data_s, profile))
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
177
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
178 async def on_message_update(
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
179 self, uid: str, type_: str, update_data_s: str, profile: str
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
180 ) -> None:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
181 update_data = json.loads(update_data_s)
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
182 is_at_bottom = self.is_at_bottom
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
183 if type_ == "REACTION":
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
184 reactions = update_data["reactions"]
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
185 log.debug(f"new reactions: {reactions}")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
186 try:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
187 reactions_wrapper_elt = document[f"msg_reactions_{uid}"]
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
188 except KeyError:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
189 log.debug(f"Message {uid} not found, no reactions to update")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
190 else:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
191 log.debug(f"Message {uid} found, new reactions: {reactions}")
1596
52098b5bab8d browser (chat): add data for reactions
Goffi <goffi@goffi.org>
parents: 1595
diff changeset
192 reactions_elt = self.reactions_tpl.get_elt(
52098b5bab8d browser (chat): add data for reactions
Goffi <goffi@goffi.org>
parents: 1595
diff changeset
193 {
52098b5bab8d browser (chat): add data for reactions
Goffi <goffi@goffi.org>
parents: 1595
diff changeset
194 "chat_type": chat_type,
52098b5bab8d browser (chat): add data for reactions
Goffi <goffi@goffi.org>
parents: 1595
diff changeset
195 "own_local_jid": str(own_local_jid),
52098b5bab8d browser (chat): add data for reactions
Goffi <goffi@goffi.org>
parents: 1595
diff changeset
196 "reactions": reactions
52098b5bab8d browser (chat): add data for reactions
Goffi <goffi@goffi.org>
parents: 1595
diff changeset
197 })
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
198 reactions_wrapper_elt.clear()
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
199 reactions_wrapper_elt <= reactions_elt
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
200 self.add_reactions_listeners(reactions_elt)
1585
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
201 elif type_ in ("EDIT", "RETRACT"):
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
202 try:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
203 old_message_elt = document[uid]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
204 except KeyError:
1585
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
205 log.debug(f"Message {uid} not found, no {type_.lower()}ion to apply")
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
206 else:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
207 template_data = await self.message_to_template_data(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
208 uid,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
209 update_data["timestamp"],
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
210 jid.JID(update_data["from"]),
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
211 jid.JID(update_data["to"]),
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
212 update_data["message"],
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
213 update_data["subject"],
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
214 update_data["type"],
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
215 update_data["extra"]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
216 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
217
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
218 new_message_elt = self.message_tpl.get_elt(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
219 template_data
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
220 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
221 old_message_elt.replaceWith(new_message_elt)
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
222 self.add_message_event_listeners(new_message_elt)
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
223 self.handle_url_previews(new_message_elt)
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
224 else:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
225 log.warning(f"Unsupported update type: {type_!r}")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
226
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
227 # If user was at the bottom, keep the scroll at the bottom
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
228 if is_at_bottom:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
229 self.messages_elt.scrollTop = self.messages_elt.scrollHeight
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
230
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
231 async def message_to_template_data(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
232 self,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
233 uid: str,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
234 timestamp: float,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
235 from_jid: jid.JID,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
236 to_jid: jid.JID,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
237 message_data: dict,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
238 subject_data: dict,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
239 mess_type: str,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
240 extra: dict,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
241 ) -> dict:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
242 """Generate template data to use with [message_tpl]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
243
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
244 @return: template data
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
245 """
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
246 xhtml_data = extra.get("xhtml")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
247 if not xhtml_data:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
248 xhtml = None
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
249 else:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
250 try:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
251 xhtml = xhtml_data[""]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
252 except KeyError:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
253 xhtml = next(iter(xhtml_data.values()))
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
254
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
255 if chat_type == "group":
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
256 await cache.fill_identities([str(from_jid)])
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
257 else:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
258 await cache.fill_identities([str(jid.JID(from_jid).bare)])
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
259 from_jid = from_jid.bare
1613
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
260 attachments = extra.get("attachments", [])
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
261 for attachment in attachments:
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
262 if "url" not in attachment:
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
263 try:
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
264 attachment["url"] = next(
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
265 s['url'] for s in attachment["sources"] if 'url' in s
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
266 )
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
267 except (StopIteration, KeyError):
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
268 log.warning(
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
269 f"An attachment has no URL: {attachment}"
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
270 )
1610
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
271 msg_data = {
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
272 "id": uid,
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
273 "timestamp": extra.get("updated", timestamp),
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
274 "type": mess_type,
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
275 "from_": str(from_jid),
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
276 "text": message_data.get("") or next(iter(message_data.values()), ""),
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
277 "subject": subject_data.get("") or next(iter(subject_data.values()), ""),
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
278 "type": mess_type,
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
279 "reeceived": extra.get("received_timestamp") or timestamp,
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
280 "encrypted": extra.get("encrypted", False),
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
281 "received": extra.get("received", False),
1613
c4407befc52a browser (chat): fix attachments URL for messages.
Goffi <goffi@goffi.org>
parents: 1610
diff changeset
282 "attachments": attachments,
1610
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
283 "extra": extra
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
284 }
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
285 for key in ("thread", "thread_parent", "delay_sender", "info_type"):
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
286 value = extra.get(key)
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
287 if value is not None:
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
288 msg_data[key] = value
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
289
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
290 if xhtml:
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
291 msg_data["html"] = safe(xhtml)
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
292
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
293 return {
1595
7941444c1671 pages: set `own_local_jid` to avoid confusion with `own_jid`:
Goffi <goffi@goffi.org>
parents: 1585
diff changeset
294 "own_local_jid": str(own_local_jid),
7941444c1671 pages: set `own_local_jid` to avoid confusion with `own_jid`:
Goffi <goffi@goffi.org>
parents: 1585
diff changeset
295 "chat_type": chat_type,
1610
19c83dd943df browser (chat): don't set `None` value in message data used in template:
Goffi <goffi@goffi.org>
parents: 1596
diff changeset
296 "msg": msg_data,
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
297 "identities": identities,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
298 }
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
299
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
300 async def on_message_new(
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
301 self,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 uid: str,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
303 timestamp: float,
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
304 from_jid: jid.JID,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
305 to_jid: jid.JID,
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
306 message_data: dict,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
307 subject_data: dict,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
308 mess_type: str,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
309 extra: dict,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
310 profile: str,
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
311 ) -> None:
1542
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
312 # FIXME: visibilityState doesn't detect OS events such as `Alt + Tab`, using focus
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
313 # event may help to get those use cases, but it gives false positives.
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
314 if (
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
315 document.visibilityState == "hidden"
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
316 and self.new_messages_marker_elt.parent is None
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
317 ):
1542
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
318 # the page is not visible, and we have no new messages marker yet, so we add
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
319 # it
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
320 self.messages_elt <= self.new_messages_marker_elt
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
321
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
322 template_data = await self.message_to_template_data(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
323 uid,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
324 timestamp,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
325 from_jid,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
326 to_jid,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
327 message_data,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
328 subject_data,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
329 mess_type,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
330 extra
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
331 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
332
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
333 message_elt = self.message_tpl.get_elt(
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
334 template_data
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
335 )
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
336
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
337 # Check if user is viewing older messages or is at the bottom
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
338 is_at_bottom = self.is_at_bottom
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
339
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
340 self.messages_elt <= message_elt
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
341 self.add_message_event_listeners(message_elt)
1541
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
342 # we add preview in parallel on purpose, as they can be slow to get
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
343 self.handle_url_previews(message_elt)
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
344
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
345 # If user was at the bottom, keep the scroll at the bottom
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
346 if is_at_bottom:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
347 self.messages_elt.scrollTop = self.messages_elt.scrollHeight
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
348
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
349 def auto_resize_message_input(self):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
350 """Resize the message input field according to content."""
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
351
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
352 is_at_bottom = self.is_at_bottom
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
353
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
354 # The textarea's height is first reset to 'auto' to ensure it's not influenced by
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
355 # the previous content.
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
356 self.message_input.style.height = "auto"
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
357
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
358 # Then the height is set to the scrollHeight of the textarea (which is the height
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
359 # of the content), plus the vertical border, resulting in a textarea that grows as
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
360 # more lines of text are added.
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
361 self.message_input.style.height = f"{self.message_input.scrollHeight + 2}px"
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
362
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
363 if is_at_bottom:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
364 # we want the message are to still display the last message
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
365 self.messages_elt.scrollTop = self.messages_elt.scrollHeight
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
366
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
367 def on_message_keydown(self, evt):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
368 """Handle the 'keydown' event of the message input field
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
369
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
370 @param evt: The event object. 'target' refers to the textarea element.
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
371 """
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
372 if evt.keyCode == 13: # <Enter> key
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
373 if not window.navigator.maxTouchPoints:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
374 # we have a non touch device, we send message on <Enter>
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
375 if not evt.shiftKey:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
376 evt.preventDefault() # Prevents line break
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
377 aio.run(self.send_message())
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
378 elif evt.keyCode == 27: # <ESC> key
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
379 evt.preventDefault()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
380 self.message_input.value = ''
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
381 self.input_mode = 'normal'
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
382 self.auto_resize_message_input()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
383 elif evt.keyCode == 38: # <Up> arrow key
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
384 if self.input_mode == "normal" and self.message_input.value.strip() == "":
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
385 evt.preventDefault()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
386 own_msgs = document.getElementsByClassName('own_msg')
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
387 if own_msgs.length > 0:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
388 last_msg = own_msgs[own_msgs.length - 1]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
389 aio.run(self.on_action_edit(None, last_msg))
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
390
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
391 def update_attachments_visibility(self):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
392 if len(self.attachments_elt.children):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
393 self.attachments_elt.classList.remove("is-contracted")
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
394 else:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
395 self.attachments_elt.classList.add("is-contracted")
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
396
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
397 def on_file_selected(self, evt):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
398 """Handle file selection"""
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
399 log.info("file selected")
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
400 files = evt.currentTarget.files
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
401 self.file_uploader.upload_files(files, self.attachments_elt)
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
402 self.message_input.focus()
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
403
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
404 def on_attachment_delete(self, evt):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
405 evt.stopPropagation()
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
406 target = evt.currentTarget
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
407 item_elt = DOMNode(target.closest(".attachment-preview"))
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
408 item_elt.remove()
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
409
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
410 def on_attach_button_click(self, evt):
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
411 document["file_input"].click()
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
412
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
413 def on_extra_btn_click(self, evt):
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
414 message_elt = evt.target.closest("div.is-chat-message")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
415 is_own = message_elt.classList.contains("own_msg")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
416 if is_own:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
417 own_messages = document.select('.own_msg')
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
418 # with XMPP, we can currently only edit our last message
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
419 can_edit = own_messages and message_elt is own_messages[-1]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
420 else:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
421 can_edit = False
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
422
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
423 content_elt = self.extra_menu_tpl.get_elt({
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
424 "edit": can_edit,
1585
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
425 "retract": is_own,
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
426 })
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
427 extra_popup = popup.create_popup(evt.target, content_elt, focus_elt=message_elt)
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
428
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
429 def on_action_click(evt, callback):
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
430 extra_popup.hide()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
431 aio.run(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
432 callback(evt, message_elt)
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
433 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
434
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
435 for cls_name, callback in (
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
436 ("action_quote", self.on_action_quote),
1585
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
437 ("action_edit", self.on_action_edit),
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
438 ("action_retract", self.on_action_retract),
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
439 ):
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
440 for elt in content_elt.select(f".{cls_name}"):
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
441 elt.bind("click", lambda evt, callback=callback: on_action_click(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
442 evt, callback
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
443 ))
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
444
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
445 def on_reaction_click(self, evt, message_elt):
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
446 window.evt = evt
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
447 aio.run(
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
448 bridge.message_reactions_set(
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
449 message_elt["id"], [evt.detail["unicode"]], "toggle"
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
450 )
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
451 )
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
452 if evt.deltaY != 0:
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
453 document["attachments"].scrollLeft += evt.deltaY * 0.8
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
454 evt.preventDefault()
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
455
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
456 async def get_message_tuple(self, message_elt) -> tuple|None:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
457 """Retrieve message tuple from as sent by [message_new]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
458
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
459 If not corresponding message data is found, an error will shown, and None is
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
460 returned.
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
461 @param message_elt: message element, it's "id" attribute will be use to retrieve
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
462 message data
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
463 @return: message data as a tuple, or None if not message with this ID is found.
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
464 """
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
465 message_id = message_elt['id']
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
466 history_data = await bridge.history_get(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
467 "", "", -2, True, {"id": message_elt['id']}
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
468 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
469 if not history_data:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
470 dialog.notification.show(f"Can't find message {message_id}", "error")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
471 return None
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
472 return history_data[0]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
473
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
474 async def on_action_quote(self, __, message_elt) -> None:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
475 message_data = await self.get_message_tuple(message_elt)
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
476 if message_data is not None:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
477 messages = message_data[4]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
478 body = next(iter(messages.values()), "")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
479 quote = "\n".join(f"> {l}" for l in body.split("\n"))
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
480 self.message_input.value = f"{quote}\n{self.message_input.value}"
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
481 self.input_mode = "quote"
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
482 self.input_data["id"] = message_elt["id"]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
483 self.auto_resize_message_input()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
484 self.message_input.focus()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
485
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
486 async def on_action_edit(self, __, message_elt) -> None:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
487 message_data = await self.get_message_tuple(message_elt)
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
488 if message_data is not None:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
489 messages = message_data[4]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
490 body = next(iter(messages.values()), "")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
491 if not body:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
492 dialog.notification.show("No content found in message, nothing to edit")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
493 return
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
494
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
495 self.message_input.value = body
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
496 self.input_mode = "edit"
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
497 self.input_data["id"] = message_elt["id"]
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
498 self.auto_resize_message_input()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
499 self.message_input.focus()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
500
1585
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
501 async def on_action_retract(self, __, message_elt) -> None:
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
502 confirmed = await dialog.Confirm(safe(
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
503 "This message will be permanently removed. Are you sure?<br><br>"
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
504 "WARNING: It is impossible to guarantee that other participants in the "
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
505 "discussion will delete this message as well. You must assume it has been "
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
506 "seen. If a password or other sensitive information has been accidentally "
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
507 "shared, please ensure to take appropriate measures to change it and "
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
508 "mitigate the risks."
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
509 )).ashow()
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
510 if confirmed:
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
511 await bridge.message_retract(message_elt["id"])
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
512 else:
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
513 log.info(f"Retraction of message {message_elt['id']} cancelled by user.")
9fc4120888be browser (chat): message retraction implementation
Goffi <goffi@goffi.org>
parents: 1584
diff changeset
514
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
515 def get_reaction_panel(self, source_elt):
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
516 emoji_picker_elt = document.createElement("emoji-picker")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
517 message_elt = source_elt.closest("div.is-chat-message")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
518 emoji_picker_elt.bind(
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
519 "emoji-click", lambda evt: self.on_reaction_click(evt, message_elt)
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
520 )
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
521
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
522 return emoji_picker_elt
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
523
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
524 def add_message_event_listeners(self, parent_elt=None):
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
525 """Prepare a message to be dynamic
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
526
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
527 - make attachments dynamically clickable
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
528 - make the extra button clickable
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
529 """
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
530 ## attachments
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
531 # FIXME: only handle images for now, and display them in a modal
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
532 if parent_elt is None:
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
533 parent_elt = document
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
534 img_elts = parent_elt.select(".message-attachment img")
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
535 for img_elt in img_elts:
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
536 img_elt.bind("click", self.open_modal)
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
537 img_elt.style.cursor = "pointer"
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
538
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
539 ## reaction button
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
540 for reaction_btn in parent_elt.select(".reaction-button"):
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
541 message_elt = reaction_btn.closest("div.is-chat-message")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
542 tippy(
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
543 reaction_btn,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
544 {
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
545 "trigger": "click",
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
546 "content": self.get_reaction_panel,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
547 "appendTo": document.body,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
548 "placement": "bottom",
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
549 "interactive": True,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
550 "theme": "light",
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
551 "onShow": lambda __, message_elt=message_elt: (
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
552 message_elt.classList.add("has-popup-focus")
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
553 ),
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
554 "onHide": lambda __, message_elt=message_elt: (
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
555 message_elt.classList.remove("has-popup-focus")
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
556 ),
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
557 },
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
558 )
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
559
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
560 ## extra button
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
561 for extra_btn in parent_elt.select(".extra-button"):
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
562 extra_btn.bind("click", self.on_extra_btn_click)
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
563
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
564 ## editions
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
565 for edition_icon_elt in parent_elt.select(".message-editions"):
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
566 message_elt = edition_icon_elt.closest("div.is-chat-message")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
567 dataset = message_elt.dataset.to_dict()
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
568 try:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
569 editions = json.loads(dataset["editions"])
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
570 except (ValueError, KeyError):
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
571 log.error(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
572 f"Internal Error: invalid or missing editions data: {message_elt['id']}"
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
573 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
574 else:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
575 for edition in editions:
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
576 edition["text"] = (
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
577 edition["message"].get("")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
578 or next(iter(edition["message"].values()), "")
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
579 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
580 editions_elt = self.editions_tpl.get_elt({"editions": editions})
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
581 tippy(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
582 edition_icon_elt,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
583 {
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
584 "content": editions_elt,
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
585 "theme": "light",
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
586 "appendTo": document.body
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
587 }
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
588
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
589 )
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
590
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
591 def add_reactions_listeners(self, parent_elt=None) -> None:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
592 """Add listener on reactions to handle details and reaction toggle"""
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
593 if parent_elt is None:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
594 parent_elt = document
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
595
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
596 is_touch = is_touch_device()
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
597
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
598 for reaction_elt in parent_elt.select(".reaction"):
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
599 # Reaction details
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
600 dataset = reaction_elt.dataset.to_dict()
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
601 reacting_jids = sorted(json.loads(dataset.get("jids", "[]")))
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
602 reaction_details_elt = self.reactions_details_tpl.get_elt(
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
603 {"reacting_jids": reacting_jids, "identities": identities}
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
604 )
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
605
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
606 # Configure tippy based on device type
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
607 tippy_config = {
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
608 "content": reaction_details_elt,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
609 "placement": "bottom",
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
610 "theme": "light",
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
611 "touch": ["hold", 500] if is_touch else True,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
612 "trigger": "click" if is_touch else "mouseenter focus",
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
613 "delay": [0, 800] if is_touch else 0,
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
614 }
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
615 tippy(reaction_elt, tippy_config)
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
616
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
617 # Toggle reaction when clicked/touched
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
618 emoji_elt = reaction_elt.select_one(".emoji")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
619 emoji = emoji_elt.html.strip()
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
620 message_elt = reaction_elt.closest("div.is-chat-message")
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
621 msg_id = message_elt["id"]
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
622
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
623 def toggle_reaction(event, msg_id=msg_id, emoji=emoji):
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
624 # Prevent default if it's a touch device to distinguish from long press
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
625 if is_touch:
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
626 event.preventDefault()
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
627 aio.run(bridge.message_reactions_set(msg_id, [emoji], "toggle"))
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
628
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
629 reaction_elt.bind("click", toggle_reaction)
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
630
1541
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
631 def find_links(self, message_elt):
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
632 """Find all http and https links within the body of a message."""
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
633 msg_body_elt = message_elt.select_one(".msg_body")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
634 if not msg_body_elt:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
635 return
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
636
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
637 # Extracting links from text content
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
638 text = msg_body_elt.text
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
639 raw_urls = re.findall(
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
640 r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F])|#)+",
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
641 text,
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
642 )
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
643
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
644 # Extracting links from <a> elements
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
645 a_elements = msg_body_elt.select("a")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
646 for a_elt in a_elements:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
647 href = a_elt.attrs.get("href", "")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
648 if href.startswith("http://") or href.startswith("https://"):
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
649 raw_urls.append(href)
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
650
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
651 # we remove duplicates
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
652 urls = list(dict.fromkeys(raw_urls))
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
653
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
654 return urls
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
655
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
656 async def add_url_previews(self, url_previews_elt, urls) -> None:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
657 """Add URL previews to the .url-previews element of a message."""
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
658 url_previews_elt.clear()
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
659 for url in urls:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
660 try:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
661 url_preview_data_s = await bridge.url_preview_get(url, "")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
662 except Exception as e:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
663 log.warning(f"Couldn't get URL preview for {url}: {e}")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
664 continue
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
665
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
666 if not url_preview_data_s:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
667 log.warning(f"No preview could be found for URL: {url}")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
668 continue
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
669
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
670 url_preview_data = json.loads(url_preview_data_s)
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
671
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
672 url_preview_elt = self.url_preview_tpl.get_elt(
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
673 {"url_preview": url_preview_data}
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
674 )
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
675 url_previews_elt <= url_preview_elt
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
676
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
677 def handle_url_previews(self, parent_elt=None):
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
678 """Check if URL are presents in a message and show appropriate element
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
679
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
680 According to settings, either a preview control panel will be shown to wait for
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
681 user click, or directly the previews, or nothing at all.
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
682 """
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
683
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
684 if parent_elt is None:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
685 parent_elt = document
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
686 chat_message_elts = parent_elt.select(".is-chat-message")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
687 else:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
688 chat_message_elts = [parent_elt]
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
689 for message_elt in chat_message_elts:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
690 urls = self.find_links(message_elt)
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
691 if urls:
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
692 url_previews_elt = message_elt.select_one(".url-previews")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
693 url_previews_elt.classList.remove("is-hidden")
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
694 preview_control_elt = self.url_preview_control_tpl.get_elt()
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
695 fetch_preview_btn = preview_control_elt.select_one(
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
696 ".action_fetch_preview"
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
697 )
1541
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
698 fetch_preview_btn.bind(
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
699 "click",
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
700 lambda __, previews_elt=url_previews_elt, preview_urls=urls: aio.run(
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
701 self.add_url_previews(previews_elt, preview_urls)
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
702 ),
1541
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
703 )
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
704 url_previews_elt <= preview_control_elt
3c384b51b2a1 browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents: 1540
diff changeset
705
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
706 def open_modal(self, evt):
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
707 modal_image = document.select_one("#modal-image")
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
708 modal_image.src = evt.target.src
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
709 modal_image.alt = evt.target.alt
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
710 modal = document.select_one("#modal")
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
711 modal.classList.add("is-active")
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
712
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
713 def close_modal(self, evt):
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
714 modal = document.select_one("#modal")
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
715 modal.classList.remove("is-active")
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
716
1542
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
717 def handle_visibility_change(self, evt):
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
718 if (
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
719 document.visibilityState == "hidden"
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
720 and self.new_messages_marker_elt.parent is not None
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
721 ):
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
722 # if there is a new messages marker, we remove it
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
723 self.new_messages_marker_elt.remove()
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
724
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
725
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
726 libervia_web_chat = LiberviaWebChat()
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
727
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
728 document["message_input"].bind(
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
729 "input", lambda __: libervia_web_chat.auto_resize_message_input()
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
730 )
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
731 document["message_input"].bind("keydown", libervia_web_chat.on_message_keydown)
1584
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
732 document["send_button"].bind(
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
733 "click",
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
734 lambda __: aio.run(libervia_web_chat.send_message())
eab815e48795 browser (chat): message edition + extra menu:
Goffi <goffi@goffi.org>
parents: 1577
diff changeset
735 )
1540
b4342176fa0a browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents: 1536
diff changeset
736 document["attach_button"].bind("click", libervia_web_chat.on_attach_button_click)
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
737 document["file_input"].bind("change", libervia_web_chat.on_file_selected)
1542
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
738
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
739 document.bind("visibilitychange", libervia_web_chat.handle_visibility_change)
fb31d3dba0c3 browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents: 1541
diff changeset
740
1536
dc81403a5b2f browser: chat page:
Goffi <goffi@goffi.org>
parents:
diff changeset
741 bridge.register_signal("message_new", libervia_web_chat._on_message_new)
1577
9ba532041a8e browser (chat): implement message reactions.
Goffi <goffi@goffi.org>
parents: 1542
diff changeset
742 bridge.register_signal("message_update", libervia_web_chat._on_message_update)