mirror of https://github.com/M66B/FairEmail.git
Allow accounts to be exempted from polling
This commit is contained in:
parent
d5a413dcbb
commit
0bb4282e5c
File diff suppressed because it is too large
Load Diff
|
@ -56,7 +56,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
|
||||||
// https://developer.android.com/topic/libraries/architecture/room.html
|
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
version = 128,
|
version = 129,
|
||||||
entities = {
|
entities = {
|
||||||
EntityIdentity.class,
|
EntityIdentity.class,
|
||||||
EntityAccount.class,
|
EntityAccount.class,
|
||||||
|
@ -1240,6 +1240,13 @@ public abstract class DB extends RoomDatabase {
|
||||||
db.execSQL("ALTER TABLE `account` ADD COLUMN `quota_limit` INTEGER");
|
db.execSQL("ALTER TABLE `account` ADD COLUMN `quota_limit` INTEGER");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.addMigrations(new Migration(128, 129) {
|
||||||
|
@Override
|
||||||
|
public void migrate(@NonNull SupportSQLiteDatabase db) {
|
||||||
|
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||||
|
db.execSQL("ALTER TABLE `account` ADD COLUMN `poll_exempted` INTEGER NOT NULL DEFAULT 0");
|
||||||
|
}
|
||||||
|
})
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,9 @@ public interface DaoAccount {
|
||||||
@Query("UPDATE account SET keep_alive_failed = :value WHERE id = :id")
|
@Query("UPDATE account SET keep_alive_failed = :value WHERE id = :id")
|
||||||
int setAccountKeepAliveFailed(long id, int value);
|
int setAccountKeepAliveFailed(long id, int value);
|
||||||
|
|
||||||
|
@Query("UPDATE account SET poll_exempted = :value WHERE id = :id")
|
||||||
|
int setAccountPollExempted(long id, boolean value);
|
||||||
|
|
||||||
@Query("UPDATE account SET `order` = :order WHERE id = :id")
|
@Query("UPDATE account SET `order` = :order WHERE id = :id")
|
||||||
int setAccountOrder(long id, Integer order);
|
int setAccountOrder(long id, Integer order);
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ public class EntityAccount extends EntityOrder implements Serializable {
|
||||||
@NonNull
|
@NonNull
|
||||||
public Boolean ondemand = false;
|
public Boolean ondemand = false;
|
||||||
@NonNull
|
@NonNull
|
||||||
|
public Boolean poll_exempted = false;
|
||||||
|
@NonNull
|
||||||
public Boolean primary;
|
public Boolean primary;
|
||||||
@NonNull
|
@NonNull
|
||||||
public Boolean notify = false;
|
public Boolean notify = false;
|
||||||
|
|
|
@ -42,17 +42,27 @@ import android.widget.Toast;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.widget.SwitchCompat;
|
import androidx.appcompat.widget.SwitchCompat;
|
||||||
|
import androidx.constraintlayout.widget.Group;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.lifecycle.Lifecycle;
|
import androidx.lifecycle.Lifecycle;
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import java.text.DateFormatSymbols;
|
import java.text.DateFormatSymbols;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class FragmentOptionsSynchronize extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class FragmentOptionsSynchronize extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
private SwitchCompat swEnabled;
|
private SwitchCompat swEnabled;
|
||||||
private Spinner spPollInterval;
|
private Spinner spPollInterval;
|
||||||
|
private RecyclerView rvExempted;
|
||||||
private SwitchCompat swSchedule;
|
private SwitchCompat swSchedule;
|
||||||
private TextView tvSchedulePro;
|
private TextView tvSchedulePro;
|
||||||
private TextView tvScheduleStart;
|
private TextView tvScheduleStart;
|
||||||
|
@ -68,6 +78,9 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
|
||||||
private SwitchCompat swSubscribedOnly;
|
private SwitchCompat swSubscribedOnly;
|
||||||
private SwitchCompat swCheckMx;
|
private SwitchCompat swCheckMx;
|
||||||
private SwitchCompat swCheckReply;
|
private SwitchCompat swCheckReply;
|
||||||
|
private Group grpExempted;
|
||||||
|
|
||||||
|
private AdapterAccountExempted adapter;
|
||||||
|
|
||||||
private final static String[] RESET_OPTIONS = new String[]{
|
private final static String[] RESET_OPTIONS = new String[]{
|
||||||
"enabled", "poll_interval", "schedule", "schedule_start", "schedule_end",
|
"enabled", "poll_interval", "schedule", "schedule_start", "schedule_end",
|
||||||
|
@ -88,6 +101,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
|
||||||
swEnabled = view.findViewById(R.id.swEnabled);
|
swEnabled = view.findViewById(R.id.swEnabled);
|
||||||
spPollInterval = view.findViewById(R.id.spPollInterval);
|
spPollInterval = view.findViewById(R.id.spPollInterval);
|
||||||
swSchedule = view.findViewById(R.id.swSchedule);
|
swSchedule = view.findViewById(R.id.swSchedule);
|
||||||
|
rvExempted = view.findViewById(R.id.rvExempted);
|
||||||
tvSchedulePro = view.findViewById(R.id.tvSchedulePro);
|
tvSchedulePro = view.findViewById(R.id.tvSchedulePro);
|
||||||
tvScheduleStart = view.findViewById(R.id.tvScheduleStart);
|
tvScheduleStart = view.findViewById(R.id.tvScheduleStart);
|
||||||
tvScheduleEnd = view.findViewById(R.id.tvScheduleEnd);
|
tvScheduleEnd = view.findViewById(R.id.tvScheduleEnd);
|
||||||
|
@ -110,6 +124,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
|
||||||
swSubscribedOnly = view.findViewById(R.id.swSubscribedOnly);
|
swSubscribedOnly = view.findViewById(R.id.swSubscribedOnly);
|
||||||
swCheckMx = view.findViewById(R.id.swCheckMx);
|
swCheckMx = view.findViewById(R.id.swCheckMx);
|
||||||
swCheckReply = view.findViewById(R.id.swCheckReply);
|
swCheckReply = view.findViewById(R.id.swCheckReply);
|
||||||
|
grpExempted = view.findViewById(R.id.grpExempted);
|
||||||
|
|
||||||
setOptions();
|
setOptions();
|
||||||
|
|
||||||
|
@ -135,6 +150,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
|
||||||
if (value != current) {
|
if (value != current) {
|
||||||
adapterView.setTag(value);
|
adapterView.setTag(value);
|
||||||
prefs.edit().putInt("poll_interval", value).apply();
|
prefs.edit().putInt("poll_interval", value).apply();
|
||||||
|
grpExempted.setVisibility(value == 0 ? View.GONE : View.VISIBLE);
|
||||||
ServiceSynchronize.reschedule(getContext());
|
ServiceSynchronize.reschedule(getContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,10 +159,18 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
|
||||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||||
adapterView.setTag(null);
|
adapterView.setTag(null);
|
||||||
prefs.edit().remove("poll_interval").apply();
|
prefs.edit().remove("poll_interval").apply();
|
||||||
|
grpExempted.setVisibility(View.GONE);
|
||||||
ServiceSynchronize.reschedule(getContext());
|
ServiceSynchronize.reschedule(getContext());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
rvExempted.setHasFixedSize(false);
|
||||||
|
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||||
|
rvExempted.setLayoutManager(llm);
|
||||||
|
|
||||||
|
adapter = new AdapterAccountExempted(getViewLifecycleOwner(), getContext());
|
||||||
|
rvExempted.setAdapter(adapter);
|
||||||
|
|
||||||
swSchedule.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
swSchedule.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
||||||
|
@ -263,6 +287,16 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
DB db = DB.getInstance(getContext());
|
||||||
|
db.account().liveSynchronizingAccounts().observe(getViewLifecycleOwner(), new Observer<List<EntityAccount>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<EntityAccount> accounts) {
|
||||||
|
if (accounts == null)
|
||||||
|
accounts = new ArrayList<>();
|
||||||
|
adapter.set(accounts);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
|
@ -320,6 +354,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
|
||||||
spPollInterval.setSelection(pos);
|
spPollInterval.setSelection(pos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
grpExempted.setVisibility(pollInterval == 0 ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
swSchedule.setChecked(prefs.getBoolean("schedule", false) && pro);
|
swSchedule.setChecked(prefs.getBoolean("schedule", false) && pro);
|
||||||
swSchedule.setEnabled(pro);
|
swSchedule.setEnabled(pro);
|
||||||
|
@ -384,4 +419,144 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
|
||||||
ServiceSynchronize.reschedule(getContext());
|
ServiceSynchronize.reschedule(getContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AdapterAccountExempted extends RecyclerView.Adapter<AdapterAccountExempted.ViewHolder> {
|
||||||
|
private Context context;
|
||||||
|
private LifecycleOwner owner;
|
||||||
|
private LayoutInflater inflater;
|
||||||
|
|
||||||
|
private List<EntityAccount> items = new ArrayList<>();
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener {
|
||||||
|
private CheckBox cbExempted;
|
||||||
|
|
||||||
|
ViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
cbExempted = itemView.findViewById(R.id.cbExempted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void wire() {
|
||||||
|
cbExempted.setOnCheckedChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unwire() {
|
||||||
|
cbExempted.setOnCheckedChangeListener(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindTo(EntityAccount account) {
|
||||||
|
cbExempted.setEnabled(!account.ondemand);
|
||||||
|
cbExempted.setChecked(account.poll_exempted);
|
||||||
|
cbExempted.setText(account.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
int pos = getAdapterPosition();
|
||||||
|
if (pos == RecyclerView.NO_POSITION)
|
||||||
|
return;
|
||||||
|
|
||||||
|
EntityAccount account = items.get(pos);
|
||||||
|
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putLong("id", account.id);
|
||||||
|
args.putBoolean("exempted", isChecked);
|
||||||
|
|
||||||
|
new SimpleTask<Void>() {
|
||||||
|
@Override
|
||||||
|
protected Void onExecute(Context context, Bundle args) {
|
||||||
|
long id = args.getLong("id");
|
||||||
|
boolean exempted = args.getBoolean("exempted");
|
||||||
|
|
||||||
|
DB db = DB.getInstance(context);
|
||||||
|
db.account().setAccountPollExempted(id, exempted);
|
||||||
|
|
||||||
|
ServiceSynchronize.eval(context, "exempted");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onException(Bundle args, Throwable ex) {
|
||||||
|
Log.e(ex);
|
||||||
|
}
|
||||||
|
}.execute(context, owner, args, "set:exempted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AdapterAccountExempted(LifecycleOwner owner, Context context) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.context = context;
|
||||||
|
this.inflater = LayoutInflater.from(context);
|
||||||
|
|
||||||
|
setHasStableIds(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(@NonNull List<EntityAccount> accounts) {
|
||||||
|
Log.i("Set accounts=" + accounts.size());
|
||||||
|
|
||||||
|
DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(items, accounts), false);
|
||||||
|
items = accounts;
|
||||||
|
diff.dispatchUpdatesTo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DiffCallback extends DiffUtil.Callback {
|
||||||
|
private List<EntityAccount> prev = new ArrayList<>();
|
||||||
|
private List<EntityAccount> next = new ArrayList<>();
|
||||||
|
|
||||||
|
DiffCallback(List<EntityAccount> prev, List<EntityAccount> next) {
|
||||||
|
this.prev.addAll(prev);
|
||||||
|
this.next.addAll(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOldListSize() {
|
||||||
|
return prev.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNewListSize() {
|
||||||
|
return next.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
|
||||||
|
EntityAccount a1 = prev.get(oldItemPosition);
|
||||||
|
EntityAccount a2 = next.get(newItemPosition);
|
||||||
|
return a1.id.equals(a2.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
|
||||||
|
EntityAccount a1 = prev.get(oldItemPosition);
|
||||||
|
EntityAccount a2 = next.get(newItemPosition);
|
||||||
|
return (a1.ondemand == a2.ondemand &&
|
||||||
|
a1.poll_exempted == a2.poll_exempted &&
|
||||||
|
Objects.equals(a1.name, a2.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return items.get(position).id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return items.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
return new ViewHolder(inflater.inflate(R.layout.item_account_exempted, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
holder.unwire();
|
||||||
|
EntityAccount account = items.get(position);
|
||||||
|
holder.bindTo(account);
|
||||||
|
holder.wire();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1497,7 +1497,7 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
|
||||||
List<TupleAccountNetworkState> result = new ArrayList<>();
|
List<TupleAccountNetworkState> result = new ArrayList<>();
|
||||||
for (TupleAccountState accountState : accountStates)
|
for (TupleAccountState accountState : accountStates)
|
||||||
result.add(new TupleAccountNetworkState(
|
result.add(new TupleAccountNetworkState(
|
||||||
enabled && pollInterval == 0 && scheduled,
|
enabled && (pollInterval == 0 || accountState.poll_exempted) && scheduled,
|
||||||
command,
|
command,
|
||||||
networkState,
|
networkState,
|
||||||
accountState));
|
accountState));
|
||||||
|
|
|
@ -84,6 +84,29 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/spPollInterval" />
|
app:layout_constraintTop_toBottomOf="@id/spPollInterval" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvExempted"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_marginEnd="48dp"
|
||||||
|
android:text="@string/title_advanced_always"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvPollHint" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvExempted"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvExempted" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
android:id="@+id/swSchedule"
|
android:id="@+id/swSchedule"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -92,7 +115,7 @@
|
||||||
android:text="@string/title_advanced_schedule"
|
android:text="@string/title_advanced_schedule"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvPollHint"
|
app:layout_constraintTop_toBottomOf="@id/rvExempted"
|
||||||
app:switchPadding="12dp" />
|
app:switchPadding="12dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -419,5 +442,11 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/swCheckReply" />
|
app:layout_constraintTop_toBottomOf="@id/swCheckReply" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Group
|
||||||
|
android:id="@+id/grpExempted"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:constraint_referenced_ids="tvExempted,rvExempted" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/clItem"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/cbExempted"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="account"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</FrameLayout>
|
|
@ -246,6 +246,7 @@
|
||||||
|
|
||||||
<string name="title_advanced_receive">Receive messages</string>
|
<string name="title_advanced_receive">Receive messages</string>
|
||||||
<string name="title_advanced_when">When</string>
|
<string name="title_advanced_when">When</string>
|
||||||
|
<string name="title_advanced_always">Always synchronize these accounts</string>
|
||||||
<string name="title_advanced_schedule">Schedule</string>
|
<string name="title_advanced_schedule">Schedule</string>
|
||||||
<string name="title_advanced_unseen">All unread messages</string>
|
<string name="title_advanced_unseen">All unread messages</string>
|
||||||
<string name="title_advanced_flagged">All starred messages</string>
|
<string name="title_advanced_flagged">All starred messages</string>
|
||||||
|
|
Loading…
Reference in New Issue