mirror of
https://github.com/M66B/FairEmail.git
synced 2026-01-04 11:54:10 +01:00
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user