diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index fa469051cb..0cb5d97471 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -382,7 +382,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB }).setExternal(true)); if ((Helper.isPlayStoreInstall() || BuildConfig.DEBUG) && - getIntentRate(this).resolveActivity(pm) != null) + Helper.getIntentRate(this).resolveActivity(pm) != null) extra.add(new NavMenuItem(R.drawable.baseline_star_24, R.string.menu_rate, new Runnable() { @Override public void run() { @@ -1164,13 +1164,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB return intent; } - private static Intent getIntentRate(Context context) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + BuildConfig.APPLICATION_ID)); - if (intent.resolveActivity(context.getPackageManager()) == null) - intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID)); - return intent; - } - public static class FragmentDialogFirst extends FragmentDialogBase { @NonNull @Override @@ -1204,7 +1197,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB .setNegativeButton(R.string.title_no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - Helper.view(getContext(), getIntentRate(getContext())); + Helper.view(getContext(), Helper.getIntentRate(getContext())); } }) .create(); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index d949d4c34e..7e1a0e77b4 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -30,6 +30,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; import android.content.SharedPreferences; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PorterDuff; @@ -288,6 +290,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. static final String ACTION_DECRYPT = BuildConfig.APPLICATION_ID + ".DECRYPT"; static final String ACTION_NEW_MESSAGE = BuildConfig.APPLICATION_ID + ".NEW_MESSAGE"; + private static final long REVIEW_ASK_DELAY = 24 * 3600 * 1000L; // milliseonds + private static final List DUPLICATE_ORDER = Collections.unmodifiableList(Arrays.asList( EntityFolder.INBOX, EntityFolder.OUTBOX, @@ -2577,7 +2581,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. else fabMore.hide(); - checkReporting(); + if (!checkReporting()) + checkReview(); } @Override @@ -2695,24 +2700,69 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. } }; - private void checkReporting() { - if (viewType == AdapterMessage.ViewType.UNIFIED) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - if (prefs.getBoolean("crash_reports", false) || - prefs.getBoolean("crash_reports_asked", false)) - return; + private boolean checkReporting() { + if (viewType != AdapterMessage.ViewType.UNIFIED) + return false; - final Snackbar snackbar = Snackbar.make(view, R.string.title_ask_help, Snackbar.LENGTH_INDEFINITE); - snackbar.setAction(R.string.title_info, new View.OnClickListener() { - @Override - public void onClick(View v) { - snackbar.dismiss(); - new FragmentDialogReporting().show(getParentFragmentManager(), "reporting"); - } - }); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + if (prefs.getBoolean("crash_reports", false) || + prefs.getBoolean("crash_reports_asked", false)) + return false; + + final Snackbar snackbar = Snackbar.make(view, R.string.title_ask_help, Snackbar.LENGTH_INDEFINITE); + snackbar.setAction(R.string.title_info, new View.OnClickListener() { + @Override + public void onClick(View v) { + snackbar.dismiss(); + new FragmentDialogReporting().show(getParentFragmentManager(), "reporting"); + } + }); + + snackbar.show(); - snackbar.show(); + return true; + } + + private boolean checkReview() { + if (viewType != AdapterMessage.ViewType.UNIFIED) + return false; + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + if (prefs.getBoolean("review_asked", false)) + return false; + + PackageManager pm = getContext().getPackageManager(); + + Intent intent = Helper.getIntentRate(getContext()); + if (intent.resolveActivity(pm) == null) + return false; + + long installed = 0; + try { + PackageInfo pi = pm.getPackageInfo(BuildConfig.APPLICATION_ID, 0); + if (pi != null) + installed = pi.firstInstallTime; + } catch (Throwable ex) { + Log.e(ex); } + Log.i("Installed=" + new Date(installed)); + + long now = new Date().getTime(); + if (installed + REVIEW_ASK_DELAY > now) + return false; + + final Snackbar snackbar = Snackbar.make(view, R.string.title_ask_review, Snackbar.LENGTH_INDEFINITE); + snackbar.setAction(R.string.title_info, new View.OnClickListener() { + @Override + public void onClick(View v) { + snackbar.dismiss(); + new FragmentDialogReview().show(getParentFragmentManager(), "review"); + } + }); + + snackbar.show(); + + return true; } @Override @@ -5413,6 +5463,36 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. } } + public static class FragmentDialogReview extends FragmentDialogBase { + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + View dview = LayoutInflater.from(getContext()).inflate(R.layout.dialog_review, null); + CheckBox cbNotAgain = dview.findViewById(R.id.cbNotAgain); + + cbNotAgain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + prefs.edit().putBoolean("review_asked", isChecked).apply(); + } + }); + + return new AlertDialog.Builder(getContext()) + .setView(dview) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + prefs.edit().putBoolean("review_asked", true).apply(); + startActivity(Helper.getIntentRate(getContext())); + } + }) + .setNegativeButton(android.R.string.no, null) + .create(); + } + } + public static class FragmentDialogAccount extends FragmentDialogBase { @NonNull @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java index 597dc80a9c..d72624fa92 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java @@ -68,7 +68,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc }; private final static String[] RESET_QUESTIONS = new String[]{ - "welcome", "crash_reports_asked", + "welcome", "crash_reports_asked", "review_asked", "html_always_images", "print_html_confirmed", "identities_asked", "cc_bcc", "inline_image_hint", "compose_reference", "send_dialog" }; diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index fd74d4660a..7aeb299723 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -324,6 +324,13 @@ public class Helper { return new Intent(Intent.ACTION_VIEW, Uri.parse(XDA_URI)); } + static Intent getIntentRate(Context context) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + BuildConfig.APPLICATION_ID)); + if (intent.resolveActivity(context.getPackageManager()) == null) + intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID)); + return intent; + } + // Graphics static int dp2pixels(Context context, int dp) { diff --git a/app/src/main/res/layout/dialog_review.xml b/app/src/main/res/layout/dialog_review.xml new file mode 100644 index 0000000000..e8c58f00eb --- /dev/null +++ b/app/src/main/res/layout/dialog_review.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1d9d5f6a61..c850308ab7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -657,6 +657,10 @@ Help improve FairEmail Send error reports? Error reporting will help improve FairEmail + + Please review FairEmail + You have been using FairEmail for a while. It is appreciated if you rate FairEmail in the Play Store, also to maintain a balance between unfavorable and favorable reviews. + Expanding this message will download %1$s Downloading …