mirror of https://github.com/M66B/FairEmail.git
Improved error handling
This commit is contained in:
parent
c81389769e
commit
ce9b7e82e2
6
FAQ.md
6
FAQ.md
|
@ -334,7 +334,11 @@ Unfortunately, it is impossible to make everybody happy and adding lots of setti
|
||||||
To use a Gmail/G suite account, you'll need to enable access for "less secure" apps,
|
To use a Gmail/G suite account, you'll need to enable access for "less secure" apps,
|
||||||
see [here](https://support.google.com/accounts/answer/6010255) for Google's instructions
|
see [here](https://support.google.com/accounts/answer/6010255) for Google's instructions
|
||||||
or go [directy to the setting](https://www.google.com/settings/security/lesssecureapps).
|
or go [directy to the setting](https://www.google.com/settings/security/lesssecureapps).
|
||||||
You can solve the error *535-5.7.8 Username and Password not accepted* by enabling "less secure" apps.
|
When "less secure" apps is not enabled,
|
||||||
|
you'll get the error *Authentication failed - invalid credentials* for accounts (IMAP)
|
||||||
|
and *Username and Password not accepted* for identities (SMTP).
|
||||||
|
|
||||||
|
If you use multiple Gmail accounts, make sure you change the "less secure" setting of the right account.
|
||||||
|
|
||||||
You might get the alert "*Please log in via your web browser*".
|
You might get the alert "*Please log in via your web browser*".
|
||||||
This security measure can for example be triggered when too many IP addresses were used in a too short time or when you are using a VPN.
|
This security measure can for example be triggered when too many IP addresses were used in a too short time or when you are using a VPN.
|
||||||
|
|
|
@ -448,15 +448,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
|
||||||
|
|
||||||
} else if ("outbox".equals(action))
|
} else if ("outbox".equals(action))
|
||||||
onMenuOutbox();
|
onMenuOutbox();
|
||||||
|
else if (action.startsWith("thread")) {
|
||||||
else if ("error".equals(action)) {
|
|
||||||
Intent ifaq = new Intent(Intent.ACTION_VIEW);
|
|
||||||
ifaq.setData(Uri.parse(Helper.FAQ_URI + "#frequently-asked-questions"));
|
|
||||||
ifaq.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
if (ifaq.resolveActivity(getPackageManager()) != null)
|
|
||||||
startActivity(ifaq);
|
|
||||||
|
|
||||||
} else if (action.startsWith("thread")) {
|
|
||||||
intent.putExtra("thread", action.split(":", 2)[1]);
|
intent.putExtra("thread", action.split(":", 2)[1]);
|
||||||
onViewThread(intent);
|
onViewThread(intent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3069,6 +3069,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
|
||||||
message.id = null;
|
message.id = null;
|
||||||
message.folder = drafts.id;
|
message.folder = drafts.id;
|
||||||
message.ui_snoozed = null;
|
message.ui_snoozed = null;
|
||||||
|
message.error = null;
|
||||||
message.id = db.message().insertMessage(message);
|
message.id = db.message().insertMessage(message);
|
||||||
|
|
||||||
File target = message.getFile(context);
|
File target = message.getFile(context);
|
||||||
|
|
|
@ -2129,11 +2129,11 @@ class Core {
|
||||||
|
|
||||||
String title;
|
String title;
|
||||||
if (account == null)
|
if (account == null)
|
||||||
title = folder.name;
|
title = Helper.localizeFolderName(context, folder.name);
|
||||||
else if (folder == null)
|
else if (folder == null)
|
||||||
title = account.name;
|
title = account.name;
|
||||||
else
|
else
|
||||||
title = account.name + "/" + folder.name;
|
title = account.name + "/" + Helper.localizeFolderName(context, folder.name);
|
||||||
|
|
||||||
String tag = "error:" + (account == null ? 0 : account.id) + ":" + (folder == null ? 0 : folder.id);
|
String tag = "error:" + (account == null ? 0 : account.id) + ":" + (folder == null ? 0 : folder.id);
|
||||||
|
|
||||||
|
@ -2146,7 +2146,7 @@ class Core {
|
||||||
if (ex instanceof AuthenticationFailedException || // Also: Too many simultaneous connections
|
if (ex instanceof AuthenticationFailedException || // Also: Too many simultaneous connections
|
||||||
ex instanceof AlertException ||
|
ex instanceof AlertException ||
|
||||||
ex instanceof SendFailedException)
|
ex instanceof SendFailedException)
|
||||||
nm.notify(tag, 1, getNotificationError(context, title, ex).build());
|
nm.notify(tag, 1, getNotificationError(context, "error", title, ex).build());
|
||||||
|
|
||||||
// connection failure: Too many simultaneous connections
|
// connection failure: Too many simultaneous connections
|
||||||
|
|
||||||
|
@ -2164,18 +2164,12 @@ class Core {
|
||||||
!(ex instanceof MessagingException && ex.getCause() instanceof SocketTimeoutException) &&
|
!(ex instanceof MessagingException && ex.getCause() instanceof SocketTimeoutException) &&
|
||||||
!(ex instanceof MessagingException && ex.getCause() instanceof SSLException) &&
|
!(ex instanceof MessagingException && ex.getCause() instanceof SSLException) &&
|
||||||
!(ex instanceof MessagingException && "connection failure".equals(ex.getMessage())))
|
!(ex instanceof MessagingException && "connection failure".equals(ex.getMessage())))
|
||||||
nm.notify(tag, 1, getNotificationError(context, title, ex).build());
|
nm.notify(tag, 1, getNotificationError(context, "error", title, ex).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
static NotificationCompat.Builder getNotificationError(Context context, String title, Throwable ex) {
|
static NotificationCompat.Builder getNotificationError(Context context, String channel, String title, Throwable ex) {
|
||||||
return getNotificationError(context, "error", title, ex, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NotificationCompat.Builder getNotificationError(Context context, String channel, String title, Throwable ex, boolean debug) {
|
|
||||||
// Build pending intent
|
// Build pending intent
|
||||||
Intent intent = new Intent(context, ActivityView.class);
|
Intent intent = new Intent(context, ActivityView.class);
|
||||||
if (debug)
|
|
||||||
intent.setAction("error");
|
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
PendingIntent pi = PendingIntent.getActivity(
|
PendingIntent pi = PendingIntent.getActivity(
|
||||||
context, ActivityView.REQUEST_ERROR, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
context, ActivityView.REQUEST_ERROR, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
|
@ -156,6 +156,7 @@ public class EntityOperation {
|
||||||
boolean seen = message.seen;
|
boolean seen = message.seen;
|
||||||
boolean ui_seen = message.ui_seen;
|
boolean ui_seen = message.ui_seen;
|
||||||
boolean ui_browsed = message.ui_browsed;
|
boolean ui_browsed = message.ui_browsed;
|
||||||
|
String error = message.error;
|
||||||
|
|
||||||
message.id = null;
|
message.id = null;
|
||||||
message.account = target.account;
|
message.account = target.account;
|
||||||
|
@ -167,6 +168,7 @@ public class EntityOperation {
|
||||||
message.ui_seen = true;
|
message.ui_seen = true;
|
||||||
}
|
}
|
||||||
message.ui_browsed = false;
|
message.ui_browsed = false;
|
||||||
|
message.error = null;
|
||||||
message.id = db.message().insertMessage(message);
|
message.id = db.message().insertMessage(message);
|
||||||
File mtarget = message.getFile(context);
|
File mtarget = message.getFile(context);
|
||||||
long tmpid = message.id;
|
long tmpid = message.id;
|
||||||
|
@ -179,6 +181,7 @@ public class EntityOperation {
|
||||||
message.seen = seen;
|
message.seen = seen;
|
||||||
message.ui_seen = ui_seen;
|
message.ui_seen = ui_seen;
|
||||||
message.ui_browsed = ui_browsed;
|
message.ui_browsed = ui_browsed;
|
||||||
|
message.error = error;
|
||||||
|
|
||||||
if (message.content)
|
if (message.content)
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -639,27 +639,8 @@ public class FragmentAccount extends FragmentBase {
|
||||||
|
|
||||||
if (ex instanceof IllegalArgumentException)
|
if (ex instanceof IllegalArgumentException)
|
||||||
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
|
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||||
else {
|
else
|
||||||
tvError.setText(Helper.formatThrowable(ex));
|
showError(ex);
|
||||||
tvError.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
final View target;
|
|
||||||
|
|
||||||
EmailProvider provider = (EmailProvider) spProvider.getSelectedItem();
|
|
||||||
if (provider != null && provider.documentation != null) {
|
|
||||||
tvInstructions.setText(HtmlHelper.fromHtml(provider.documentation.toString()));
|
|
||||||
tvInstructions.setVisibility(View.VISIBLE);
|
|
||||||
target = tvInstructions;
|
|
||||||
} else
|
|
||||||
target = tvError;
|
|
||||||
|
|
||||||
new Handler().post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
scroll.smoothScrollTo(0, target.getBottom());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.execute(FragmentAccount.this, args, "account:check");
|
}.execute(FragmentAccount.this, args, "account:check");
|
||||||
}
|
}
|
||||||
|
@ -858,9 +839,11 @@ public class FragmentAccount extends FragmentBase {
|
||||||
String accountRealm = (account == null ? null : account.realm);
|
String accountRealm = (account == null ? null : account.realm);
|
||||||
|
|
||||||
boolean check = (synchronize && (account == null ||
|
boolean check = (synchronize && (account == null ||
|
||||||
|
!account.synchronize ||
|
||||||
!host.equals(account.host) || Integer.parseInt(port) != account.port ||
|
!host.equals(account.host) || Integer.parseInt(port) != account.port ||
|
||||||
!user.equals(account.user) || !password.equals(account.password) ||
|
!user.equals(account.user) || !password.equals(account.password) ||
|
||||||
!Objects.equals(realm, accountRealm)));
|
!Objects.equals(realm, accountRealm) ||
|
||||||
|
!TextUtils.isEmpty(account.error)));
|
||||||
boolean reload = (check || account == null ||
|
boolean reload = (check || account == null ||
|
||||||
account.synchronize != synchronize ||
|
account.synchronize != synchronize ||
|
||||||
account.notify != notify ||
|
account.notify != notify ||
|
||||||
|
@ -1078,20 +1061,34 @@ public class FragmentAccount extends FragmentBase {
|
||||||
protected void onException(Bundle args, Throwable ex) {
|
protected void onException(Bundle args, Throwable ex) {
|
||||||
if (ex instanceof IllegalArgumentException)
|
if (ex instanceof IllegalArgumentException)
|
||||||
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
|
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||||
else {
|
else
|
||||||
tvError.setText(Helper.formatThrowable(ex));
|
showError(ex);
|
||||||
tvError.setVisibility(View.VISIBLE);
|
|
||||||
new Handler().post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
scroll.smoothScrollTo(0, tvError.getBottom());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.execute(FragmentAccount.this, args, "account:save");
|
}.execute(FragmentAccount.this, args, "account:save");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showError(Throwable ex) {
|
||||||
|
tvError.setText(Helper.formatThrowable(ex));
|
||||||
|
tvError.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
final View target;
|
||||||
|
|
||||||
|
EmailProvider provider = (EmailProvider) spProvider.getSelectedItem();
|
||||||
|
if (provider != null && provider.documentation != null) {
|
||||||
|
tvInstructions.setText(HtmlHelper.fromHtml(provider.documentation.toString()));
|
||||||
|
tvInstructions.setVisibility(View.VISIBLE);
|
||||||
|
target = tvInstructions;
|
||||||
|
} else
|
||||||
|
target = tvError;
|
||||||
|
|
||||||
|
new Handler().post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
scroll.smoothScrollTo(0, target.getBottom());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
outState.putInt("fair:provider", spProvider.getSelectedItemPosition());
|
outState.putInt("fair:provider", spProvider.getSelectedItemPosition());
|
||||||
|
|
|
@ -29,6 +29,7 @@ import android.os.Handler;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.util.Patterns;
|
import android.util.Patterns;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
@ -117,6 +118,7 @@ public class FragmentIdentity extends FragmentBase {
|
||||||
private Button btnSave;
|
private Button btnSave;
|
||||||
private ContentLoadingProgressBar pbSave;
|
private ContentLoadingProgressBar pbSave;
|
||||||
private TextView tvError;
|
private TextView tvError;
|
||||||
|
private TextView tvInstructions;
|
||||||
|
|
||||||
private ContentLoadingProgressBar pbWait;
|
private ContentLoadingProgressBar pbWait;
|
||||||
|
|
||||||
|
@ -187,6 +189,8 @@ public class FragmentIdentity extends FragmentBase {
|
||||||
btnSave = view.findViewById(R.id.btnSave);
|
btnSave = view.findViewById(R.id.btnSave);
|
||||||
pbSave = view.findViewById(R.id.pbSave);
|
pbSave = view.findViewById(R.id.pbSave);
|
||||||
tvError = view.findViewById(R.id.tvError);
|
tvError = view.findViewById(R.id.tvError);
|
||||||
|
tvInstructions = view.findViewById(R.id.tvInstructions);
|
||||||
|
tvInstructions.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
|
||||||
pbWait = view.findViewById(R.id.pbWait);
|
pbWait = view.findViewById(R.id.pbWait);
|
||||||
|
|
||||||
|
@ -201,6 +205,7 @@ public class FragmentIdentity extends FragmentBase {
|
||||||
grpAuthorize.setVisibility(position > 0 ? View.VISIBLE : View.GONE);
|
grpAuthorize.setVisibility(position > 0 ? View.VISIBLE : View.GONE);
|
||||||
if (position == 0) {
|
if (position == 0) {
|
||||||
tvError.setVisibility(View.GONE);
|
tvError.setVisibility(View.GONE);
|
||||||
|
tvInstructions.setVisibility(View.GONE);
|
||||||
grpAdvanced.setVisibility(View.GONE);
|
grpAdvanced.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
tilPassword.setEndIconMode(position == 0 ? END_ICON_PASSWORD_TOGGLE : END_ICON_NONE);
|
tilPassword.setEndIconMode(position == 0 ? END_ICON_PASSWORD_TOGGLE : END_ICON_NONE);
|
||||||
|
@ -429,6 +434,7 @@ public class FragmentIdentity extends FragmentBase {
|
||||||
btnSave.setVisibility(View.GONE);
|
btnSave.setVisibility(View.GONE);
|
||||||
pbSave.setVisibility(View.GONE);
|
pbSave.setVisibility(View.GONE);
|
||||||
tvError.setVisibility(View.GONE);
|
tvError.setVisibility(View.GONE);
|
||||||
|
tvInstructions.setVisibility(View.GONE);
|
||||||
|
|
||||||
grpAuthorize.setVisibility(View.GONE);
|
grpAuthorize.setVisibility(View.GONE);
|
||||||
grpAdvanced.setVisibility(View.GONE);
|
grpAdvanced.setVisibility(View.GONE);
|
||||||
|
@ -525,6 +531,7 @@ public class FragmentIdentity extends FragmentBase {
|
||||||
Helper.setViewsEnabled(view, false);
|
Helper.setViewsEnabled(view, false);
|
||||||
pbSave.setVisibility(View.VISIBLE);
|
pbSave.setVisibility(View.VISIBLE);
|
||||||
tvError.setVisibility(View.GONE);
|
tvError.setVisibility(View.GONE);
|
||||||
|
tvInstructions.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -659,10 +666,12 @@ public class FragmentIdentity extends FragmentBase {
|
||||||
String identityRealm = (identity == null ? null : identity.realm);
|
String identityRealm = (identity == null ? null : identity.realm);
|
||||||
|
|
||||||
boolean check = (synchronize && (identity == null ||
|
boolean check = (synchronize && (identity == null ||
|
||||||
|
!identity.synchronize ||
|
||||||
!host.equals(identity.host) || Integer.parseInt(port) != identity.port ||
|
!host.equals(identity.host) || Integer.parseInt(port) != identity.port ||
|
||||||
!user.equals(identity.user) || !password.equals(identity.password) ||
|
!user.equals(identity.user) || !password.equals(identity.password) ||
|
||||||
!Objects.equals(realm, identityRealm) ||
|
!Objects.equals(realm, identityRealm) ||
|
||||||
use_ip != identity.use_ip));
|
use_ip != identity.use_ip) ||
|
||||||
|
!TextUtils.isEmpty(identity.error));
|
||||||
|
|
||||||
Long last_connected = null;
|
Long last_connected = null;
|
||||||
if (identity != null && synchronize == identity.synchronize)
|
if (identity != null && synchronize == identity.synchronize)
|
||||||
|
@ -784,20 +793,34 @@ public class FragmentIdentity extends FragmentBase {
|
||||||
protected void onException(Bundle args, Throwable ex) {
|
protected void onException(Bundle args, Throwable ex) {
|
||||||
if (ex instanceof IllegalArgumentException)
|
if (ex instanceof IllegalArgumentException)
|
||||||
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
|
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||||
else {
|
else
|
||||||
tvError.setText(Helper.formatThrowable(ex));
|
showError(ex);
|
||||||
tvError.setVisibility(View.VISIBLE);
|
|
||||||
new Handler().post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
scroll.smoothScrollTo(0, tvError.getBottom());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.execute(FragmentIdentity.this, args, "identity:save");
|
}.execute(FragmentIdentity.this, args, "identity:save");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showError(Throwable ex) {
|
||||||
|
tvError.setText(Helper.formatThrowable(ex));
|
||||||
|
tvError.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
final View target;
|
||||||
|
|
||||||
|
EmailProvider provider = (EmailProvider) spProvider.getSelectedItem();
|
||||||
|
if (provider != null && provider.documentation != null) {
|
||||||
|
tvInstructions.setText(HtmlHelper.fromHtml(provider.documentation.toString()));
|
||||||
|
tvInstructions.setVisibility(View.VISIBLE);
|
||||||
|
target = tvInstructions;
|
||||||
|
} else
|
||||||
|
target = tvError;
|
||||||
|
|
||||||
|
new Handler().post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
scroll.smoothScrollTo(0, target.getBottom());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
outState.putInt("fair:account", spAccount.getSelectedItemPosition());
|
outState.putInt("fair:account", spAccount.getSelectedItemPosition());
|
||||||
|
|
|
@ -416,7 +416,7 @@ public class ServiceSend extends LifecycleService {
|
||||||
Log.i("Reporting send error after=" + delayed);
|
Log.i("Reporting send error after=" + delayed);
|
||||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
nm.notify("send", message.identity.intValue(),
|
nm.notify("send", message.identity.intValue(),
|
||||||
Core.getNotificationError(this, ident.name, ex).build());
|
Core.getNotificationError(this, "error", ident.name, ex).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw ex;
|
throw ex;
|
||||||
|
|
|
@ -711,7 +711,7 @@ public class ServiceSynchronize extends LifecycleService {
|
||||||
.format(account.last_connected)), ex);
|
.format(account.last_connected)), ex);
|
||||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
nm.notify("receive", account.id.intValue(),
|
nm.notify("receive", account.id.intValue(),
|
||||||
Core.getNotificationError(this, "warning", account.name, warning, false)
|
Core.getNotificationError(this, "warning", account.name, warning)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -707,7 +707,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:text="provider instructions"
|
android:text="provider instructions"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvError" />
|
app:layout_constraintTop_toBottomOf="@id/tvError" />
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,10 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/title_legend_close_hint"
|
android:contentDescription="@string/title_legend_close_hint"
|
||||||
app:srcCompat="@drawable/baseline_close_24"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/tvHintActions"
|
app:layout_constraintBottom_toBottomOf="@id/tvHintActions"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/tvHintActions" />
|
app:layout_constraintTop_toTopOf="@id/tvHintActions"
|
||||||
|
app:srcCompat="@drawable/baseline_close_24" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/vSeparatorActions"
|
android:id="@+id/vSeparatorActions"
|
||||||
|
@ -71,10 +71,10 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/title_legend_close_hint"
|
android:contentDescription="@string/title_legend_close_hint"
|
||||||
app:srcCompat="@drawable/baseline_close_24"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/tvHintSync"
|
app:layout_constraintBottom_toBottomOf="@id/tvHintSync"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/tvHintSync" />
|
app:layout_constraintTop_toTopOf="@id/tvHintSync"
|
||||||
|
app:srcCompat="@drawable/baseline_close_24" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/vSeparatorSync"
|
android:id="@+id/vSeparatorSync"
|
||||||
|
@ -135,10 +135,10 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="end|bottom"
|
android:layout_gravity="end|bottom"
|
||||||
android:layout_margin="@dimen/fab_padding"
|
android:layout_margin="@dimen/fab_padding"
|
||||||
app:srcCompat="@drawable/baseline_create_new_folder_24"
|
|
||||||
android:tint="@color/colorActionForeground"
|
android:tint="@color/colorActionForeground"
|
||||||
android:tooltipText="@string/title_add"
|
android:tooltipText="@string/title_add"
|
||||||
app:backgroundTint="?attr/colorAccent" />
|
app:backgroundTint="?attr/colorAccent"
|
||||||
|
app:srcCompat="@drawable/baseline_create_new_folder_24" />
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/fabError"
|
android:id="@+id/fabError"
|
||||||
|
@ -146,8 +146,8 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal|bottom"
|
android:layout_gravity="center_horizontal|bottom"
|
||||||
android:layout_margin="@dimen/fab_padding"
|
android:layout_margin="@dimen/fab_padding"
|
||||||
v="@drawable/baseline_warning_24"
|
|
||||||
android:tint="@color/colorActionForeground"
|
android:tint="@color/colorActionForeground"
|
||||||
android:tooltipText="@string/title_compose"
|
android:tooltipText="@string/title_compose"
|
||||||
app:backgroundTint="@color/lightColorWarning" />
|
app:backgroundTint="@color/lightColorWarning"
|
||||||
|
app:srcCompat="@drawable/baseline_warning_24" />
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -612,6 +612,16 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/btnSave" />
|
app:layout_constraintTop_toBottomOf="@id/btnSave" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvInstructions"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:text="provider instructions"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvError" />
|
||||||
|
|
||||||
<eu.faircode.email.ContentLoadingProgressBar
|
<eu.faircode.email.ContentLoadingProgressBar
|
||||||
android:id="@+id/pbWait"
|
android:id="@+id/pbWait"
|
||||||
style="@style/Base.Widget.AppCompat.ProgressBar"
|
style="@style/Base.Widget.AppCompat.ProgressBar"
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:text="provider instructions"
|
android:text="provider instructions"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvError" />
|
app:layout_constraintTop_toBottomOf="@id/tvError" />
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue