Mercurial > libervia-web
annotate libervia/web/pages/chat/_browser/__init__.py @ 1545:be20e6ac9f22
browser (bridge): add methods/properties to wait for Websocket/BroadcastChannel to be ready
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 06 Jul 2023 12:10:25 +0200 |
parents | fb31d3dba0c3 |
children | 9ba532041a8e |
rev | line source |
---|---|
1536 | 1 import json |
1541
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
2 import re |
1536 | 3 |
4 from bridge import AsyncBridge as Bridge | |
1541
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
5 from browser import DOMNode, aio, bind, console as log, document, window, html |
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 |
1536 | 10 from template import Template, safe |
11 | |
12 log.warning = log.warn | |
13 profile = window.profile or "" | |
14 own_jid = jid.JID(window.own_jid) | |
15 target_jid = jid.JID(window.target_jid) | |
16 bridge = Bridge() | |
17 | |
18 # Sensible value to consider that user is at the bottom | |
19 SCROLL_SENSITIVITY = 200 | |
20 | |
21 | |
22 class LiberviaWebChat: | |
23 def __init__(self): | |
24 self.message_tpl = Template("chat/message.html") | |
1541
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
25 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
|
26 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
|
27 self.new_messages_marker_elt = Template("chat/new_messages_marker.html").get_elt() |
1541
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
28 |
1536 | 29 self.messages_elt = document["messages"] |
30 | |
31 # attachments | |
32 self.file_uploader = FileUploader( | |
33 "", "chat/attachment_preview.html", on_delete_cb=self.on_attachment_delete | |
34 ) | |
35 self.attachments_elt = document["attachments"] | |
36 self.message_input = document["message_input"] | |
37 | |
38 # hide/show attachments | |
39 MutationObserver = window.MutationObserver | |
40 observer = MutationObserver.new(lambda *__: self.update_attachments_visibility()) | |
41 observer.observe(self.attachments_elt, {"childList": True}) | |
42 | |
43 # we want the message scroll to be initially at the bottom | |
44 self.messages_elt.scrollTop = self.messages_elt.scrollHeight | |
45 | |
46 @property | |
47 def is_at_bottom(self): | |
48 return ( | |
49 self.messages_elt.scrollHeight | |
50 - self.messages_elt.scrollTop | |
51 - self.messages_elt.clientHeight | |
52 <= SCROLL_SENSITIVITY | |
53 ) | |
54 | |
55 def send_message(self): | |
56 """Send message currently in input area | |
57 | |
58 The message and corresponding attachment will be sent | |
59 """ | |
60 message = self.message_input.value.rstrip() | |
61 log.info(f"{message=}") | |
62 | |
63 # attachments | |
64 attachments = [] | |
65 for attachment_elt in self.attachments_elt.children: | |
66 file_data = json.loads(attachment_elt.getAttribute("data-file")) | |
67 attachments.append(file_data) | |
68 | |
69 if message or attachments: | |
70 extra = {} | |
71 | |
72 if attachments: | |
73 extra["attachments"] = attachments | |
74 | |
75 # now we send the message | |
76 try: | |
77 aio.run( | |
78 bridge.message_send( | |
79 str(target_jid), {"": message}, {}, "auto", json.dumps(extra) | |
80 ) | |
81 ) | |
82 except Exception as e: | |
83 dialog.notification.show(f"Can't send message: {e}", "error") | |
84 else: | |
85 self.message_input.value = "" | |
86 self.attachments_elt.clear() | |
87 | |
88 def _on_message_new( | |
89 self, | |
90 uid: str, | |
91 timestamp: float, | |
92 from_jid: str, | |
93 to_jid: str, | |
94 message: dict, | |
95 subject: dict, | |
96 mess_type: str, | |
97 extra_s: str, | |
98 profile: str, | |
99 ) -> None: | |
100 if ( | |
101 jid.JID(from_jid).bare == window.target_jid | |
102 or jid.JID(to_jid).bare == window.target_jid | |
103 ): | |
104 aio.run( | |
105 self.on_message_new( | |
106 uid, | |
107 timestamp, | |
108 from_jid, | |
109 to_jid, | |
110 message, | |
111 subject, | |
112 mess_type, | |
113 json.loads(extra_s), | |
114 profile, | |
115 ) | |
116 ) | |
117 | |
118 async def on_message_new( | |
119 self, | |
120 uid: str, | |
121 timestamp: float, | |
122 from_jid: str, | |
123 to_jid: str, | |
124 message_data: dict, | |
125 subject_data: dict, | |
126 mess_type: str, | |
127 extra: dict, | |
128 profile: str, | |
129 ) -> None: | |
1542
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
130 # 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
|
131 # event may help to get those use cases, but it gives false positives. |
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
132 if document.visibilityState == "hidden" and self.new_messages_marker_elt.parent is None: |
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
133 # 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
|
134 # it |
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
135 self.messages_elt <= self.new_messages_marker_elt |
1536 | 136 xhtml_data = extra.get("xhtml") |
137 if not xhtml_data: | |
138 xhtml = None | |
139 else: | |
140 try: | |
141 xhtml = xhtml_data[""] | |
142 except KeyError: | |
143 xhtml = next(iter(xhtml_data.values())) | |
144 | |
145 await cache.fill_identities([from_jid]) | |
146 | |
147 msg_data = { | |
148 "id": uid, | |
149 "timestamp": timestamp, | |
150 "type": mess_type, | |
151 "from_": from_jid, | |
152 "text": message_data.get("") or next(iter(message_data.values()), ""), | |
153 "subject": subject_data.get("") or next(iter(subject_data.values()), ""), | |
154 "type": mess_type, | |
155 "thread": extra.get("thread"), | |
156 "thread_parent": extra.get("thread_parent"), | |
157 "reeceived": extra.get("received_timestamp") or timestamp, | |
158 "delay_sender": extra.get("delay_sender"), | |
159 "info_type": extra.get("info_type"), | |
160 "html": safe(xhtml) if xhtml else None, | |
161 "encrypted": extra.get("encrypted", False), | |
162 "received": extra.get("received", False), | |
163 "edited": extra.get("edited", False), | |
164 "attachments": extra.get("attachments", []), | |
165 } | |
166 message_elt = self.message_tpl.get_elt( | |
167 { | |
168 "own_jid": own_jid, | |
169 "msg": msg_data, | |
170 "identities": identities, | |
171 } | |
172 ) | |
173 | |
174 # Check if user is viewing older messages or is at the bottom | |
175 is_at_bottom = self.is_at_bottom | |
176 | |
177 self.messages_elt <= message_elt | |
178 self.make_attachments_dynamic(message_elt) | |
1541
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
179 # 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
|
180 self.handle_url_previews(message_elt) |
1536 | 181 |
182 # If user was at the bottom, keep the scroll at the bottom | |
183 if is_at_bottom: | |
184 self.messages_elt.scrollTop = self.messages_elt.scrollHeight | |
185 | |
186 def auto_resize_message_input(self): | |
187 """Resize the message input field according to content.""" | |
188 | |
189 is_at_bottom = self.is_at_bottom | |
190 | |
191 # The textarea's height is first reset to 'auto' to ensure it's not influenced by | |
192 # the previous content. | |
193 self.message_input.style.height = "auto" | |
194 | |
195 # Then the height is set to the scrollHeight of the textarea (which is the height | |
196 # of the content), plus the vertical border, resulting in a textarea that grows as | |
197 # more lines of text are added. | |
198 self.message_input.style.height = f"{self.message_input.scrollHeight + 2}px" | |
199 | |
200 if is_at_bottom: | |
201 # we want the message are to still display the last message | |
202 self.messages_elt.scrollTop = self.messages_elt.scrollHeight | |
203 | |
204 def on_message_keydown(self, evt): | |
205 """Handle the 'keydown' event of the message input field | |
206 | |
207 @param evt: The event object. 'target' refers to the textarea element. | |
208 """ | |
209 if evt.keyCode == 13: # <Enter> key | |
210 if not window.navigator.maxTouchPoints: | |
211 # we have a non touch device, we send message on <Enter> | |
212 if not evt.shiftKey: | |
213 evt.preventDefault() # Prevents line break | |
214 self.send_message() | |
215 | |
216 def update_attachments_visibility(self): | |
217 if len(self.attachments_elt.children): | |
218 self.attachments_elt.classList.remove("is-contracted") | |
219 else: | |
220 self.attachments_elt.classList.add("is-contracted") | |
221 | |
222 def on_file_selected(self, evt): | |
223 """Handle file selection""" | |
224 log.info("file selected") | |
225 files = evt.currentTarget.files | |
226 self.file_uploader.upload_files(files, self.attachments_elt) | |
227 self.message_input.focus() | |
228 | |
229 def on_attachment_delete(self, evt): | |
230 evt.stopPropagation() | |
231 target = evt.currentTarget | |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
232 item_elt = DOMNode(target.closest(".attachment-preview")) |
1536 | 233 item_elt.remove() |
234 | |
235 def on_attach_button_click(self, evt): | |
236 document["file_input"].click() | |
237 | |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
238 @bind(document["attachments"], "wheel") |
1536 | 239 def wheel_event(evt): |
240 """Make the mouse wheel to act on horizontal scrolling for attachments | |
241 | |
242 Attachments don't have vertical scrolling, thus is makes sense to use the wheel | |
243 for horizontal scrolling | |
244 """ | |
245 if evt.deltaY != 0: | |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
246 document["attachments"].scrollLeft += evt.deltaY * 0.8 |
1536 | 247 evt.preventDefault() |
248 | |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
249 def make_attachments_dynamic(self, parent_elt=None): |
1536 | 250 """Make attachments dynamically clickable""" |
251 # FIXME: only handle images for now, and display them in a modal | |
252 if parent_elt is None: | |
253 parent_elt = document | |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
254 img_elts = parent_elt.select(".message-attachment img") |
1536 | 255 for img_elt in img_elts: |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
256 img_elt.bind("click", self.open_modal) |
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
257 img_elt.style.cursor = "pointer" |
1536 | 258 |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
259 close_button = document.select_one(".modal-close") |
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
260 close_button.bind("click", self.close_modal) |
1536 | 261 |
1541
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
262 def find_links(self, message_elt): |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
263 """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
|
264 msg_body_elt = message_elt.select_one(".msg_body") |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
265 if not msg_body_elt: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
266 return |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
267 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
268 # Extracting links from text content |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
269 text = msg_body_elt.text |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
270 raw_urls = re.findall( |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
271 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
|
272 text, |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
273 ) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
274 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
275 # Extracting links from <a> elements |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
276 a_elements = msg_body_elt.select("a") |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
277 for a_elt in a_elements: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
278 href = a_elt.attrs.get("href", "") |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
279 if href.startswith("http://") or href.startswith("https://"): |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
280 raw_urls.append(href) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
281 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
282 # we remove duplicates |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
283 urls = list(dict.fromkeys(raw_urls)) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
284 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
285 return urls |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
286 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
287 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
|
288 """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
|
289 url_previews_elt.clear() |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
290 for url in urls: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
291 try: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
292 url_preview_data_s = await bridge.url_preview_get(url, "") |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
293 except Exception as e: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
294 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
|
295 continue |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
296 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
297 if not url_preview_data_s: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
298 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
|
299 continue |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
300 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
301 url_preview_data = json.loads(url_preview_data_s) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
302 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
303 url_preview_elt = self.url_preview_tpl.get_elt( |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
304 {"url_preview": url_preview_data} |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
305 ) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
306 url_previews_elt <= url_preview_elt |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
307 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
308 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
309 def handle_url_previews(self, parent_elt=None): |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
310 """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
|
311 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
312 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
|
313 user click, or directly the previews, or nothing at all. |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
314 """ |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
315 |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
316 if parent_elt is None: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
317 parent_elt = document |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
318 chat_message_elts = parent_elt.select(".is-chat-message") |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
319 else: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
320 chat_message_elts = [parent_elt] |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
321 for message_elt in chat_message_elts: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
322 urls = self.find_links(message_elt) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
323 if urls: |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
324 url_previews_elt = message_elt.select_one(".url-previews") |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
325 url_previews_elt.classList.remove("is-hidden") |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
326 preview_control_elt = self.url_preview_control_tpl.get_elt() |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
327 fetch_preview_btn = preview_control_elt.select_one(".action_fetch_preview") |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
328 fetch_preview_btn.bind( |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
329 "click", |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
330 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
|
331 self.add_url_previews(previews_elt, preview_urls) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
332 ) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
333 ) |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
334 url_previews_elt <= preview_control_elt |
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
335 |
1536 | 336 def open_modal(self, evt): |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
337 modal_image = document.select_one("#modal-image") |
1536 | 338 modal_image.src = evt.target.src |
339 modal_image.alt = evt.target.alt | |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
340 modal = document.select_one("#modal") |
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
341 modal.classList.add("is-active") |
1536 | 342 |
343 def close_modal(self, evt): | |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
344 modal = document.select_one("#modal") |
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
345 modal.classList.remove("is-active") |
1536 | 346 |
347 | |
1542
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
348 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
|
349 if ( |
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
350 document.visibilityState == "hidden" |
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
351 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
|
352 ): |
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
353 # 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
|
354 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
|
355 |
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
356 |
1536 | 357 libervia_web_chat = LiberviaWebChat() |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
358 |
1536 | 359 document["message_input"].bind( |
360 "input", lambda __: libervia_web_chat.auto_resize_message_input() | |
361 ) | |
362 document["message_input"].bind("keydown", libervia_web_chat.on_message_keydown) | |
363 document["send_button"].bind("click", lambda __: libervia_web_chat.send_message()) | |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
364 document["attach_button"].bind("click", libervia_web_chat.on_attach_button_click) |
1536 | 365 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
|
366 |
fb31d3dba0c3
browser (chat): add marker for new messages when page is not visible
Goffi <goffi@goffi.org>
parents:
1541
diff
changeset
|
367 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
|
368 |
1536 | 369 bridge.register_signal("message_new", libervia_web_chat._on_message_new) |
1540
b4342176fa0a
browser (chat): minor reformatting
Goffi <goffi@goffi.org>
parents:
1536
diff
changeset
|
370 |
1536 | 371 libervia_web_chat.make_attachments_dynamic() |
1541
3c384b51b2a1
browser (chat): URL previews implementation
Goffi <goffi@goffi.org>
parents:
1540
diff
changeset
|
372 libervia_web_chat.handle_url_previews() |