diff --git a/src/cheogram/java/com/cheogram/android/WebxdcPage.java b/src/cheogram/java/com/cheogram/android/WebxdcPage.java index d44b4b4fd30f18591fdac893fae4d6e8d53ac827..3847395cd891c47f56775473033636b371cafc03 100644 --- a/src/cheogram/java/com/cheogram/android/WebxdcPage.java +++ b/src/cheogram/java/com/cheogram/android/WebxdcPage.java @@ -5,8 +5,12 @@ package com.cheogram.android; import android.content.Context; import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.graphics.ImageDecoder; +import android.graphics.Rect; import android.net.Uri; import android.os.Build; +import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.Gravity; @@ -25,6 +29,8 @@ import androidx.annotation.RequiresApi; import androidx.core.content.ContextCompat; import androidx.databinding.DataBindingUtil; +import com.google.common.io.ByteStreams; + import io.ipfs.cid.Cid; import java.lang.ref.WeakReference; @@ -32,6 +38,7 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import java.util.zip.ZipEntry; @@ -48,6 +55,7 @@ import eu.siacs.conversations.R; import eu.siacs.conversations.databinding.WebxdcPageBinding; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.Consumer; import eu.siacs.conversations.utils.MimeUtils; @@ -85,6 +93,33 @@ public class WebxdcPage implements ConversationPage { baseUrl = "https://" + source.getUuid() + ".localhost"; } + public Drawable getIcon() { + if (android.os.Build.VERSION.SDK_INT < 28) return null; + ZipEntry entry = zip.getEntry("icon.webp"); + if (entry == null) entry = zip.getEntry("icon.png"); + if (entry == null) entry = zip.getEntry("icon.jpg"); + if (entry == null) return null; + + try { + DisplayMetrics metrics = xmppConnectionService.getResources().getDisplayMetrics(); + ImageDecoder.Source source = ImageDecoder.createSource(ByteBuffer.wrap(ByteStreams.toByteArray(zip.getInputStream(entry)))); + return ImageDecoder.decodeDrawable(source, (decoder, info, src) -> { + int w = info.getSize().getWidth(); + int h = info.getSize().getHeight(); + Rect r = FileBackend.rectForSize(w, h, (int)(metrics.density * 288)); + decoder.setTargetSize(r.width(), r.height()); + }); + } catch (final IOException e) { + Log.w(Config.LOGTAG, "WebxdcPage.getIcon: " + e); + return null; + } + } + + public String getName() { + String title = manifest == null ? null : manifest.getString("name"); + return title == null ? "ChatApp" : title; + } + public String getTitle() { String title = manifest == null ? null : manifest.getString("name"); if (lastUpdate != null && lastUpdate.getDocument() != null) { diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index ecb2e5de460f2bd116e83bfaf5c53b2c8dda0ac2..98767774cf7bbeb2854e084324bb481c1613ac7d 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -1309,8 +1309,8 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl pagerAdapter.refreshSessions(); } - public void startWebxdc(Cid cid, Message message, XmppConnectionService xmppConnectionService) { - pagerAdapter.startWebxdc(cid, message, xmppConnectionService); + public void startWebxdc(WebxdcPage page) { + pagerAdapter.startWebxdc(page); } public void startCommand(Element command, XmppConnectionService xmppConnectionService) { @@ -1423,9 +1423,9 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl } } - public void startWebxdc(Cid cid, Message message, XmppConnectionService xmppConnectionService) { + public void startWebxdc(WebxdcPage page) { show(); - sessions.add(new WebxdcPage(cid, message, xmppConnectionService)); + sessions.add(page); notifyDataSetChanged(); if (mPager != null) mPager.setCurrentItem(getCount() - 1); } 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 fa9b5645fd0baf5efcb057480b4d7d1e4d9879ed..0b25adf3c0e08500b8b9c1b40bd437a1a3976490 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -42,6 +42,7 @@ import androidx.core.content.res.ResourcesCompat; import com.cheogram.android.BobTransfer; import com.cheogram.android.SwipeDetector; +import com.cheogram.android.WebxdcPage; import com.cheogram.android.WebxdcUpdate; import com.google.common.base.Strings; @@ -675,25 +676,35 @@ public class MessageAdapter extends ArrayAdapter { } private void displayWebxdcMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground, final int type) { + WebxdcPage webxdc = new WebxdcPage(message.getFileParams().getCids().get(0), message, activity.xmppConnectionService); displayTextMessage(viewHolder, message, darkBackground, type); viewHolder.image.setVisibility(View.GONE); viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText("Open ChatApp"); + viewHolder.download_button.setText("Open " + webxdc.getName()); viewHolder.download_button.setOnClickListener(v -> { Conversation conversation = (Conversation) message.getConversation(); if (!conversation.switchToSession("webxdc\0" + message.getUuid())) { - conversation.startWebxdc(message.getFileParams().getCids().get(0), message, activity.xmppConnectionService); + conversation.startWebxdc(webxdc); } }); - WebxdcUpdate lastUpdate = activity.xmppConnectionService.findLastWebxdcUpdate(message); - if (lastUpdate != null && (lastUpdate.getSummary() != null || lastUpdate.getDocument() != null)) { - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setText( - (lastUpdate.getDocument() == null ? "" : lastUpdate.getDocument() + "\n") + - (lastUpdate.getSummary() == null ? "" : lastUpdate.getSummary()) - ); - } + new Thread(() -> { + Drawable icon = webxdc.getIcon(); + WebxdcUpdate lastUpdate = activity.xmppConnectionService.findLastWebxdcUpdate(message); + activity.runOnUiThread(() -> { + if (lastUpdate != null && (lastUpdate.getSummary() != null || lastUpdate.getDocument() != null)) { + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setText( + (lastUpdate.getDocument() == null ? "" : lastUpdate.getDocument() + "\n") + + (lastUpdate.getSummary() == null ? "" : lastUpdate.getSummary()) + ); + } + if (icon != null) { + viewHolder.image.setVisibility(View.VISIBLE); + viewHolder.image.setImageDrawable(icon); + } + }); + }).start(); } private void displayOpenableMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground, final int type) {