Browse Source

remove pro features validations

main
Distopico 6 years ago
parent
commit
1f57a7377a
11 changed files with 201 additions and 391 deletions
  1. +2
    -1
      app/src/main/java/eu/faircode/email/ActivityBase.java
  2. +43
    -68
      app/src/main/java/eu/faircode/email/ActivityView.java
  3. +5
    -9
      app/src/main/java/eu/faircode/email/AdapterMessage.java
  4. +2
    -1
      app/src/main/java/eu/faircode/email/FragmentAbout.java
  5. +8
    -33
      app/src/main/java/eu/faircode/email/FragmentAccount.java
  6. +34
    -36
      app/src/main/java/eu/faircode/email/FragmentCompose.java
  7. +67
    -90
      app/src/main/java/eu/faircode/email/FragmentMessages.java
  8. +0
    -95
      app/src/main/java/eu/faircode/email/FragmentPro.java
  9. +22
    -39
      app/src/main/java/eu/faircode/email/FragmentSetup.java
  10. +16
    -17
      app/src/main/java/eu/faircode/email/ServiceSynchronize.java
  11. +2
    -2
      app/src/main/res/layout/fragment_account.xml

+ 2
- 1
app/src/main/java/eu/faircode/email/ActivityBase.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -35,7 +36,7 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
Log.i(Helper.TAG, "Create " + this.getClass().getName() + " version=" + BuildConfig.VERSION_NAME); Log.i(Helper.TAG, "Create " + this.getClass().getName() + " version=" + BuildConfig.VERSION_NAME);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String theme = (Helper.isPro(this) ? prefs.getString("theme", "light") : "light");
String theme = prefs.getString("theme", "light");
setTheme("light".equals(theme) ? R.style.AppThemeLight : R.style.AppThemeDark); setTheme("light".equals(theme) ? R.style.AppThemeLight : R.style.AppThemeDark);
prefs.registerOnSharedPreferenceChangeListener(this); prefs.registerOnSharedPreferenceChangeListener(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);


+ 43
- 68
app/src/main/java/eu/faircode/email/ActivityView.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.app.Activity; import android.app.Activity;
@ -117,7 +118,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
static final String ACTION_EDIT_ANSWER = BuildConfig.APPLICATION_ID + ".EDIT_ANSWER"; static final String ACTION_EDIT_ANSWER = BuildConfig.APPLICATION_ID + ".EDIT_ANSWER";
static final String ACTION_STORE_ATTACHMENT = BuildConfig.APPLICATION_ID + ".STORE_ATTACHMENT"; static final String ACTION_STORE_ATTACHMENT = BuildConfig.APPLICATION_ID + ".STORE_ATTACHMENT";
static final String ACTION_DECRYPT = BuildConfig.APPLICATION_ID + ".DECRYPT"; static final String ACTION_DECRYPT = BuildConfig.APPLICATION_ID + ".DECRYPT";
static final String ACTION_SHOW_PRO = BuildConfig.APPLICATION_ID + ".SHOW_PRO";
static final String UPDATE_LATEST_API = "https://api.github.com/repos/M66B/open-source-email/releases/latest"; static final String UPDATE_LATEST_API = "https://api.github.com/repos/M66B/open-source-email/releases/latest";
static final long UPDATE_INTERVAL = 12 * 3600 * 1000L; // milliseconds static final long UPDATE_INTERVAL = 12 * 3600 * 1000L; // milliseconds
@ -172,9 +172,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
case R.string.menu_faq: case R.string.menu_faq:
onMenuFAQ(); onMenuFAQ();
break; break;
case R.string.menu_pro:
onMenuPro();
break;
case R.string.menu_privacy: case R.string.menu_privacy:
onMenuPrivacy(); onMenuPrivacy();
break; break;
@ -313,7 +310,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
iff.addAction(ACTION_EDIT_ANSWER); iff.addAction(ACTION_EDIT_ANSWER);
iff.addAction(ACTION_STORE_ATTACHMENT); iff.addAction(ACTION_STORE_ATTACHMENT);
iff.addAction(ACTION_DECRYPT); iff.addAction(ACTION_DECRYPT);
iff.addAction(ACTION_SHOW_PRO);
lbm.registerReceiver(receiver, iff); lbm.registerReceiver(receiver, iff);
if (!pgpService.isBound()) if (!pgpService.isBound())
@ -339,48 +335,43 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
intent.removeExtra(Intent.EXTRA_PROCESS_TEXT); intent.removeExtra(Intent.EXTRA_PROCESS_TEXT);
setIntent(intent); setIntent(intent);
if (Helper.isPro(this)) {
Bundle args = new Bundle();
args.putString("search", search);
Bundle args = new Bundle();
args.putString("search", search);
new SimpleTask<Long>() {
@Override
protected Long onLoad(Context context, Bundle args) {
DB db = DB.getInstance(context);
new SimpleTask<Long>() {
@Override
protected Long onLoad(Context context, Bundle args) {
DB db = DB.getInstance(context);
EntityFolder archive = db.folder().getPrimaryArchive();
if (archive == null)
throw new IllegalArgumentException(getString(R.string.title_no_primary_archive));
EntityFolder archive = db.folder().getPrimaryArchive();
if (archive == null) {
throw new IllegalArgumentException(getString(R.string.title_no_primary_archive));
}
db.message().deleteFoundMessages();
db.message().deleteFoundMessages();
return archive.id;
}
return archive.id;
}
@Override
protected void onLoaded(Bundle args, Long archive) {
Bundle sargs = new Bundle();
sargs.putLong("folder", archive);
sargs.putString("search", args.getString("search"));
@Override
protected void onLoaded(Bundle args, Long archive) {
Bundle sargs = new Bundle();
sargs.putLong("folder", archive);
sargs.putString("search", args.getString("search"));
FragmentMessages fragment = new FragmentMessages();
fragment.setArguments(sargs);
FragmentMessages fragment = new FragmentMessages();
fragment.setArguments(sargs);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("search");
fragmentTransaction.commit();
}
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("search");
fragmentTransaction.commit();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(ActivityView.this, ex);
}
}.load(this, args);
} else {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(ActivityView.this, ex);
}
}.load(this, args);
} }
} }
@ -712,12 +703,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
Helper.view(this, getIntentFAQ()); Helper.view(this, getIntentFAQ());
} }
private void onMenuPro() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
private void onMenuPrivacy() { private void onMenuPrivacy() {
Helper.view(this, Helper.getIntentPrivacy()); Helper.view(this, Helper.getIntentPrivacy());
} }
@ -833,8 +818,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
onStoreAttachment(intent); onStoreAttachment(intent);
else if (ACTION_DECRYPT.equals(intent.getAction())) else if (ACTION_DECRYPT.equals(intent.getAction()))
onDecrypt(intent); onDecrypt(intent);
else if (ACTION_SHOW_PRO.equals(intent.getAction()))
onShowPro(intent);
} }
}; };
@ -901,33 +884,25 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
} }
private void onDecrypt(Intent intent) { private void onDecrypt(Intent intent) {
if (Helper.isPro(this)) {
if (pgpService.isBound()) {
Intent data = new Intent();
data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{intent.getStringExtra("to")});
data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
decrypt(data, intent.getLongExtra("id", -1));
} else {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_openpgp, Snackbar.LENGTH_LONG);
if (Helper.getIntentOpenKeychain().resolveActivity(getPackageManager()) != null)
snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
if (pgpService.isBound()) {
Intent data = new Intent();
data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{intent.getStringExtra("to")});
data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
decrypt(data, intent.getLongExtra("id", -1));
} else {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_openpgp, Snackbar.LENGTH_LONG);
if (Helper.getIntentOpenKeychain().resolveActivity(getPackageManager()) != null) {
snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startActivity(Helper.getIntentOpenKeychain()); startActivity(Helper.getIntentOpenKeychain());
} }
}); });
snackbar.show();
} }
} else
onShowPro(intent);
}
private void onShowPro(Intent intent) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
snackbar.show();
}
} }
private void decrypt(Intent data, long id) { private void decrypt(Intent data, long id) {


+ 5
- 9
app/src/main/java/eu/faircode/email/AdapterMessage.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.Manifest; import android.Manifest;
@ -948,15 +949,10 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem target) { public boolean onMenuItemClick(MenuItem target) {
if (Helper.isPro(context))
context.startActivity(new Intent(context, ActivityCompose.class)
.putExtra("action", "reply")
.putExtra("reference", data.message.id)
.putExtra("answer", (long) target.getItemId()));
else {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
}
context.startActivity(new Intent(context, ActivityCompose.class)
.putExtra("action", "reply")
.putExtra("reference", data.message.id)
.putExtra("answer", (long) target.getItemId()));
return true; return true;
} }
}); });


+ 2
- 1
app/src/main/java/eu/faircode/email/FragmentAbout.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.app.usage.UsageStatsManager; import android.app.usage.UsageStatsManager;
@ -95,7 +96,7 @@ public class FragmentAbout extends FragmentEx {
BuildConfig.APPLICATION_ID, BuildConfig.APPLICATION_ID,
BuildConfig.VERSION_NAME, BuildConfig.VERSION_NAME,
Helper.hasValidFingerprint(context) ? "1" : "3", Helper.hasValidFingerprint(context) ? "1" : "3",
Helper.isPro(context) ? "+" : ""));
"+"));
sb.append(String.format("Android: %s (SDK %d)\r\n", Build.VERSION.RELEASE, Build.VERSION.SDK_INT)); sb.append(String.format("Android: %s (SDK %d)\r\n", Build.VERSION.RELEASE, Build.VERSION.SDK_INT));
sb.append("\r\n"); sb.append("\r\n");


+ 8
- 33
app/src/main/java/eu/faircode/email/FragmentAccount.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.Manifest; import android.Manifest;
@ -116,7 +117,6 @@ public class FragmentAccount extends FragmentEx {
private View vwColor; private View vwColor;
private ImageView ibColorDefault; private ImageView ibColorDefault;
private EditText etSignature; private EditText etSignature;
private ImageButton ibPro;
private CheckBox cbSynchronize; private CheckBox cbSynchronize;
private CheckBox cbPrimary; private CheckBox cbPrimary;
@ -190,7 +190,6 @@ public class FragmentAccount extends FragmentEx {
vwColor = view.findViewById(R.id.vwColor); vwColor = view.findViewById(R.id.vwColor);
ibColorDefault = view.findViewById(R.id.ibColorDefault); ibColorDefault = view.findViewById(R.id.ibColorDefault);
etSignature = view.findViewById(R.id.etSignature); etSignature = view.findViewById(R.id.etSignature);
ibPro = view.findViewById(R.id.ibPro);
cbSynchronize = view.findViewById(R.id.cbSynchronize); cbSynchronize = view.findViewById(R.id.cbSynchronize);
cbPrimary = view.findViewById(R.id.cbPrimary); cbPrimary = view.findViewById(R.id.cbPrimary);
@ -362,23 +361,16 @@ public class FragmentAccount extends FragmentEx {
btnColor.setOnClickListener(new View.OnClickListener() { btnColor.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (Helper.isPro(getContext())) {
int[] colors = getContext().getResources().getIntArray(R.array.colorPicker);
ColorPickerDialog colorPickerDialog = new ColorPickerDialog();
colorPickerDialog.initialize(R.string.title_account_color, colors, color, 4, colors.length);
colorPickerDialog.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener() {
int[] colors = getContext().getResources().getIntArray(R.array.colorPicker);
ColorPickerDialog colorPickerDialog = new ColorPickerDialog();
colorPickerDialog.initialize(R.string.title_account_color, colors, color, 4, colors.length);
colorPickerDialog.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener() {
@Override @Override
public void onColorSelected(int color) { public void onColorSelected(int color) {
setColor(color); setColor(color);
} }
}); });
colorPickerDialog.show(getFragmentManager(), "colorpicker");
} else {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(FragmentAccount.this);
fragmentTransaction.add(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
colorPickerDialog.show(getFragmentManager(), "colorpicker");
} }
}); });
@ -389,16 +381,6 @@ public class FragmentAccount extends FragmentEx {
} }
}); });
ibPro.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(FragmentAccount.this);
fragmentTransaction.add(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
});
cbSynchronize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { cbSynchronize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
@ -979,15 +961,8 @@ public class FragmentAccount extends FragmentEx {
setColor(color); setColor(color);
boolean pro = Helper.isPro(getContext());
etSignature.setHint(pro ? R.string.title_optional : R.string.title_pro_feature);
etSignature.setEnabled(pro);
if (pro) {
ViewGroup.LayoutParams lp = ibPro.getLayoutParams();
lp.height = 0;
lp.width = 0;
ibPro.setLayoutParams(lp);
}
etSignature.setHint(R.string.title_optional);
etSignature.setEnabled(true);
cbPrimary.setEnabled(cbSynchronize.isChecked()); cbPrimary.setEnabled(cbSynchronize.isChecked());


+ 34
- 36
app/src/main/java/eu/faircode/email/FragmentCompose.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.Manifest; import android.Manifest;
@ -496,45 +497,41 @@ public class FragmentCompose extends FragmentEx {
} }
private void onEncrypt() { private void onEncrypt() {
if (Helper.isPro(getContext())) {
if (pgpService.isBound())
try {
String to = etTo.getText().toString();
InternetAddress ato[] = (TextUtils.isEmpty(to) ? new InternetAddress[0] : InternetAddress.parse(to));
if (ato.length == 0)
throw new IllegalArgumentException(getString(R.string.title_to_missing));
String[] tos = new String[ato.length];
for (int i = 0; i < ato.length; i++)
tos[i] = ato[i].getAddress();
Intent data = new Intent();
data.setAction(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
data.putExtra(OpenPgpApi.EXTRA_USER_IDS, tos);
data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
encrypt(data);
} catch (Throwable ex) {
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Helper.unexpectedError(getContext(), ex);
if (pgpService.isBound()) {
try {
String to = etTo.getText().toString();
InternetAddress ato[] = (TextUtils.isEmpty(to) ? new InternetAddress[0] : InternetAddress.parse(to));
if (ato.length == 0)
throw new IllegalArgumentException(getString(R.string.title_to_missing));
String[] tos = new String[ato.length];
for (int i = 0; i < ato.length; i++)
tos[i] = ato[i].getAddress();
Intent data = new Intent();
data.setAction(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
data.putExtra(OpenPgpApi.EXTRA_USER_IDS, tos);
data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
encrypt(data);
} catch (Throwable ex) {
if (ex instanceof IllegalArgumentException) {
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
} else {
Helper.unexpectedError(getContext(), ex);
} }
else {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_openpgp, Snackbar.LENGTH_LONG);
if (Helper.getIntentOpenKeychain().resolveActivity(getContext().getPackageManager()) != null)
snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
}
} else {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_openpgp, Snackbar.LENGTH_LONG);
if (Helper.getIntentOpenKeychain().resolveActivity(getContext().getPackageManager()) != null) {
snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startActivity(Helper.getIntentOpenKeychain()); startActivity(Helper.getIntentOpenKeychain());
} }
}); });
snackbar.show();
} }
} else {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
snackbar.show();
} }
} }
@ -962,7 +959,6 @@ public class FragmentCompose extends FragmentEx {
long id = args.getLong("id", -1); long id = args.getLong("id", -1);
long reference = args.getLong("reference", -1); long reference = args.getLong("reference", -1);
long answer = args.getLong("answer", -1); long answer = args.getLong("answer", -1);
boolean pro = Helper.isPro(getContext());
Log.i(Helper.TAG, "Load draft action=" + action + " id=" + id + " reference=" + reference); Log.i(Helper.TAG, "Load draft action=" + action + " id=" + id + " reference=" + reference);
@ -1076,8 +1072,9 @@ public class FragmentCompose extends FragmentEx {
else else
body = body.replaceAll("\\r?\\n", "<br />"); body = body.replaceAll("\\r?\\n", "<br />");
if (pro && !TextUtils.isEmpty(account.signature))
if (!TextUtils.isEmpty(account.signature)) {
body += account.signature; body += account.signature;
}
} else { } else {
draft.thread = ref.thread; draft.thread = ref.thread;
@ -1125,8 +1122,9 @@ public class FragmentCompose extends FragmentEx {
HtmlHelper.sanitize(ref.read(context))); HtmlHelper.sanitize(ref.read(context)));
} }
if (pro && !TextUtils.isEmpty(account.signature))
if (!TextUtils.isEmpty(account.signature)) {
body = account.signature + body; body = account.signature + body;
}
if (answer > 0 && ("reply".equals(action) || "reply_all".equals(action))) { if (answer > 0 && ("reply".equals(action) || "reply_all".equals(action))) {
String text = db.answer().getAnswer(answer).text; String text = db.answer().getAnswer(answer).text;
@ -1567,4 +1565,4 @@ public class FragmentCompose extends FragmentEx {
return view; return view;
} }
} }
}
}

+ 67
- 90
app/src/main/java/eu/faircode/email/FragmentMessages.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.content.Context; import android.content.Context;
@ -174,15 +175,6 @@ public class FragmentMessages extends FragmentEx {
// Wire controls // Wire controls
tvSupport.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
});
ibHintSwipe.setOnClickListener(new View.OnClickListener() { ibHintSwipe.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -549,56 +541,58 @@ public class FragmentMessages extends FragmentEx {
fabMove.setOnClickListener(new View.OnClickListener() { fabMove.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (Helper.isPro(getContext())) {
Bundle args = new Bundle();
args.putLong("folder", folder);
new SimpleTask<List<EntityFolder>>() {
@Override
protected List<EntityFolder> onLoad(Context context, Bundle args) {
long folder = args.getLong("folder");
DB db = DB.getInstance(context);
EntityFolder source = db.folder().getFolder(folder);
List<EntityFolder> folders = db.folder().getFolders(source.account);
List<EntityFolder> targets = new ArrayList<>();
for (EntityFolder f : folders)
if (!f.id.equals(folder) && !EntityFolder.DRAFTS.equals(f.type))
targets.add(f);
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
Collections.sort(targets, new Comparator<EntityFolder>() {
Bundle args = new Bundle();
args.putLong("folder", folder);
new SimpleTask<List<EntityFolder>>() {
@Override
protected List<EntityFolder> onLoad(Context context, Bundle args) {
long folder = args.getLong("folder");
DB db = DB.getInstance(context);
EntityFolder source = db.folder().getFolder(folder);
List<EntityFolder> folders = db.folder().getFolders(source.account);
List<EntityFolder> targets = new ArrayList<>();
for (EntityFolder f : folders) {
if (!f.id.equals(folder) && !EntityFolder.DRAFTS.equals(f.type)) {
targets.add(f);
}
}
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
Collections.sort(targets, new Comparator<EntityFolder>() {
@Override @Override
public int compare(EntityFolder f1, EntityFolder f2) { public int compare(EntityFolder f1, EntityFolder f2) {
int s = Integer.compare( int s = Integer.compare(
EntityFolder.FOLDER_SORT_ORDER.indexOf(f1.type), EntityFolder.FOLDER_SORT_ORDER.indexOf(f1.type),
EntityFolder.FOLDER_SORT_ORDER.indexOf(f2.type)); EntityFolder.FOLDER_SORT_ORDER.indexOf(f2.type));
if (s != 0)
if (s != 0) {
return s; return s;
}
return collator.compare( return collator.compare(
f1.name == null ? "" : f1.name, f1.name == null ? "" : f1.name,
f2.name == null ? "" : f2.name); f2.name == null ? "" : f2.name);
} }
}); });
return targets;
}
return targets;
}
@Override
protected void onLoaded(final Bundle args, List<EntityFolder> folders) {
PopupMenu popupMenu = new PopupMenu(getContext(), popupAnchor);
@Override
protected void onLoaded(final Bundle args, List<EntityFolder> folders) {
PopupMenu popupMenu = new PopupMenu(getContext(), popupAnchor);
int order = 0;
for (EntityFolder folder : folders) {
String name = (folder.display == null
? Helper.localizeFolderName(getContext(), folder.name)
: folder.display);
popupMenu.getMenu().add(Menu.NONE, folder.id.intValue(), order++, name);
}
int order = 0;
for (EntityFolder folder : folders) {
String name = (folder.display == null
? Helper.localizeFolderName(getContext(), folder.name)
: folder.display);
popupMenu.getMenu().add(Menu.NONE, folder.id.intValue(), order++, name);
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(final MenuItem target) { public boolean onMenuItemClick(final MenuItem target) {
MutableSelection<Long> selection = new MutableSelection<>(); MutableSelection<Long> selection = new MutableSelection<>();
@ -656,19 +650,14 @@ public class FragmentMessages extends FragmentEx {
} }
}); });
popupMenu.show();
}
popupMenu.show();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), ex);
}
}.load(FragmentMessages.this, args);
} else {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), ex);
}
}.load(FragmentMessages.this, args);
} }
}); });
@ -857,7 +846,7 @@ public class FragmentMessages extends FragmentEx {
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
grpSupport.setVisibility(Helper.isPro(getContext()) ? View.GONE : View.VISIBLE);
grpSupport.setVisibility(View.GONE);
} }
@Override @Override
@ -872,33 +861,27 @@ public class FragmentMessages extends FragmentEx {
public boolean onQueryTextSubmit(String query) { public boolean onQueryTextSubmit(String query) {
menuSearch.collapseActionView(); menuSearch.collapseActionView();
if (Helper.isPro(getContext())) {
Bundle args = new Bundle();
args.putLong("folder", folder);
args.putString("search", query);
Bundle args = new Bundle();
args.putLong("folder", folder);
args.putString("search", query);
new SimpleTask<Void>() {
@Override
protected Void onLoad(Context context, Bundle args) {
DB.getInstance(context).message().deleteFoundMessages();
return null;
}
new SimpleTask<Void>() {
@Override
protected Void onLoad(Context context, Bundle args) {
DB.getInstance(context).message().deleteFoundMessages();
return null;
}
@Override
protected void onLoaded(Bundle args, Void data) {
FragmentMessages fragment = new FragmentMessages();
fragment.setArguments(args);
@Override
protected void onLoaded(Bundle args, Void data) {
FragmentMessages fragment = new FragmentMessages();
fragment.setArguments(args);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("search");
fragmentTransaction.commit();
}
}.load(FragmentMessages.this, args);
} else {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("search");
fragmentTransaction.commit();
}
}.load(FragmentMessages.this, args);
return true; return true;
} }
@ -945,15 +928,9 @@ public class FragmentMessages extends FragmentEx {
case R.id.menu_sort_on_unread: case R.id.menu_sort_on_unread:
case R.id.menu_sort_on_starred: case R.id.menu_sort_on_starred:
if (Helper.isPro(getContext())) {
prefs.edit().putString("sort", item.getItemId() == R.id.menu_sort_on_unread ? "unread" : "starred").apply();
item.setChecked(true);
loadMessages();
} else {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
prefs.edit().putString("sort", item.getItemId() == R.id.menu_sort_on_unread ? "unread" : "starred").apply();
item.setChecked(true);
loadMessages();
return true; return true;
case R.id.menu_folders: case R.id.menu_folders:


+ 0
- 95
app/src/main/java/eu/faircode/email/FragmentPro.java View File

@ -1,95 +0,0 @@
package eu.faircode.email;
/*
This file is part of FairEmail.
FairEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FairEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B)
*/
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
public class FragmentPro extends FragmentEx implements SharedPreferences.OnSharedPreferenceChangeListener {
private TextView tvActivated;
private TextView tvList;
private Button btnPurchase;
private TextView tvPrice;
@Override
@Nullable
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
setSubtitle(R.string.menu_pro);
View view = inflater.inflate(R.layout.fragment_pro, container, false);
tvActivated = view.findViewById(R.id.tvActivated);
tvList = view.findViewById(R.id.tvList);
btnPurchase = view.findViewById(R.id.btnPurchase);
tvPrice = view.findViewById(R.id.tvPrice);
tvList.setText(Html.fromHtml("<a href=\"https://email.faircode.eu/#pro\">" + Html.escapeHtml(getString(R.string.title_pro_list)) + "</a>"));
tvList.setMovementMethod(LinkMovementMethod.getInstance());
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
onSharedPreferenceChanged(prefs, "pro");
btnPurchase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
lbm.sendBroadcast(new Intent(ActivityView.ACTION_PURCHASE));
}
});
tvPrice.setMovementMethod(LinkMovementMethod.getInstance());
return view;
}
@Override
public void onResume() {
super.onResume();
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if ("pro".equals(key)) {
boolean pro = prefs.getBoolean(key, false);
tvActivated.setVisibility(pro ? View.VISIBLE : View.GONE);
btnPurchase.setEnabled(!pro);
}
}
}

+ 22
- 39
app/src/main/java/eu/faircode/email/FragmentSetup.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.Manifest; import android.Manifest;
@ -231,31 +232,21 @@ public class FragmentSetup extends FragmentEx {
tbDarkTheme.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { tbDarkTheme.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton button, boolean checked) { public void onCheckedChanged(CompoundButton button, boolean checked) {
if (Helper.isPro(getContext())) {
if (checked != (Boolean) button.getTag()) {
button.setTag(checked);
tbDarkTheme.setChecked(checked);
prefs.edit().putString("theme", checked ? "dark" : "light").apply();
}
} else {
prefs.edit().remove("theme").apply();
if (checked) {
tbDarkTheme.setChecked(false);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
if (checked != (Boolean) button.getTag()) {
button.setTag(checked);
tbDarkTheme.setChecked(checked);
prefs.edit().putString("theme", checked ? "dark" : "light").apply();
} }
} }
}); });
btnOptions.setOnClickListener(new View.OnClickListener() { btnOptions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentOptions()).addToBackStack("options");
fragmentTransaction.commit();
}
@Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentOptions()).addToBackStack("options");
fragmentTransaction.commit();
}
}); });
// Initialize // Initialize
@ -445,26 +436,18 @@ public class FragmentSetup extends FragmentEx {
} }
private void onMenuExport() { private void onMenuExport() {
if (Helper.isPro(getContext()))
new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
.setMessage(R.string.title_setup_export_do)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
startActivityForResult(getIntentExport(), ActivitySetup.REQUEST_EXPORT);
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
.setMessage(R.string.title_setup_export_do)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
startActivityForResult(getIntentExport(), ActivitySetup.REQUEST_EXPORT);
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
} }
})
.create()
.show();
else {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
}
}).create().show();
} }
private void onMenuImport() { private void onMenuImport() {


+ 16
- 17
app/src/main/java/eu/faircode/email/ServiceSynchronize.java View File

@ -17,6 +17,7 @@ package eu.faircode.email;
along with FairEmail. If not, see <http://www.gnu.org/licenses/>. along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
Copyright 2019 by Distopico <distopico@riseup.net>
*/ */
import android.Manifest; import android.Manifest;
@ -347,7 +348,6 @@ public class ServiceSynchronize extends LifecycleService {
if (messages.size() == 0) if (messages.size() == 0)
return notifications; return notifications;
boolean pro = Helper.isPro(this);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
// Build pending intent // Build pending intent
@ -392,20 +392,18 @@ public class ServiceSynchronize extends LifecycleService {
builder.setLights(0xff00ff00, 1000, 1000); builder.setLights(0xff00ff00, 1000, 1000);
} }
if (pro) {
DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT);
StringBuilder sb = new StringBuilder();
for (EntityMessage message : messages) {
sb.append("<strong>").append(MessageHelper.getFormattedAddresses(message.from, false)).append("</strong>");
if (!TextUtils.isEmpty(message.subject))
sb.append(": ").append(message.subject);
sb.append(" ").append(df.format(new Date(message.sent == null ? message.received : message.sent)));
sb.append("<br>");
}
builder.setStyle(new Notification.BigTextStyle().bigText(Html.fromHtml(sb.toString())));
DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT);
StringBuilder sb = new StringBuilder();
for (EntityMessage message : messages) {
sb.append("<strong>").append(MessageHelper.getFormattedAddresses(message.from, false)).append("</strong>");
if (!TextUtils.isEmpty(message.subject))
sb.append(": ").append(message.subject);
sb.append(" ").append(df.format(new Date(message.sent == null ? message.received : message.sent)));
sb.append("<br>");
} }
builder.setStyle(new Notification.BigTextStyle().bigText(Html.fromHtml(sb.toString())));
notifications.add(builder.build()); notifications.add(builder.build());
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
@ -465,12 +463,13 @@ public class ServiceSynchronize extends LifecycleService {
.addAction(actionSeen.build()) .addAction(actionSeen.build())
.addAction(actionTrash.build()); .addAction(actionTrash.build());
if (pro)
if (!TextUtils.isEmpty(message.subject))
mbuilder.setContentText(message.subject);
if (!TextUtils.isEmpty(message.subject)) {
mbuilder.setContentText(message.subject);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mbuilder.setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN); mbuilder.setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN);
}
notifications.add(mbuilder.build()); notifications.add(mbuilder.build());
} }


+ 2
- 2
app/src/main/res/layout/fragment_account.xml View File

@ -550,7 +550,7 @@
android:id="@+id/grpAdvanced" android:id="@+id/grpAdvanced"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:constraint_referenced_ids="tvName,etName,btnColor,vwColor,ibColorDefault,tvSignature,etSignature,ibPro,cbSynchronize,cbPrimary,tvInterval,etInterval" />
app:constraint_referenced_ids="tvName,etName,btnColor,vwColor,ibColorDefault,tvSignature,etSignature,cbSynchronize,cbPrimary,tvInterval,etInterval" />
<androidx.constraintlayout.widget.Group <androidx.constraintlayout.widget.Group
android:id="@+id/grpFolders" android:id="@+id/grpFolders"
@ -558,4 +558,4 @@
android:layout_height="0dp" android:layout_height="0dp"
app:constraint_referenced_ids="tvDrafts,spDrafts,tvSent,spSent,tvAll,spAll,tvTrash,spTrash,tvJunk,spJunk" /> app:constraint_referenced_ids="tvDrafts,spDrafts,tvSent,spSent,tvAll,spAll,tvTrash,spTrash,tvJunk,spJunk" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</ScrollView>

Loading…
Cancel
Save