Fixed image sizing

pull/162/head
M66B 6 years ago
parent e097a01922
commit 2d917e21ab

@ -1419,179 +1419,185 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
wvBody.setVisibility(View.GONE); wvBody.setVisibility(View.GONE);
} }
Bundle args = new Bundle(); final Bundle args = new Bundle();
args.putSerializable("message", message); args.putSerializable("message", message);
args.putBoolean("show_images", show_images); args.putBoolean("show_images", show_images);
args.putBoolean("show_full", show_full); args.putBoolean("show_full", show_full);
args.putBoolean("show_quotes", show_quotes); args.putBoolean("show_quotes", show_quotes);
args.putInt("zoom", zoom); args.putInt("zoom", zoom);
new SimpleTask<Object>() { // Run task after measure
new Handler().post(new Runnable() {
@Override @Override
protected Object onExecute(final Context context, final Bundle args) throws IOException { public void run() {
TupleMessageEx message = (TupleMessageEx) args.getSerializable("message"); new SimpleTask<Object>() {
boolean show_full = args.getBoolean("show_full"); @Override
boolean show_images = args.getBoolean("show_images"); protected Object onExecute(final Context context, final Bundle args) throws IOException {
boolean show_quotes = args.getBoolean("show_quotes"); TupleMessageEx message = (TupleMessageEx) args.getSerializable("message");
int zoom = args.getInt("zoom"); boolean show_full = args.getBoolean("show_full");
boolean show_images = args.getBoolean("show_images");
if (message == null || !message.content) boolean show_quotes = args.getBoolean("show_quotes");
return null; int zoom = args.getInt("zoom");
if (message == null || !message.content)
return null;
File file = message.getFile(context); File file = message.getFile(context);
if (!file.exists()) if (!file.exists())
return null; return null;
String body = Helper.readText(file); String body = Helper.readText(file);
Document document = JsoupEx.parse(body); Document document = JsoupEx.parse(body);
// Check for inline encryption // Check for inline encryption
int begin = body.indexOf(Helper.PGP_BEGIN_MESSAGE); int begin = body.indexOf(Helper.PGP_BEGIN_MESSAGE);
int end = body.indexOf(Helper.PGP_END_MESSAGE); int end = body.indexOf(Helper.PGP_END_MESSAGE);
args.putBoolean("iencrypted", begin >= 0 && begin < end); args.putBoolean("iencrypted", begin >= 0 && begin < end);
// Check for images // Check for images
boolean has_images = false; boolean has_images = false;
for (Element img : document.select("img")) { for (Element img : document.select("img")) {
if (inline) { if (inline) {
String src = img.attr("src"); String src = img.attr("src");
if (!src.startsWith("cid:")) { if (!src.startsWith("cid:")) {
has_images = true; has_images = true;
break; break;
}
} else {
has_images = true;
break;
}
} }
} else { args.putBoolean("has_images", has_images);
has_images = true;
break; if (show_full) {
} HtmlHelper.removeViewportLimitations(document);
} if (inline || show_images)
args.putBoolean("has_images", has_images); HtmlHelper.embedInlineImages(context, message.id, document);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean disable_tracking = prefs.getBoolean("disable_tracking", true);
if (disable_tracking)
HtmlHelper.removeTrackingPixels(context, document);
if (debug) {
Document format = JsoupEx.parse(document.html());
format.outputSettings().prettyPrint(true).outline(true).indentAmount(1);
Element pre = document.createElement("pre");
pre.text(format.html());
document.body().appendChild(pre);
}
if (show_full) { return document.html();
HtmlHelper.removeViewportLimitations(document); } else {
if (inline || show_images) // Collapse quotes
HtmlHelper.embedInlineImages(context, message.id, document); if (!show_quotes) {
for (Element quote : document.select("blockquote"))
quote.html("&#8230;");
body = document.html();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); // Cleanup message
boolean disable_tracking = prefs.getBoolean("disable_tracking", true); String html = HtmlHelper.sanitize(context, body, show_images);
if (disable_tracking) if (debug) {
HtmlHelper.removeTrackingPixels(context, document); Document format = JsoupEx.parse(html);
format.outputSettings().prettyPrint(true).outline(true).indentAmount(1);
if (debug) { String[] lines = format.html().split("\\r?\\n");
Document format = JsoupEx.parse(document.html()); for (int i = 0; i < lines.length; i++)
format.outputSettings().prettyPrint(true).outline(true).indentAmount(1); lines[i] = Html.escapeHtml(lines[i]);
Element pre = document.createElement("pre"); html += "<pre>" + TextUtils.join("<br>", lines) + "</pre>";
pre.text(format.html()); }
document.body().appendChild(pre);
}
return document.html(); Spanned spanned = HtmlHelper.fromHtml(html, new Html.ImageGetter() {
} else { @Override
// Collapse quotes public Drawable getDrawable(String source) {
if (!show_quotes) { Drawable drawable = ImageHelper.decodeImage(context, message.id, source, show_images, tvBody);
for (Element quote : document.select("blockquote"))
quote.html("&#8230;");
body = document.html();
}
// Cleanup message if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
String html = HtmlHelper.sanitize(context, body, show_images); if (drawable instanceof AnimatedImageDrawable)
if (debug) { ((AnimatedImageDrawable) drawable).start();
Document format = JsoupEx.parse(html); }
format.outputSettings().prettyPrint(true).outline(true).indentAmount(1);
String[] lines = format.html().split("\\r?\\n");
for (int i = 0; i < lines.length; i++)
lines[i] = Html.escapeHtml(lines[i]);
html += "<pre>" + TextUtils.join("<br>", lines) + "</pre>";
}
Spanned spanned = HtmlHelper.fromHtml(html, new Html.ImageGetter() { return drawable;
@Override }
public Drawable getDrawable(String source) { }, null);
Drawable drawable = ImageHelper.decodeImage(context, message.id, source, show_images, tvBody);
// Replace quote spans
SpannableStringBuilder builder = new SpannableStringBuilder(spanned);
QuoteSpan[] quoteSpans = builder.getSpans(0, builder.length(), QuoteSpan.class);
for (QuoteSpan quoteSpan : quoteSpans) {
builder.setSpan(
new StyledQuoteSpan(context, colorPrimary),
builder.getSpanStart(quoteSpan),
builder.getSpanEnd(quoteSpan),
builder.getSpanFlags(quoteSpan));
builder.removeSpan(quoteSpan);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { // Make collapsed quotes clickable
if (drawable instanceof AnimatedImageDrawable) if (!show_quotes) {
((AnimatedImageDrawable) drawable).start(); final int px = Helper.dp2pixels(context, 24 + (zoom) * 8);
StyledQuoteSpan[] squotes = builder.getSpans(0, builder.length(), StyledQuoteSpan.class);
for (StyledQuoteSpan squote : squotes)
builder.setSpan(new DynamicDrawableSpan() {
@Override
public Drawable getDrawable() {
Drawable d = context.getDrawable(R.drawable.baseline_format_quote_24);
d.setTint(colorAccent);
d.setBounds(0, 0, px, px);
return d;
}
},
builder.getSpanStart(squote),
builder.getSpanEnd(squote),
builder.getSpanFlags(squote));
} }
return drawable; return builder;
} }
}, null);
// Replace quote spans
SpannableStringBuilder builder = new SpannableStringBuilder(spanned);
QuoteSpan[] quoteSpans = builder.getSpans(0, builder.length(), QuoteSpan.class);
for (QuoteSpan quoteSpan : quoteSpans) {
builder.setSpan(
new StyledQuoteSpan(context, colorPrimary),
builder.getSpanStart(quoteSpan),
builder.getSpanEnd(quoteSpan),
builder.getSpanFlags(quoteSpan));
builder.removeSpan(quoteSpan);
}
// Make collapsed quotes clickable
if (!show_quotes) {
final int px = Helper.dp2pixels(context, 24 + (zoom) * 8);
StyledQuoteSpan[] squotes = builder.getSpans(0, builder.length(), StyledQuoteSpan.class);
for (StyledQuoteSpan squote : squotes)
builder.setSpan(new DynamicDrawableSpan() {
@Override
public Drawable getDrawable() {
Drawable d = context.getDrawable(R.drawable.baseline_format_quote_24);
d.setTint(colorAccent);
d.setBounds(0, 0, px, px);
return d;
}
},
builder.getSpanStart(squote),
builder.getSpanEnd(squote),
builder.getSpanFlags(squote));
} }
return builder; @Override
} protected void onExecuted(Bundle args, Object result) {
} TupleMessageEx message = (TupleMessageEx) args.getSerializable("message");
properties.setValue("iencrypted", message.id, args.getBoolean("iencrypted"));
@Override
protected void onExecuted(Bundle args, Object result) {
TupleMessageEx message = (TupleMessageEx) args.getSerializable("message");
properties.setValue("iencrypted", message.id, args.getBoolean("iencrypted"));
TupleMessageEx amessage = getMessage(); TupleMessageEx amessage = getMessage();
if (amessage == null || !amessage.id.equals(message.id)) if (amessage == null || !amessage.id.equals(message.id))
return; return;
boolean show_expanded = properties.getValue("expanded", message.id); boolean show_expanded = properties.getValue("expanded", message.id);
if (!show_expanded) if (!show_expanded)
return; return;
boolean has_images = args.getBoolean("has_images"); boolean has_images = args.getBoolean("has_images");
boolean show_images = properties.getValue("images", message.id); boolean show_images = properties.getValue("images", message.id);
if (result instanceof Spanned) { if (result instanceof Spanned) {
tvBody.setText((Spanned) result); tvBody.setText((Spanned) result);
tvBody.setTextIsSelectable(false); tvBody.setTextIsSelectable(false);
tvBody.setTextIsSelectable(true); tvBody.setTextIsSelectable(true);
tvBody.setMovementMethod(new TouchHandler(message)); tvBody.setMovementMethod(new TouchHandler(message));
} else if (result instanceof String) } else if (result instanceof String)
((WebView) wvBody).loadDataWithBaseURL(null, (String) result, "text/html", "UTF-8", null); ((WebView) wvBody).loadDataWithBaseURL(null, (String) result, "text/html", "UTF-8", null);
else else
throw new IllegalStateException("Result=" + result); throw new IllegalStateException("Result=" + result);
pbBody.setVisibility(View.GONE); pbBody.setVisibility(View.GONE);
// Show attachments/images // Show attachments/images
cowner.start(); cowner.start();
ibImages.setVisibility(has_images && !show_images ? View.VISIBLE : View.GONE); ibImages.setVisibility(has_images && !show_images ? View.VISIBLE : View.GONE);
} }
@Override @Override
protected void onException(Bundle args, Throwable ex) { protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(parentFragment.getFragmentManager(), ex); Helper.unexpectedError(parentFragment.getFragmentManager(), ex);
}
}.execute(context, owner, args, "message:body");
} }
}.execute(context, owner, args, "message:body"); });
} }
private void bindAttachments(final TupleMessageEx message, @Nullable List<EntityAttachment> attachments) { private void bindAttachments(final TupleMessageEx message, @Nullable List<EntityAttachment> attachments) {

@ -58,8 +58,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
class ImageHelper { class ImageHelper {
private static final float MIN_LUMINANCE = 0.33f; private static final float MIN_LUMINANCE = 0.33f;
@ -387,33 +385,12 @@ class ImageHelper {
d.setBounds(0, 0, w, h); d.setBounds(0, 0, w, h);
} }
final Semaphore semaphore = new Semaphore(0); float width = view.getWidth();
if (w > width) {
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { float scale = width / w;
@Override w = Math.round(w * scale);
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { h = Math.round(h * scale);
view.removeOnLayoutChangeListener(this); d.setBounds(0, 0, w, h);
Rect bounds = d.getBounds();
int w = bounds.width();
int h = bounds.height();
float width = view.getWidth();
if (w > width) {
float scale = width / w;
w = Math.round(w * scale);
h = Math.round(h * scale);
d.setBounds(0, 0, w, h);
}
semaphore.release();
}
});
try {
semaphore.tryAcquire(2500, TimeUnit.MILLISECONDS);
} catch (InterruptedException ex) {
Log.e(ex);
} }
} }

Loading…
Cancel
Save