diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 7dd89d718bfe58c37760affb3c53678df12d3aa5..3063b6b033581be7995bc5d593182e788fb7ae3f 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -55,11 +55,13 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; +import java.nio.ByteBuffer; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Locale; @@ -1039,7 +1041,46 @@ public class FileBackend { } public Drawable getThumbnail(Message message, Resources res, int size, boolean cacheOnly) throws IOException { - return getThumbnail(getFile(message), res, size, cacheOnly); + final LruCache cache = mXmppConnectionService.getDrawableCache(); + DownloadableFile file = getFile(message); + Drawable thumbnail = cache.get(file.getAbsolutePath()); + if (thumbnail != null) return thumbnail; + + if ((thumbnail == null) && (!cacheOnly)) { + synchronized (THUMBNAIL_LOCK) { + List thumbs = message.getFileParams() != null ? message.getFileParams().getThumbnails() : null; + if (thumbs != null && !thumbs.isEmpty()) { + for (Element thumb : thumbs) { + Uri uri = Uri.parse(thumb.getAttribute("uri")); + if (uri.getScheme().equals("data")) { + if (android.os.Build.VERSION.SDK_INT < 28) continue; + String[] parts = uri.getSchemeSpecificPart().split(",", 2); + byte[] data; + if (Arrays.asList(parts[0].split(";")).contains("base64")) { + data = Base64.decode(parts[1], 0); + } else { + data = parts[1].getBytes("UTF-8"); + } + + ImageDecoder.Source source = ImageDecoder.createSource(ByteBuffer.wrap(data)); + thumbnail = ImageDecoder.decodeDrawable(source, (decoder, info, src) -> { + int w = info.getSize().getWidth(); + int h = info.getSize().getHeight(); + Rect r = rectForSize(w, h, size); + decoder.setTargetSize(r.width(), r.height()); + }); + + if (thumbnail != null) { + cache.put(file.getAbsolutePath(), thumbnail); + return thumbnail; + } + } + } + } + } + } + + return getThumbnail(file, res, size, cacheOnly); } public Drawable getThumbnail(DownloadableFile file, Resources res, int size, boolean cacheOnly) throws IOException { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index ebe612059c228fcef8d61115fef7570236d531ad..54f2c7ad07e2431814760f8b0c1db59dc3156709 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -600,7 +600,7 @@ public class MessageAdapter extends ArrayAdapter { if (uri.getScheme().equals("data")) { String[] parts = uri.getSchemeSpecificPart().split(",", 2); parts = parts[0].split(";"); - if (!parts[0].equals("image/blurhash")) continue; + if (!parts[0].equals("image/blurhash") && !parts[0].equals("image/jpeg") && !parts[0].equals("image/png") && !parts[0].equals("image/webp") && !parts[0].equals("image/gif")) continue; } else { continue; }