diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 0e39d79ef6..141869786d 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -86,7 +86,6 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.PopupMenu; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Group; -import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; @@ -1784,176 +1783,25 @@ public class AdapterMessage extends RecyclerView.Adapter() { - @Override - protected String onExecute(Context context, Bundle args) throws Throwable { - long id = args.getLong("id"); - - DB db = DB.getInstance(context); - EntityMessage message = db.message().getMessage(id); - if (message == null || !message.content) - return null; - - File file = message.getFile(context); - if (!file.exists()) - return null; - - String html = HtmlHelper.getHtmlEmbedded(context, id, Helper.readText(file)); - - // Remove viewport limitations - Document doc = Jsoup.parse(html); - for (Element meta : doc.select("meta").select("[name=viewport]")) { - String content = meta.attr("content"); - String[] params = content.split(";"); - if (params.length > 0) { - List viewport = new ArrayList<>(); - for (String param : params) - if (!param.toLowerCase().contains("maximum-scale") && - !param.toLowerCase().contains("user-scalable")) - viewport.add(param.trim()); - - if (viewport.size() == 0) - meta.attr("content", ""); - else - meta.attr("content", TextUtils.join(" ;", viewport) + ";"); - } - } - - return doc.html(); - } - - @Override - protected void onExecuted(Bundle args, String html) { - long id = args.getLong("id"); - - TupleMessageEx amessage = getMessage(); - if (amessage == null || !amessage.id.equals(id)) - return; - - WebView webView = new WebView(context); - setupWebView(webView); - - boolean show_images = properties.getValue("images", id); - - WebSettings settings = webView.getSettings(); - settings.setDefaultFontSize(Math.round(textSize)); - settings.setDefaultFixedFontSize(Math.round(textSize)); - settings.setLoadsImagesAutomatically(show_images); - settings.setBuiltInZoomControls(true); - settings.setDisplayZoomControls(false); - - webView.loadDataWithBaseURL("", html, "text/html", "UTF-8", null); - - final Dialog dialog = new Dialog(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen); - dialog.setContentView(webView); - - owner.getLifecycle().addObserver(new LifecycleObserver() { - @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) - public void onCreate() { - dialog.show(); - } - - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - public void onDestroyed() { - dialog.dismiss(); - } - }); - } - - @Override - protected void onException(Bundle args, Throwable ex) { - Helper.unexpectedError(parentFragment.getFragmentManager(), ex); - } - }.execute(context, owner, args, "message:full"); - } - - private void setupWebView(WebView webView) { - webView.setWebViewClient(new WebViewClient() { - public boolean shouldOverrideUrlLoading(WebView view, String url) { - Log.i("Open url=" + url); - - Uri uri = Uri.parse(url); - if ("cid".equals(uri.getScheme()) || "data".equals(uri.getScheme())) - return false; - - onOpenLink(uri, null); - return true; - } - }); - - webView.setDownloadListener(new DownloadListener() { - public void onDownloadStart( - String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { - Log.i("Download url=" + url + " mime type=" + mimetype); - - Uri uri = Uri.parse(url); - if ("cid".equals(uri.getScheme()) || "data".equals(uri.getScheme())) - return; - - Helper.view(context, owner, uri, true); - } - }); - - webView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - WebView.HitTestResult result = ((WebView) view).getHitTestResult(); - if (result.getType() == WebView.HitTestResult.IMAGE_TYPE || - result.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) { - Log.i("Long press url=" + result.getExtra()); - - Uri uri = Uri.parse(result.getExtra()); - if ("cid".equals(uri.getScheme()) || "data".equals(uri.getScheme())) - return false; - - Helper.view(context, owner, uri, true); - - return true; - } - return false; - } - }); - - WebSettings settings = webView.getSettings(); - settings.setUseWideViewPort(true); - settings.setLoadWithOverviewMode(true); - settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING); - settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); - settings.setAllowFileAccess(false); - - if (monospaced) - settings.setStandardFontFamily("monospace"); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (properties.getValue("confirmed", message.id) || + prefs.getBoolean("show_html_confirmed", false)) { + FragmentDialogWebView fragment = new FragmentDialogWebView(); + fragment.setArguments(args); + fragment.show(parentFragment.getFragmentManager(), "message:full"); + } else { + FragmentDialogFull fragment = new FragmentDialogFull(); + fragment.setArguments(args); + fragment.setTargetFragment(parentFragment, FragmentMessages.REQUEST_MESSAGE_PROPERTY); + fragment.show(parentFragment.getFragmentManager(), "message:full:confirm"); + } } private void onShowImages(final TupleMessageEx message) { @@ -3652,6 +3500,179 @@ public class AdapterMessage extends RecyclerView.Adapter() { + @Override + protected String onExecute(Context context, Bundle args) throws Throwable { + long id = args.getLong("id"); + + DB db = DB.getInstance(context); + EntityMessage message = db.message().getMessage(id); + if (message == null || !message.content) + return null; + + File file = message.getFile(context); + if (!file.exists()) + return null; + + String html = HtmlHelper.getHtmlEmbedded(context, id, Helper.readText(file)); + + // Remove viewport limitations + Document doc = Jsoup.parse(html); + for (Element meta : doc.select("meta").select("[name=viewport]")) { + String content = meta.attr("content"); + String[] params = content.split(";"); + if (params.length > 0) { + List viewport = new ArrayList<>(); + for (String param : params) + if (!param.toLowerCase().contains("maximum-scale") && + !param.toLowerCase().contains("user-scalable")) + viewport.add(param.trim()); + + if (viewport.size() == 0) + meta.attr("content", ""); + else + meta.attr("content", TextUtils.join(" ;", viewport) + ";"); + } + } + + return doc.html(); + } + + @Override + protected void onExecuted(Bundle args, String html) { + webView.loadDataWithBaseURL("", html, "text/html", "UTF-8", null); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Helper.unexpectedError(getFragmentManager(), ex); + } + }.execute(getContext(), getActivity(), getArguments(), "message:full"); + + Dialog dialog = new Dialog(getContext(), android.R.style.Theme_Black_NoTitleBar_Fullscreen); + dialog.setContentView(webView); + return dialog; + } + + private void setupWebView(WebView webView) { + webView.setWebViewClient(new WebViewClient() { + public boolean shouldOverrideUrlLoading(WebView view, String url) { + Log.i("Open url=" + url); + + Uri uri = Uri.parse(url); + if ("cid".equals(uri.getScheme()) || "data".equals(uri.getScheme())) + return false; + + Bundle args = new Bundle(); + args.putParcelable("uri", uri); + args.putString("title", null); + + FragmentDialogLink fragment = new FragmentDialogLink(); + fragment.setArguments(args); + fragment.show(getFragmentManager(), "open:link"); + + return true; + } + }); + + webView.setDownloadListener(new DownloadListener() { + public void onDownloadStart( + String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { + Log.i("Download url=" + url + " mime type=" + mimetype); + + Uri uri = Uri.parse(url); + if ("cid".equals(uri.getScheme()) || "data".equals(uri.getScheme())) + return; + + Helper.view(getContext(), getActivity(), uri, true); + } + }); + + webView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + WebView.HitTestResult result = ((WebView) view).getHitTestResult(); + if (result.getType() == WebView.HitTestResult.IMAGE_TYPE || + result.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) { + Log.i("Long press url=" + result.getExtra()); + + Uri uri = Uri.parse(result.getExtra()); + if ("cid".equals(uri.getScheme()) || "data".equals(uri.getScheme())) + return false; + + Helper.view(getContext(), getActivity(), uri, true); + + return true; + } + return false; + } + }); + + WebSettings settings = webView.getSettings(); + settings.setUseWideViewPort(true); + settings.setLoadWithOverviewMode(true); + settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING); + settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + settings.setAllowFileAccess(false); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + boolean monospaced = prefs.getBoolean("monospaced", false); + if (monospaced) + settings.setStandardFontFamily("monospace"); + } + } + public static class FragmentKeywordManage extends DialogFragmentEx { @NonNull @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index a5b838a4d5..6c25fc9d26 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -254,6 +254,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. static final int REQUEST_PRINT = 17; private static final int REQUEST_SEARCH = 18; private static final int REQUEST_ACCOUNT = 19; + static final int REQUEST_MESSAGE_PROPERTY = 20; static final String ACTION_STORE_RAW = BuildConfig.APPLICATION_ID + ".STORE_RAW"; static final String ACTION_STORE_ATTACHMENT = BuildConfig.APPLICATION_ID + ".STORE_ATTACHMENT"; @@ -3366,6 +3367,10 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. onMenuFolders(args.getLong("account")); } break; + case REQUEST_MESSAGE_PROPERTY: + if (resultCode == RESULT_OK) + onPropertySet(data.getBundleExtra("args")); + break; } } @@ -4204,6 +4209,14 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. }.execute(this, pargs, "message:print"); } + private void onPropertySet(Bundle args) { + long id = args.getLong("id"); + String name = args.getString("name"); + boolean value = args.getBoolean("value"); + Log.i("Set property " + name + "=" + value + " id=" + id); + iProperties.setValue(name, id, value); + } + static void search( final Context context, final LifecycleOwner owner, final FragmentManager manager, long folder, boolean server, String query) {