diff --git a/cheogram.doap b/cheogram.doap index 3fee25647..eedab8e48 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 47b8c7b32..580e03781 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 912728f65..ad62d9aee 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 29e7fc3fc..34fe6d078 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 318c5a2f1..8b0557dbd 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;