Show inline images

Resf #49
This commit is contained in:
M66B
2018-09-13 17:03:28 +00:00
parent cdb745d0b7
commit fd65310f22
8 changed files with 1016 additions and 6 deletions

View File

@@ -119,7 +119,7 @@ public class AdapterAttachment extends RecyclerView.Adapter<AdapterAttachment.Vi
progressbar.setVisibility(
attachment.progress == null || attachment.available ? View.GONE : View.VISIBLE);
tvType.setText(attachment.type);
tvType.setText(attachment.type + " " + attachment.cid);
tvType.setVisibility(debug ? View.VISIBLE : View.GONE);
}

View File

@@ -45,7 +45,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
version = 14,
version = 15,
entities = {
EntityIdentity.class,
EntityAccount.class,
@@ -213,6 +213,14 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `account` ADD COLUMN `color` INTEGER");
}
})
.addMigrations(new Migration(14, 15) {
@Override
public void migrate(SupportSQLiteDatabase db) {
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `attachment` ADD COLUMN `cid` TEXT");
db.execSQL("CREATE UNIQUE INDEX `index_attachment_message_cid` ON `attachment` (`message`, `cid`)");
}
})
.build();
}

View File

@@ -54,6 +54,11 @@ public interface DaoAttachment {
" AND sequence = :sequence")
EntityAttachment getAttachment(long message, int sequence);
@Query("SELECT * FROM attachment" +
" WHERE message = :message" +
" AND cid = :cid")
EntityAttachment getAttachment(long message, String cid);
@Query("SELECT * FROM attachment" +
" WHERE id = :id")
EntityAttachment getAttachment(long id);

View File

@@ -41,7 +41,8 @@ import static androidx.room.ForeignKey.CASCADE;
},
indices = {
@Index(value = {"message"}),
@Index(value = {"message", "sequence"}, unique = true)
@Index(value = {"message", "sequence"}, unique = true),
@Index(value = {"message", "cid"}, unique = true)
}
)
public class EntityAttachment {
@@ -56,7 +57,9 @@ public class EntityAttachment {
public String name;
@NonNull
public String type;
public String cid; // Content-ID
public Integer size;
public Integer progress;
@NonNull
public Boolean available = false;

View File

@@ -135,6 +135,7 @@ public class FragmentMessage extends FragmentEx {
private TupleMessageEx message = null;
private boolean free = false;
private boolean addresses = false;
private boolean show_images = false;
private boolean headers = false;
private AdapterAttachment adapter;
@@ -443,6 +444,7 @@ public class FragmentMessage extends FragmentEx {
outState.putBoolean("free", free);
outState.putBoolean("headers", headers);
outState.putBoolean("addresses", addresses);
outState.putBoolean("show_images", show_images);
}
@Override
@@ -470,13 +472,14 @@ public class FragmentMessage extends FragmentEx {
free = savedInstanceState.getBoolean("free");
headers = savedInstanceState.getBoolean("headers");
addresses = savedInstanceState.getBoolean("addresses");
show_images = savedInstanceState.getBoolean("show_images");
}
if (tvBody.getTag() == null) {
// Spanned text needs to be loaded after recreation too
final Bundle args = new Bundle();
args.putLong("id", message.id);
args.putBoolean("show_images", false);
args.putBoolean("show_images", show_images);
pbBody.setVisibility(View.VISIBLE);
@@ -486,7 +489,8 @@ public class FragmentMessage extends FragmentEx {
@Override
public void onClick(View v) {
v.setEnabled(false);
args.putBoolean("show_images", true);
show_images = true;
args.putBoolean("show_images", show_images);
bodyTask.load(FragmentMessage.this, args);
}
});
@@ -606,6 +610,14 @@ public class FragmentMessage extends FragmentEx {
adapter.set(attachments);
grpAttachments.setVisibility(!free && attachments.size() > 0 ? View.VISIBLE : View.GONE);
Bundle args = new Bundle();
args.putLong("id", message.id);
args.putBoolean("show_images", show_images);
pbBody.setVisibility(View.VISIBLE);
bodyTask.load(FragmentMessage.this, args);
}
});
@@ -1153,6 +1165,21 @@ public class FragmentMessage extends FragmentEx {
float scale = context.getResources().getDisplayMetrics().density;
int px = (int) (24 * scale + 0.5f);
if (source != null && source.startsWith("cid")) {
String cid = "<" + source.split(":")[1] + ">";
EntityAttachment attachment = DB.getInstance(context).attachment().getAttachment(id, cid);
if (attachment == null || !attachment.available) {
Drawable d = context.getResources().getDrawable(R.drawable.baseline_warning_24, context.getTheme());
d.setBounds(0, 0, px, px);
return d;
} else {
File file = EntityAttachment.getFile(context, attachment.id);
Drawable d = Drawable.createFromPath(file.getAbsolutePath());
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
return d;
}
}
if (show_images) {
// Get cache folder
File dir = new File(context.getCacheDir(), "images");

View File

@@ -35,7 +35,7 @@ public class HtmlHelper {
private static Pattern pattern = Pattern.compile("([http|https]+://[\\w\\S(\\.|:|/)]+)");
public static String sanitize(String html) {
Document document = Jsoup.parse(Jsoup.clean(html, Whitelist.relaxed()));
Document document = Jsoup.parse(Jsoup.clean(html, Whitelist.relaxed().addProtocols("img", "src", "cid")));
for (Element tr : document.select("tr"))
tr.after("<br>");
NodeTraversor.traverse(new NodeVisitor() {

View File

@@ -415,10 +415,13 @@ public class MessageHelper {
if (Part.ATTACHMENT.equalsIgnoreCase(disposition) || !TextUtils.isEmpty(filename)) {
ContentType ct = new ContentType(part.getContentType());
String[] cid = part.getHeader("Content-ID");
EntityAttachment attachment = new EntityAttachment();
attachment.name = filename;
attachment.type = ct.getBaseType();
attachment.size = part.getSize();
attachment.cid = (cid == null || cid.length == 0 ? null : cid[0]);
attachment.part = part;
// Try to guess a better content type