Added option connect via unmetered only

pull/207/head
M66B 2 years ago
parent 0a92b677b2
commit 7fa99dc0a7

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>

Loading…
Cancel
Save