Mercurial > libervia-desktop-kivy
comparison cagou/plugins/plugin_wid_chat.py @ 425:13884aac1220
chat: show images in attachments:
- if an image is received from somebody in roster, it is automatically displayed (we
display only for people in roster to avoid IP address leak)
- encrypted files are decrypted and stored in cache before being displayed
- GIFs image are shown as attachment because they are badly handle in Kivy (images
frequencies is not handled correctly, and memory consumption explode). Instead, a click
on it will open the GIF in the appropriate software of the platform.
- a click on an attachment image will open it in the gallery
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 26 Feb 2020 16:47:39 +0100 |
parents | 8a9bfe3fb9c6 |
children | d3a6ae859556 |
comparison
equal
deleted
inserted
replaced
424:027fad764864 | 425:13884aac1220 |
---|---|
19 | 19 |
20 from functools import partial | 20 from functools import partial |
21 from pathlib import Path | 21 from pathlib import Path |
22 import sys | 22 import sys |
23 import uuid | 23 import uuid |
24 from urllib.parse import urlparse | |
24 from kivy.uix.boxlayout import BoxLayout | 25 from kivy.uix.boxlayout import BoxLayout |
25 from kivy.uix.textinput import TextInput | 26 from kivy.uix.textinput import TextInput |
26 from kivy.uix.screenmanager import Screen, NoTransition | 27 from kivy.uix.screenmanager import Screen, NoTransition |
27 from kivy.uix import screenmanager | 28 from kivy.uix import screenmanager |
28 from kivy.uix.behaviors import ButtonBehavior | 29 from kivy.uix.behaviors import ButtonBehavior |
42 from cagou import G | 43 from cagou import G |
43 from ..core.constants import Const as C | 44 from ..core.constants import Const as C |
44 from ..core import cagou_widget | 45 from ..core import cagou_widget |
45 from ..core import xmlui | 46 from ..core import xmlui |
46 from ..core.image import Image | 47 from ..core.image import Image |
47 from ..core.common import SymbolButton, JidButton | 48 from ..core.common import SymbolButton, JidButton, ContactButton |
48 from ..core.behaviors import FilterBehavior | 49 from ..core.behaviors import FilterBehavior |
49 from ..core import menu | 50 from ..core import menu |
50 from ..core.common import ContactButton | 51 from ..core.common_widgets import ImagesGallery |
51 | 52 |
52 log = logging.getLogger(__name__) | 53 log = logging.getLogger(__name__) |
53 | 54 |
54 PLUGIN_INFO = { | 55 PLUGIN_INFO = { |
55 "name": _("chat"), | 56 "name": _("chat"), |
92 class AttachmentsToSend(BoxLayout): | 93 class AttachmentsToSend(BoxLayout): |
93 """Layout for attachments to be sent with current message""" | 94 """Layout for attachments to be sent with current message""" |
94 attachments = properties.ObjectProperty() | 95 attachments = properties.ObjectProperty() |
95 | 96 |
96 | 97 |
97 class AttachmentItem(BoxLayout): | 98 class BaseAttachmentItem(BoxLayout): |
98 data = properties.DictProperty() | 99 data = properties.DictProperty() |
99 progress = properties.NumericProperty(0) | 100 progress = properties.NumericProperty(0) |
101 | |
102 | |
103 class AttachmentItem(BaseAttachmentItem): | |
100 | 104 |
101 def get_symbol(self, data): | 105 def get_symbol(self, data): |
102 media_type = data.get(C.MESS_KEY_MEDIA_TYPE, '') | 106 media_type = data.get(C.MESS_KEY_MEDIA_TYPE, '') |
103 main_type = media_type.split('/', 1)[0] | 107 main_type = media_type.split('/', 1)[0] |
104 if main_type == 'image': | 108 if main_type == 'image': |
114 url = self.data.get('url') | 118 url = self.data.get('url') |
115 if url: | 119 if url: |
116 G.local_platform.open_url(url, self) | 120 G.local_platform.open_url(url, self) |
117 else: | 121 else: |
118 log.warning(f"can't find URL in {self.data}") | 122 log.warning(f"can't find URL in {self.data}") |
123 | |
124 | |
125 class AttachmentImageItem(ButtonBehavior, BaseAttachmentItem): | |
126 image = properties.ObjectProperty() | |
127 | |
128 def on_press(self): | |
129 gallery = ImagesGallery(sources=[self.image.source]) | |
130 G.host.showExtraUI(gallery) | |
119 | 131 |
120 | 132 |
121 class AttachmentToSendItem(AttachmentItem): | 133 class AttachmentToSendItem(AttachmentItem): |
122 # True when the item is being sent | 134 # True when the item is being sent |
123 sending = properties.BooleanProperty(False) | 135 sending = properties.BooleanProperty(False) |
195 self.avatar.source = update_dict['avatar'] | 207 self.avatar.source = update_dict['avatar'] |
196 if 'status' in update_dict: | 208 if 'status' in update_dict: |
197 status = update_dict['status'] | 209 status = update_dict['status'] |
198 self.delivery.text = '\u2714' if status == 'delivered' else '' | 210 self.delivery.text = '\u2714' if status == 'delivered' else '' |
199 | 211 |
212 def _setPath(self, item, path): | |
213 """Set path of decrypted file to an item""" | |
214 item.data['path'] = path | |
215 | |
200 def add_attachments(self): | 216 def add_attachments(self): |
201 """Add attachments layout + attachments item""" | 217 """Add attachments layout + attachments item""" |
202 attachments = self.mess_data.attachments | 218 attachments = self.mess_data.attachments |
203 if not attachments: | 219 if not attachments: |
204 return | 220 return |
205 root_layout = AttachmentsLayout() | 221 root_layout = AttachmentsLayout() |
206 self.right_part.add_widget(root_layout) | 222 self.right_part.add_widget(root_layout) |
207 layout = root_layout.attachments | 223 layout = root_layout.attachments |
208 for attachment in attachments: | 224 for attachment in attachments: |
209 item = AttachmentItem(data=attachment) | 225 media_type = attachment.get(C.MESS_KEY_MEDIA_TYPE, '') |
226 main_type = media_type.split('/', 1)[0] | |
227 if ((main_type == 'image' | |
228 # GIF images are really badly handled by Kivy, the | |
229 # memory consumption explode, and the images frequencies | |
230 # are not handled correctly, thus we can't display them | |
231 # and user will have to open the item. | |
232 and media_type != "image/gif" | |
233 and (self.mess_data.own_mess or self.chat.contact_list.isInRoster( | |
234 self.mess_data.from_jid)))): | |
235 url = urlparse(attachment['url']) | |
236 if url.scheme == "aesgcm": | |
237 # we remove the URL now, we'll replace it by | |
238 # the local decrypted version | |
239 del attachment['url'] | |
240 item = AttachmentImageItem(data=attachment) | |
241 G.host.downloadURL( | |
242 url.geturl(), | |
243 callback=partial(self._setPath, item), | |
244 dest=C.FILE_DEST_CACHE, | |
245 profile=self.chat.profile, | |
246 ) | |
247 else: | |
248 item = AttachmentImageItem(data=attachment) | |
249 else: | |
250 item = AttachmentItem(data=attachment) | |
210 layout.add_widget(item) | 251 layout.add_widget(item) |
211 | 252 |
212 | 253 |
213 class MessageInputBox(BoxLayout): | 254 class MessageInputBox(BoxLayout): |
214 message_input = properties.ObjectProperty() | 255 message_input = properties.ObjectProperty() |