From 31831558be9b7f5e97e441208a0610d2cfe15e05 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Wed, 10 May 2023 13:09:51 -0500 Subject: [PATCH] Initial support for XEP-0221 Works for images delivered over https only --- cheogram.doap | 8 ++++ .../res/layout/command_result_field.xml | 13 ++++++ .../conversations/entities/Conversation.java | 43 ++++++++++++++++++- .../http/HttpConnectionManager.java | 8 +++- .../http/HttpDownloadConnection.java | 14 ++++-- .../persistance/FileBackend.java | 10 +++-- 6 files changed, 88 insertions(+), 8 deletions(-) diff --git a/cheogram.doap b/cheogram.doap index 3fee25647958aa8c2501c79309bbacb64c2123e7..eedab8e480f702210399212a2d171c5557a769fb 100644 --- a/cheogram.doap +++ b/cheogram.doap @@ -60,6 +60,14 @@ + + + + partial + 1.0 + When used with XEP-0050, images over HTTPS only + + diff --git a/src/cheogram/res/layout/command_result_field.xml b/src/cheogram/res/layout/command_result_field.xml index 47b8c7b327739f307308dcb8b591160786dcee44..580e03781cf21ead231bf94d747e6bbefdb17b23 100644 --- a/src/cheogram/res/layout/command_result_field.xml +++ b/src/cheogram/res/layout/command_result_field.xml @@ -16,6 +16,19 @@ android:paddingBottom="4dp" android:textAppearance="@style/TextAppearance.Conversations.Caption" /> + + cache = xmppConnectionService.getDrawableCache(); + final HttpConnectionManager httpManager = xmppConnectionService.getHttpConnectionManager(); + for (Element uriEl : media.getChildren()) { + if (!"uri".equals(uriEl.getName())) continue; + if (!"urn:xmpp:media-element".equals(uriEl.getNamespace())) continue; + String mimeType = uriEl.getAttribute("type"); + String uriS = uriEl.getContent(); + if (mimeType == null || uriS == null) continue; + Uri uri = Uri.parse(uriS); + if (mimeType.startsWith("image/") && "https".equals(uri.getScheme())) { + final Drawable d = cache.get(uri.toString()); + if (d == null) { + int size = (int)(xmppConnectionService.getResources().getDisplayMetrics().density * 288); + Message dummy = new Message(Conversation.this, uri.toString(), Message.ENCRYPTION_NONE); + dummy.setFileParams(new Message.FileParams(uri.toString())); + httpManager.createNewDownloadConnection(dummy, true, (file) -> { + if (file == null) { + dummy.getTransferable().start(); + } else { + try { + xmppConnectionService.getFileBackend().getThumbnail(file, xmppConnectionService.getResources(), size, false, uri.toString()); + } catch (final Exception e) { } + } + }); + } else { + binding.mediaImage.setImageDrawable(d); + binding.mediaImage.setVisibility(View.VISIBLE); + } + } + } + } + Element validate = field.el.findChild("validate", "http://jabber.org/protocol/xdata-validate"); String datatype = validate == null ? null : validate.getAttribute("datatype"); @@ -2987,7 +3026,9 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl return false; } - public void refresh() { } + public void refresh() { + notifyDataSetChanged(); + } protected void loading() { View v = getView(); diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java index 912728f65c6d2495dfd6e839fe2c939250fec86c..ad62d9aee7e46170f5b1bd49aa5efcbc308b4581 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java @@ -27,9 +27,11 @@ import javax.net.ssl.X509TrustManager; import eu.siacs.conversations.BuildConfig; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.Consumer; import eu.siacs.conversations.utils.TLSSocketFactory; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; @@ -85,6 +87,10 @@ public class HttpConnectionManager extends AbstractConnectionManager { } public void createNewDownloadConnection(final Message message, boolean interactive) { + createNewDownloadConnection(message, interactive, null); + } + + public void createNewDownloadConnection(final Message message, boolean interactive, Consumer cb) { synchronized (this.downloadConnections) { for (HttpDownloadConnection connection : this.downloadConnections) { if (connection.getMessage() == message) { @@ -92,7 +98,7 @@ public class HttpConnectionManager extends AbstractConnectionManager { return; } } - final HttpDownloadConnection connection = new HttpDownloadConnection(message, this); + final HttpDownloadConnection connection = new HttpDownloadConnection(message, this, cb); connection.init(interactive); this.downloadConnections.add(connection); } diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index 29e7fc3fca2bd75f42b49c2617c1c693b9bc2bcf..34fe6d078b7d8d9f106bdc02664b181ee1f5bf2a 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -24,6 +24,7 @@ import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.Consumer; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.FileWriterException; import eu.siacs.conversations.utils.MimeUtils; @@ -46,11 +47,13 @@ public class HttpDownloadConnection implements Transferable { private boolean acceptedAutomatically = false; private int mProgress = 0; private Call mostRecentCall; + final private Consumer cb; - HttpDownloadConnection(Message message, HttpConnectionManager manager) { + HttpDownloadConnection(Message message, HttpConnectionManager manager, Consumer cb) { this.message = message; this.mHttpConnectionManager = manager; this.mXmppConnectionService = manager.getXmppConnectionService(); + this.cb = cb; } @Override @@ -188,7 +191,7 @@ public class HttpDownloadConnection implements Transferable { } private void finish() { - boolean notify = acceptedAutomatically && !message.isRead(); + boolean notify = acceptedAutomatically && !message.isRead() && cb == null; if (message.getEncryption() == Message.ENCRYPTION_PGP) { notify = message.getConversation().getAccount().getPgpDecryptionService().decrypt(message, notify); } @@ -210,6 +213,7 @@ public class HttpDownloadConnection implements Transferable { message.setDeleted(true); } message.setTransferable(null); + cb.accept(file); mXmppConnectionService.updateMessage(message); mHttpConnectionManager.finishConnection(this); final boolean notifyAfterScan = notify; @@ -325,7 +329,11 @@ public class HttpDownloadConnection implements Transferable { } else { changeStatus(STATUS_OFFER); HttpDownloadConnection.this.acceptedAutomatically = false; - HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message); + if (cb == null) { + HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message); + } else { + cb.accept(null); + } } } diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 318c5a2f1eb9bc2d33e4e6a0af7437e0e1f071fe..8b0557dbd4feae1dd3941bec717ee79556beb00e 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -1164,11 +1164,15 @@ public class FileBackend { } public Drawable getThumbnail(DownloadableFile file, Resources res, int size, boolean cacheOnly) throws IOException { + return getThumbnail(file, res, size, cacheOnly, file.getAbsolutePath()); + } + + public Drawable getThumbnail(DownloadableFile file, Resources res, int size, boolean cacheOnly, String cacheKey) throws IOException { final LruCache cache = mXmppConnectionService.getDrawableCache(); - Drawable thumbnail = cache.get(file.getAbsolutePath()); + Drawable thumbnail = cache.get(cacheKey); if ((thumbnail == null) && (!cacheOnly)) { synchronized (THUMBNAIL_LOCK) { - thumbnail = cache.get(file.getAbsolutePath()); + thumbnail = cache.get(cacheKey); if (thumbnail != null) { return thumbnail; } @@ -1183,7 +1187,7 @@ public class FileBackend { throw new FileNotFoundException(); } } - cache.put(file.getAbsolutePath(), thumbnail); + cache.put(cacheKey, thumbnail); } } return thumbnail;