mirror of
https://github.com/M66B/FairEmail.git
synced 2026-03-29 05:15:13 +02:00
Added option connect via unmetered only
This commit is contained in:
2747
app/schemas/eu.faircode.email.DB/233.json
Normal file
2747
app/schemas/eu.faircode.email.DB/233.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -71,7 +71,7 @@ import io.requery.android.database.sqlite.SQLiteDatabase;
|
||||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 232,
|
||||
version = 233,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
@@ -2318,6 +2318,12 @@ public abstract class DB extends RoomDatabase {
|
||||
logMigration(startVersion, endVersion);
|
||||
db.execSQL("ALTER TABLE `contact` ADD COLUMN 'identity' INTEGER");
|
||||
}
|
||||
}).addMigrations(new Migration(232, 233) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase db) {
|
||||
logMigration(startVersion, endVersion);
|
||||
db.execSQL("ALTER TABLE `account` ADD COLUMN 'conditions' TEXT");
|
||||
}
|
||||
}).addMigrations(new Migration(998, 999) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase db) {
|
||||
|
||||
@@ -143,6 +143,8 @@ public class EntityAccount extends EntityOrder implements Serializable {
|
||||
public Boolean use_received = false; // Received header
|
||||
public String prefix; // namespace, obsolete
|
||||
|
||||
public String conditions;
|
||||
|
||||
public Long quota_usage;
|
||||
public Long quota_limit;
|
||||
|
||||
@@ -295,6 +297,7 @@ public class EntityAccount extends EntityOrder implements Serializable {
|
||||
json.put("ignore_size", ignore_size);
|
||||
json.put("use_date", use_date);
|
||||
json.put("use_received", use_received);
|
||||
json.put("conditions", conditions);
|
||||
// not prefix
|
||||
// not created
|
||||
// not tbd
|
||||
@@ -383,6 +386,7 @@ public class EntityAccount extends EntityOrder implements Serializable {
|
||||
account.ignore_size = json.optBoolean("ignore_size", false);
|
||||
account.use_date = json.optBoolean("use_date", false);
|
||||
account.use_received = json.optBoolean("use_received", false);
|
||||
account.conditions = json.optString("conditions");
|
||||
|
||||
return account;
|
||||
}
|
||||
@@ -420,6 +424,7 @@ public class EntityAccount extends EntityOrder implements Serializable {
|
||||
this.ignore_size == other.ignore_size &&
|
||||
this.use_date == other.use_date &&
|
||||
this.use_received == other.use_received &&
|
||||
Objects.equals(this.conditions, other.conditions) &&
|
||||
Objects.equals(this.quota_usage, other.quota_usage) &&
|
||||
Objects.equals(this.quota_limit, other.quota_limit) &&
|
||||
Objects.equals(this.created, other.created) &&
|
||||
|
||||
@@ -68,6 +68,8 @@ import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.sun.mail.imap.IMAPFolder;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.cert.X509Certificate;
|
||||
@@ -121,6 +123,7 @@ public class FragmentAccount extends FragmentBase {
|
||||
private CheckBox cbPartialFetch;
|
||||
private CheckBox cbIgnoreSize;
|
||||
private RadioGroup rgDate;
|
||||
private CheckBox cbUnmetered;
|
||||
|
||||
private Button btnCheck;
|
||||
private ContentLoadingProgressBar pbCheck;
|
||||
@@ -228,6 +231,7 @@ public class FragmentAccount extends FragmentBase {
|
||||
cbPartialFetch = view.findViewById(R.id.cbPartialFetch);
|
||||
cbIgnoreSize = view.findViewById(R.id.cbIgnoreSize);
|
||||
rgDate = view.findViewById(R.id.rgDate);
|
||||
cbUnmetered = view.findViewById(R.id.cbUnmeteredOnly);
|
||||
|
||||
btnCheck = view.findViewById(R.id.btnCheck);
|
||||
pbCheck = view.findViewById(R.id.pbCheck);
|
||||
@@ -881,6 +885,7 @@ public class FragmentAccount extends FragmentBase {
|
||||
args.putBoolean("ignore_size", cbIgnoreSize.isChecked());
|
||||
args.putBoolean("use_date", rgDate.getCheckedRadioButtonId() == R.id.radio_date_header);
|
||||
args.putBoolean("use_received", rgDate.getCheckedRadioButtonId() == R.id.radio_received_header);
|
||||
args.putBoolean("unmetered", cbUnmetered.isChecked());
|
||||
|
||||
args.putSerializable("drafts", drafts);
|
||||
args.putSerializable("sent", sent);
|
||||
@@ -950,6 +955,7 @@ public class FragmentAccount extends FragmentBase {
|
||||
boolean ignore_size = args.getBoolean("ignore_size");
|
||||
boolean use_date = args.getBoolean("use_date");
|
||||
boolean use_received = args.getBoolean("use_received");
|
||||
boolean unmetered = args.getBoolean("unmetered");
|
||||
|
||||
EntityFolder drafts = (EntityFolder) args.getSerializable("drafts");
|
||||
EntityFolder sent = (EntityFolder) args.getSerializable("sent");
|
||||
@@ -994,6 +1000,14 @@ public class FragmentAccount extends FragmentBase {
|
||||
DB db = DB.getInstance(context);
|
||||
EntityAccount account = db.account().getAccount(id);
|
||||
|
||||
JSONObject jconditions = new JSONObject();
|
||||
if (account != null && account.conditions != null)
|
||||
try {
|
||||
jconditions = new JSONObject(account.conditions);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
|
||||
if (should) {
|
||||
if (account == null)
|
||||
return !TextUtils.isEmpty(host) && !TextUtils.isEmpty(user);
|
||||
@@ -1046,6 +1060,8 @@ public class FragmentAccount extends FragmentBase {
|
||||
return true;
|
||||
if (!Objects.equals(account.use_received, use_received))
|
||||
return true;
|
||||
if (unmetered != jconditions.optBoolean("unmetered"))
|
||||
return true;
|
||||
if (account.error != null && account.synchronize)
|
||||
return true;
|
||||
|
||||
@@ -1184,6 +1200,9 @@ public class FragmentAccount extends FragmentBase {
|
||||
account.use_date = use_date;
|
||||
account.use_received = use_received;
|
||||
|
||||
jconditions.put("unmetered", unmetered);
|
||||
account.conditions = jconditions.toString();
|
||||
|
||||
if (!update)
|
||||
account.created = now;
|
||||
|
||||
@@ -1530,6 +1549,15 @@ public class FragmentAccount extends FragmentBase {
|
||||
cbPartialFetch.setChecked(account == null ? true : account.partial_fetch);
|
||||
cbIgnoreSize.setChecked(account == null ? false : account.ignore_size);
|
||||
|
||||
JSONObject jcondition = new JSONObject();
|
||||
try {
|
||||
if (account != null && account.conditions != null)
|
||||
jcondition = new JSONObject(account.conditions);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
cbUnmetered.setChecked(jcondition.optBoolean("unmetered"));
|
||||
|
||||
if (account != null && account.use_date)
|
||||
rgDate.check(R.id.radio_date_header);
|
||||
else if (account != null && account.use_received)
|
||||
|
||||
@@ -60,6 +60,8 @@ import androidx.lifecycle.Lifecycle;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@@ -94,6 +96,7 @@ public class FragmentPop extends FragmentBase {
|
||||
private CheckBox cbLeaveDevice;
|
||||
private EditText etMax;
|
||||
private EditText etInterval;
|
||||
private CheckBox cbUnmetered;
|
||||
|
||||
private ArrayAdapter<EntityFolder> adapterSwipe;
|
||||
private Spinner spLeft;
|
||||
@@ -159,6 +162,7 @@ public class FragmentPop extends FragmentBase {
|
||||
cbLeaveDevice = view.findViewById(R.id.cbLeaveDevice);
|
||||
etMax = view.findViewById(R.id.etMax);
|
||||
etInterval = view.findViewById(R.id.etInterval);
|
||||
cbUnmetered = view.findViewById(R.id.cbUnmeteredOnly);
|
||||
|
||||
spLeft = view.findViewById(R.id.spLeft);
|
||||
spRight = view.findViewById(R.id.spRight);
|
||||
@@ -323,6 +327,7 @@ public class FragmentPop extends FragmentBase {
|
||||
args.putBoolean("leave_device", cbLeaveDevice.isChecked());
|
||||
args.putString("max", etMax.getText().toString());
|
||||
args.putString("interval", etInterval.getText().toString());
|
||||
args.putBoolean("unmetered", cbUnmetered.isChecked());
|
||||
|
||||
args.putLong("left", ((EntityFolder) spLeft.getSelectedItem()).id);
|
||||
args.putLong("right", ((EntityFolder) spRight.getSelectedItem()).id);
|
||||
@@ -373,6 +378,7 @@ public class FragmentPop extends FragmentBase {
|
||||
boolean leave_device = args.getBoolean("leave_device");
|
||||
String max = args.getString("max");
|
||||
String interval = args.getString("interval");
|
||||
boolean unmetered = args.getBoolean("unmetered");
|
||||
|
||||
long left = args.getLong("left");
|
||||
long right = args.getLong("right");
|
||||
@@ -411,6 +417,14 @@ public class FragmentPop extends FragmentBase {
|
||||
DB db = DB.getInstance(context);
|
||||
EntityAccount account = db.account().getAccount(id);
|
||||
|
||||
JSONObject jconditions = new JSONObject();
|
||||
if (account != null && account.conditions != null)
|
||||
try {
|
||||
jconditions = new JSONObject(account.conditions);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
|
||||
if (should) {
|
||||
if (account == null)
|
||||
return !TextUtils.isEmpty(host) && !TextUtils.isEmpty(user);
|
||||
@@ -453,6 +467,8 @@ public class FragmentPop extends FragmentBase {
|
||||
return true;
|
||||
if (!Objects.equals(account.poll_interval, poll_interval))
|
||||
return true;
|
||||
if (unmetered != jconditions.optBoolean("unmetered"))
|
||||
return true;
|
||||
|
||||
if (!Objects.equals(account.swipe_left, left))
|
||||
return true;
|
||||
@@ -530,6 +546,9 @@ public class FragmentPop extends FragmentBase {
|
||||
account.max_messages = max_messages;
|
||||
account.poll_interval = poll_interval;
|
||||
|
||||
jconditions.put("unmetered", unmetered);
|
||||
account.conditions = jconditions.toString();
|
||||
|
||||
account.swipe_left = left;
|
||||
account.swipe_right = right;
|
||||
|
||||
@@ -713,6 +732,16 @@ public class FragmentPop extends FragmentBase {
|
||||
? EntityAccount.DEFAULT_MAX_MESSAGES : account.max_messages));
|
||||
|
||||
etInterval.setText(account == null ? "" : Long.toString(account.poll_interval));
|
||||
|
||||
JSONObject jcondition = new JSONObject();
|
||||
try {
|
||||
if (account != null && account.conditions != null)
|
||||
jcondition = new JSONObject(account.conditions);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
cbUnmetered.setChecked(jcondition.optBoolean("unmetered"));
|
||||
|
||||
cbIdentity.setChecked(account == null);
|
||||
|
||||
List<EntityFolder> folders = getSwipeActions();
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class TupleAccountNetworkState {
|
||||
public boolean enabled;
|
||||
@NonNull
|
||||
@@ -33,6 +35,8 @@ public class TupleAccountNetworkState {
|
||||
@NonNull
|
||||
public TupleAccountState accountState;
|
||||
|
||||
private JSONObject jconditions;
|
||||
|
||||
public TupleAccountNetworkState(
|
||||
boolean enabled,
|
||||
@NonNull Bundle command,
|
||||
@@ -42,9 +46,21 @@ public class TupleAccountNetworkState {
|
||||
this.command = command;
|
||||
this.networkState = networkState;
|
||||
this.accountState = accountState;
|
||||
|
||||
this.jconditions = new JSONObject();
|
||||
if (this.accountState.conditions != null)
|
||||
try {
|
||||
jconditions = new JSONObject(this.accountState.conditions);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canRun() {
|
||||
boolean unmetered = jconditions.optBoolean("unmetered");
|
||||
if (unmetered && !this.networkState.isUnmetered())
|
||||
return false;
|
||||
|
||||
return (this.networkState.isSuitable() && this.accountState.shouldRun(enabled));
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ public class TupleAccountState extends EntityAccount {
|
||||
this.ignore_size.equals(other.ignore_size) &&
|
||||
this.use_date.equals(other.use_date) &&
|
||||
this.use_received.equals(other.use_received) &&
|
||||
Objects.equals(this.conditions, other.conditions) &&
|
||||
this.folders == other.folders &&
|
||||
Objects.equals(this.tbd, other.tbd));
|
||||
} else
|
||||
|
||||
@@ -653,6 +653,15 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/rgDate" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbUnmeteredOnly"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_unmetered_only"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvDateRemark" />
|
||||
|
||||
<!-- check -->
|
||||
|
||||
<Button
|
||||
@@ -665,7 +674,7 @@
|
||||
android:tag="disable"
|
||||
android:text="@string/title_check"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvDateRemark" />
|
||||
app:layout_constraintTop_toBottomOf="@id/cbUnmeteredOnly" />
|
||||
|
||||
<eu.faircode.email.ContentLoadingProgressBar
|
||||
android:id="@+id/pbCheck"
|
||||
@@ -1052,7 +1061,8 @@
|
||||
cbBrowse,tvBrowseHint,
|
||||
cbAutoSeen,
|
||||
tvInterval,etInterval,tvIntervalRemark,
|
||||
cbPartialFetch,tvPartialFetchRemark,cbIgnoreSize,rgDate,tvDateRemark" />
|
||||
cbPartialFetch,tvPartialFetchRemark,cbIgnoreSize,rgDate,tvDateRemark,
|
||||
cbUnmeteredOnly" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/grpFolders"
|
||||
|
||||
@@ -464,6 +464,15 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etInterval" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbUnmeteredOnly"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_unmetered_only"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvIntervalRemark" />
|
||||
|
||||
<eu.faircode.email.FixedTextView
|
||||
android:id="@+id/tvLeft"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -472,7 +481,7 @@
|
||||
android:text="@string/title_account_left"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvIntervalRemark" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/cbUnmeteredOnly" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spLeft"
|
||||
|
||||
@@ -950,6 +950,7 @@
|
||||
<string name="title_received_header">Use \'Received\' header</string>
|
||||
<string name="title_date_header">Use \'Date\' header (sent time)</string>
|
||||
<string name="title_date_remark">Changes will be applied to new messages only</string>
|
||||
<string name="title_unmetered_only">Connect only via unmetered networks</string>
|
||||
<string name="title_related_identity">Add related identity (SMTP server)</string>
|
||||
<string name="title_check">Check</string>
|
||||
<string name="title_trust">Trust server certificate with fingerprint %1$s</string>
|
||||
|
||||
Reference in New Issue
Block a user