changeset 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 027fad764864
children d3a6ae859556
files cagou/plugins/plugin_wid_chat.kv cagou/plugins/plugin_wid_chat.py
diffstat 2 files changed, 59 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/cagou/plugins/plugin_wid_chat.kv	Wed Feb 26 16:43:48 2020 +0100
+++ b/cagou/plugins/plugin_wid_chat.kv	Wed Feb 26 16:47:39 2020 +0100
@@ -27,9 +27,12 @@
 # Chat
 
 
-<AttachmentItem>:
+<BaseAttachmentItem>:
     size_hint: None, None
     size: self.minimum_width, dp(50)
+
+
+<AttachmentItem>:
     canvas.before:
         Color:
             rgb: app.c_prim_dark
@@ -54,6 +57,16 @@
         on_press: root.on_press()
 
 
+<AttachmentImageItem>:
+    size: self.minimum_width, self.minimum_height
+    image: image
+    orientation: "vertical"
+    SizedImage:
+        id: image
+        source: root.data.get('url', root.data.get('path'))
+        anim_delay: -1
+
+
 <AttachmentsLayout>:
     attachments: self
     size_hint: 1, None
--- a/cagou/plugins/plugin_wid_chat.py	Wed Feb 26 16:43:48 2020 +0100
+++ b/cagou/plugins/plugin_wid_chat.py	Wed Feb 26 16:47:39 2020 +0100
@@ -21,6 +21,7 @@
 from pathlib import Path
 import sys
 import uuid
+from urllib.parse import urlparse
 from kivy.uix.boxlayout import BoxLayout
 from kivy.uix.textinput import TextInput
 from kivy.uix.screenmanager import Screen, NoTransition
@@ -44,10 +45,10 @@
 from ..core import cagou_widget
 from ..core import xmlui
 from ..core.image import Image
-from ..core.common import SymbolButton, JidButton
+from ..core.common import SymbolButton, JidButton, ContactButton
 from ..core.behaviors import FilterBehavior
 from ..core import menu
-from ..core.common import ContactButton
+from ..core.common_widgets import ImagesGallery
 
 log = logging.getLogger(__name__)
 
@@ -94,10 +95,13 @@
     attachments = properties.ObjectProperty()
 
 
-class AttachmentItem(BoxLayout):
+class BaseAttachmentItem(BoxLayout):
     data = properties.DictProperty()
     progress = properties.NumericProperty(0)
 
+
+class AttachmentItem(BaseAttachmentItem):
+
     def get_symbol(self, data):
         media_type = data.get(C.MESS_KEY_MEDIA_TYPE, '')
         main_type = media_type.split('/', 1)[0]
@@ -118,6 +122,14 @@
             log.warning(f"can't find URL in {self.data}")
 
 
+class AttachmentImageItem(ButtonBehavior, BaseAttachmentItem):
+    image = properties.ObjectProperty()
+
+    def on_press(self):
+        gallery = ImagesGallery(sources=[self.image.source])
+        G.host.showExtraUI(gallery)
+
+
 class AttachmentToSendItem(AttachmentItem):
     # True when the item is being sent
     sending = properties.BooleanProperty(False)
@@ -197,6 +209,10 @@
             status = update_dict['status']
             self.delivery.text =  '\u2714' if status == 'delivered' else ''
 
+    def _setPath(self, item, path):
+        """Set path of decrypted file to an item"""
+        item.data['path'] = path
+
     def add_attachments(self):
         """Add attachments layout + attachments item"""
         attachments = self.mess_data.attachments
@@ -206,7 +222,32 @@
         self.right_part.add_widget(root_layout)
         layout = root_layout.attachments
         for attachment in attachments:
-            item = AttachmentItem(data=attachment)
+            media_type = attachment.get(C.MESS_KEY_MEDIA_TYPE, '')
+            main_type = media_type.split('/', 1)[0]
+            if ((main_type == 'image'
+                 # GIF images are really badly handled by Kivy, the
+                 # memory consumption explode, and the images frequencies
+                 # are not handled correctly, thus we can't display them
+                 # and user will have to open the item.
+                 and media_type != "image/gif"
+                 and (self.mess_data.own_mess or self.chat.contact_list.isInRoster(
+                    self.mess_data.from_jid)))):
+                url = urlparse(attachment['url'])
+                if url.scheme == "aesgcm":
+                    # we remove the URL now, we'll replace it by
+                    # the local decrypted version
+                    del attachment['url']
+                    item = AttachmentImageItem(data=attachment)
+                    G.host.downloadURL(
+                        url.geturl(),
+                        callback=partial(self._setPath, item),
+                        dest=C.FILE_DEST_CACHE,
+                        profile=self.chat.profile,
+                    )
+                else:
+                    item = AttachmentImageItem(data=attachment)
+            else:
+                item = AttachmentItem(data=attachment)
             layout.add_widget(item)