diff --git a/.gitignore b/.gitignore index 3b96410ab6..ca03dae8d8 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ /app/full /app/play_beta /app/play_release +/app/src/main/assets/*.md /tools/config.sh crowdin.properties keystore.properties diff --git a/README.md b/README.md index a5e030452f..9b26d2130c 100644 --- a/README.md +++ b/README.md @@ -172,19 +172,20 @@ FairEmail uses: * [JavaMail](https://projects.eclipse.org/projects/ee4j.javamail). Copyright (c) 1997-2018 Oracle® and/or its affiliates. All rights reserved. [GPLv2+CE license](https://javaee.github.io/javamail/JavaMail-License). * [jsoup](https://jsoup.org/). Copyright © 2009 - 2017 Jonathan Hedley. [MIT license](https://jsoup.org/license). -* [Android Support Library](https://developer.android.com/tools/support-library/). Copyright (C) 2011 The Android Open Source Project. [Apache license](https://android.googlesource.com/platform/frameworks/support/+/master/LICENSE.txt). -* [Android Architecture Components](https://developer.android.com/topic/libraries/architecture/). Copyright 2018 The Android Open Source Project, Inc. [Apache license](https://github.com/googlesamples/android-architecture-components/blob/master/LICENSE). -* [colorpicker](https://android.googlesource.com/platform/frameworks/opt/colorpicker). Copyright (C) 2013 The Android Open Source Project. [Apache license](https://android.googlesource.com/platform/frameworks/opt/colorpicker/+/master/src/com/android/colorpicker/ColorPickerDialog.java). +* [Android Support Library](https://developer.android.com/tools/support-library/). Copyright (C) 2011 The Android Open Source Project. [Apache license 2.0](https://android.googlesource.com/platform/frameworks/support/+/master/LICENSE.txt). +* [Android Architecture Components](https://developer.android.com/topic/libraries/architecture/). Copyright 2018 The Android Open Source Project, Inc. [Apache license 2.0](https://github.com/googlesamples/android-architecture-components/blob/master/LICENSE). +* [colorpicker](https://android.googlesource.com/platform/frameworks/opt/colorpicker). Copyright (C) 2013 The Android Open Source Project. [Apache license 2.0](https://android.googlesource.com/platform/frameworks/opt/colorpicker/+/master/src/com/android/colorpicker/ColorPickerDialog.java). * [dnsjava](http://www.xbill.org/dnsjava/). Copyright (c) 1998-2011, Brian Wellington. [BSD License](https://sourceforge.net/p/dnsjava/code/HEAD/tree/trunk/LICENSE). * [OpenPGP API library](https://github.com/open-keychain/openpgp-api). Copyright (C) 2014-2015 Dominik Schürmann. [Apache License 2.0](https://github.com/open-keychain/openpgp-api/blob/master/LICENSE). * [Android SQLite support library](https://github.com/requery/sqlite-android). Copyright (C) 2017 requery.io. [Apache License 2.0](https://github.com/requery/sqlite-android/blob/master/LICENSE). * [App shortcut icon generator](https://romannurik.github.io/AndroidAssetStudio/icons-app-shortcut.html). Copyright ???. [Apache License 2.0](https://github.com/romannurik/AndroidAssetStudio/blob/master/LICENSE). * [Mozilla ISPDB](https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration#ISPDB). *Free to use for any client.* -* [ShortcutBadger](https://github.com/leolin310148/ShortcutBadger). Copyright 2014 Leo Lin. [Apache license](https://github.com/leolin310148/ShortcutBadger/blob/master/LICENSE). +* [ShortcutBadger](https://github.com/leolin310148/ShortcutBadger). Copyright 2014 Leo Lin. [Apache license 2.0](https://github.com/leolin310148/ShortcutBadger/blob/master/LICENSE). * [Bugsnag exception reporter for Android](https://github.com/bugsnag/bugsnag-android). Copyright (c) 2012 Bugsnag. [MIT License](https://github.com/bugsnag/bugsnag-android/blob/master/LICENSE.txt). * [biweekly](https://github.com/mangstadt/biweekly). Copyright (c) 2013-2018, Michael Angstadt. [BSD 2-Clause](https://github.com/mangstadt/biweekly/blob/master/LICENSE). -* [PhotoView](https://github.com/chrisbanes/PhotoView). Copyright 2018 Chris Banes. [Apache License](https://github.com/chrisbanes/PhotoView/blob/master/LICENSE). -* [ReLinker](https://github.com/KeepSafe/ReLinker). Copyright 2015 - 2016 KeepSafe Software, Inc. [Apache License](https://github.com/KeepSafe/ReLinker/blob/master/LICENSE). +* [PhotoView](https://github.com/chrisbanes/PhotoView). Copyright 2018 Chris Banes. [Apache License 2.0](https://github.com/chrisbanes/PhotoView/blob/master/LICENSE). +* [ReLinker](https://github.com/KeepSafe/ReLinker). Copyright 2015 - 2016 KeepSafe Software, Inc. [Apache License 2.0](https://github.com/KeepSafe/ReLinker/blob/master/LICENSE). +* [Markwon](https://github.com/noties/Markwon). Copyright 2019 Dimitry Ivanov. [Apache License 2.0](https://github.com/noties/Markwon/blob/master/LICENSE). Error reporting is sponsored by: diff --git a/app/build.gradle b/app/build.gradle index 0684e7e265..1f8c3f294d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,6 +18,7 @@ android { archivesBaseName = "FairEmail-v$versionName" // https://en.wikipedia.org/wiki/List_of_dinosaur_genera + // Upcoming: Echinodon buildConfigField "String", "RELEASE_NAME", "\"Dinodocus\"" javaCompileOptions { @@ -115,6 +116,14 @@ android { } } +task copyMarkdown(type: Copy) { + from "${rootDir}" + into "src/main/assets" + include "SETUP.md" + include "PRIVACY.md" +} +preBuild.dependsOn copyMarkdown + repositories { google() jcenter() @@ -153,6 +162,7 @@ dependencies { def biweekly_version = "0.6.3" def photoview_version = "2.3.0" def relinker_version = "1.3.1" + def markwon_version = "4.0.2" // https://developer.android.com/jetpack/androidx/releases/ @@ -231,7 +241,7 @@ dependencies { implementation "me.leolin:ShortcutBadger:$badge_version" // https://github.com/bugsnag/bugsnag-android - implementation ("com.bugsnag:bugsnag-android:$bugsnag_version") { + implementation("com.bugsnag:bugsnag-android:$bugsnag_version") { exclude group: "com.bugsnag", module: "bugsnag-plugin-android-anr" exclude group: "com.bugsnag", module: "bugsnag-plugin-android-ndk" } @@ -250,6 +260,9 @@ dependencies { // https://square.github.io/leakcanary/getting_started/ //debugImplementation "com.squareup.leakcanary:leakcanary-android:2.0-alpha-3" + // https://github.com/noties/Markwon + implementation "io.noties.markwon:core:$markwon_version" + // git clone https://android.googlesource.com/platform/frameworks/opt/colorpicker implementation project(path: ':colorpicker') } diff --git a/app/src/main/java/eu/faircode/email/ActivitySetup.java b/app/src/main/java/eu/faircode/email/ActivitySetup.java index 8fe8e3d7e1..ad9412613c 100644 --- a/app/src/main/java/eu/faircode/email/ActivitySetup.java +++ b/app/src/main/java/eu/faircode/email/ActivitySetup.java @@ -235,14 +235,13 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac } })); - if (Helper.getIntentPrivacy().resolveActivity(pm) != null) - menus.add(new NavMenuItem(R.drawable.baseline_account_box_24, R.string.menu_privacy, new Runnable() { - @Override - public void run() { - drawerLayout.closeDrawer(drawerContainer); - onMenuPrivacy(); - } - })); + menus.add(new NavMenuItem(R.drawable.baseline_account_box_24, R.string.menu_privacy, new Runnable() { + @Override + public void run() { + drawerLayout.closeDrawer(drawerContainer); + onMenuPrivacy(); + } + })); menus.add(new NavMenuItem(R.drawable.baseline_info_24, R.string.menu_about, new Runnable() { @Override @@ -474,7 +473,11 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac } private void onMenuPrivacy() { - Helper.view(this, Helper.getIntentPrivacy()); + Bundle args = new Bundle(); + args.putString("name", "PRIVACY.md"); + FragmentDialogMarkdown fragment = new FragmentDialogMarkdown(); + fragment.setArguments(args); + fragment.show(getSupportFragmentManager(), "privacy"); } private void onMenuAbout() { diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index b317b28bf2..f0f443a683 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -322,14 +322,13 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB } })); - if (Helper.getIntentPrivacy().resolveActivity(pm) != null) - extra.add(new NavMenuItem(R.drawable.baseline_account_box_24, R.string.menu_privacy, new Runnable() { - @Override - public void run() { - drawerLayout.closeDrawer(drawerContainer); - onMenuPrivacy(); - } - })); + extra.add(new NavMenuItem(R.drawable.baseline_account_box_24, R.string.menu_privacy, new Runnable() { + @Override + public void run() { + drawerLayout.closeDrawer(drawerContainer); + onMenuPrivacy(); + } + })); extra.add(new NavMenuItem(R.drawable.baseline_info_24, R.string.menu_about, new Runnable() { @Override @@ -899,7 +898,11 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB } private void onMenuPrivacy() { - Helper.view(this, Helper.getIntentPrivacy()); + Bundle args = new Bundle(); + args.putString("name", "PRIVACY.md"); + FragmentDialogMarkdown fragment = new FragmentDialogMarkdown(); + fragment.setArguments(args); + fragment.show(getSupportFragmentManager(), "privacy"); } private void onMenuAbout() { diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogMarkdown.java b/app/src/main/java/eu/faircode/email/FragmentDialogMarkdown.java new file mode 100644 index 0000000000..5ae440e4d2 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentDialogMarkdown.java @@ -0,0 +1,75 @@ +package eu.faircode.email; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.io.InputStream; + +import io.noties.markwon.Markwon; + +public class FragmentDialogMarkdown extends DialogFragmentEx { + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + final View dview = LayoutInflater.from(getContext()).inflate(R.layout.dialog_markdown, null); + final TextView tvMarkdown = dview.findViewById(R.id.tvMarkdown); + final ContentLoadingProgressBar pbWait = dview.findViewById(R.id.pbWait); + + tvMarkdown.setText(null); + + Dialog dialog = new Dialog(getContext()); + //dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + dialog.setContentView(dview); + dialog.getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT); + + new SimpleTask() { + @Override + protected void onPreExecute(Bundle args) { + tvMarkdown.setVisibility(View.GONE); + pbWait.setVisibility(View.VISIBLE); + } + + @Override + protected void onPostExecute(Bundle args) { + tvMarkdown.setVisibility(View.VISIBLE); + pbWait.setVisibility(View.GONE); + } + + @Override + protected Spanned onExecute(Context context, Bundle args) throws Throwable { + String name = args.getString("name"); + try (InputStream is = context.getAssets().open(name)) { + byte[] buffer = new byte[is.available()]; + is.read(buffer); + Markwon markwon = Markwon.create(context); + return markwon.toMarkdown(new String(buffer)); + } + } + + @Override + protected void onExecuted(Bundle args, Spanned markdown) { + tvMarkdown.setText(markdown); + tvMarkdown.setMovementMethod(LinkMovementMethod.getInstance()); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Helper.unexpectedError(getFragmentManager(), ex); + } + }.execute(getContext(), getActivity(), getArguments(), "markdown:read"); + + return dialog; + } +} diff --git a/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java b/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java index fbed97bd8c..b5ab8a1276 100644 --- a/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java +++ b/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java @@ -165,7 +165,6 @@ public class FragmentQuickSetup extends FragmentBase { @Override public void onPrepareOptionsMenu(Menu menu) { PackageManager pm = getContext().getPackageManager(); - menu.findItem(R.id.menu_help).setVisible(Helper.getIntentSetupHelp().resolveActivity(pm) != null); super.onPrepareOptionsMenu(menu); } @@ -181,7 +180,11 @@ public class FragmentQuickSetup extends FragmentBase { } private void onMenuHelp() { - startActivity(Helper.getIntentSetupHelp()); + Bundle args = new Bundle(); + args.putString("name", "SETUP.md"); + FragmentDialogMarkdown fragment = new FragmentDialogMarkdown(); + fragment.setArguments(args); + fragment.show(getChildFragmentManager(), "help"); } private void onSave(boolean check) { diff --git a/app/src/main/java/eu/faircode/email/FragmentSetup.java b/app/src/main/java/eu/faircode/email/FragmentSetup.java index 2b0400f9b1..dd427c90a9 100644 --- a/app/src/main/java/eu/faircode/email/FragmentSetup.java +++ b/app/src/main/java/eu/faircode/email/FragmentSetup.java @@ -141,11 +141,14 @@ public class FragmentSetup extends FragmentBase { } }); - btnHelp.setVisibility(Helper.getIntentSetupHelp().resolveActivity(pm) == null ? View.GONE : View.VISIBLE); btnHelp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - startActivity(Helper.getIntentSetupHelp()); + Bundle args = new Bundle(); + args.putString("name", "SETUP.md"); + FragmentDialogMarkdown fragment = new FragmentDialogMarkdown(); + fragment.setArguments(args); + fragment.show(getChildFragmentManager(), "help"); } }); diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index 055068d1ad..2918d6304e 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -227,24 +227,12 @@ public class Helper { } } - static Intent getIntentSetupHelp() { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse("https://github.com/M66B/FairEmail/blob/master/SETUP.md#setup-help")); - return intent; - } - static Intent getIntentFAQ() { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(Helper.FAQ_URI)); return intent; } - static Intent getIntentPrivacy() { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse("https://github.com/M66B/FairEmail/blob/master/PRIVACY.md#fairemail")); - return intent; - } - static Intent getIntentOpenKeychain() { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("https://f-droid.org/en/packages/org.sufficientlysecure.keychain/")); diff --git a/app/src/main/res/layout/dialog_markdown.xml b/app/src/main/res/layout/dialog_markdown.xml new file mode 100644 index 0000000000..358be91f41 --- /dev/null +++ b/app/src/main/res/layout/dialog_markdown.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + \ No newline at end of file