Improved account/identity help

pull/157/head
M66B 6 years ago
parent 0fbff8cfdf
commit 963d36cb4b

@ -337,27 +337,36 @@ Unfortunately, it is impossible to make everybody happy and adding lots of setti
<a name="faq6"></a> <a name="faq6"></a>
**(6) How can I login to Gmail / G suite?** **(6) How can I login to Gmail / G suite?**
To use a Gmail/G suite account, you'll need to enable access for "less secure" apps, To use a Gmail/G suite account,
see [here](https://support.google.com/accounts/answer/6010255) for Google's instructions you can either enable access for "less secure apps" and use your account password
or enable two factor authentication and use an app specific password.
Note that an app specific password is required when two factor authentication is enabled.
**Enable "Less secure apps"**
See [here](https://support.google.com/accounts/answer/6010255) about how to enable "less secure apps"
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).
When "less secure" apps is not enabled,
If you use multiple Gmail accounts, make sure you change the "less secure apps" setting of the right account(s).
Be aware that you need to leave the "less secure apps" settings screen by using the back arrow to apply the setting.
When "less secure apps" is not enabled,
you'll get the error *Authentication failed - invalid credentials* for accounts (IMAP) you'll get the error *Authentication failed - invalid credentials* for accounts (IMAP)
and *Username and Password not accepted* for identities (SMTP). 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(s). **App specific password**
Be aware that you need to leave the "less secure" settings screen by using the back arrow to apply the setting.
See [this FAQ](#user-content-faq111) for more information. See [here](https://support.google.com/accounts/answer/185833) about how to generate an app specific password.
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 happens when Google considers the network that connects you to the internet (this could be a VPN) to to be unsafe.
You can prevent this by using an app specific password. This can be prevented by using an app specific password.
To login to Gmail / G suite you'll sometimes need an app specific password, for example when two factor authentication is enabled. See [here](https://support.google.com/mail/accounts/answer/78754) for troubleshooting.
See here for instructions: [https://support.google.com/accounts/answer/185833](https://support.google.com/accounts/answer/185833).
If this doesn't work, see here for more solutions: [https://support.google.com/mail/accounts/answer/78754](https://support.google.com/mail/accounts/answer/78754) See [this FAQ](#user-content-faq111) about why OAuth is not being used.
<br /> <br />
@ -378,7 +387,7 @@ which happens when reconnecting or if you synchronize manually.
**(8) Can I use a Microsoft Exchange account?** **(8) Can I use a Microsoft Exchange account?**
You can use a Microsoft Exchange account if it is accessible via IMAP. You can use a Microsoft Exchange account if it is accessible via IMAP.
See here for more information: [https://support.office.com/en-us/article/what-is-a-microsoft-exchange-account-47f000aa-c2bf-48ac-9bc2-83e5c6036793](https://support.office.com/en-us/article/what-is-a-microsoft-exchange-account-47f000aa-c2bf-48ac-9bc2-83e5c6036793) See [here](https://support.office.com/en-us/article/what-is-a-microsoft-exchange-account-47f000aa-c2bf-48ac-9bc2-83e5c6036793) for more information.
Please see [here](#frequently-requested-features) about ActiveSync support. Please see [here](#frequently-requested-features) about ActiveSync support.
@ -1569,7 +1578,7 @@ You will likely need to save the associated identity again as well.
For the correct settings, see [here](https://help.yahoo.com/kb/SLN4075.html). For the correct settings, see [here](https://help.yahoo.com/kb/SLN4075.html).
You might need to enable "*less secure sign in*" for "*outdated*" apps, You might need to enable "*less secure sign in*" for "*outdated*" apps,
see [here](https://help.yahoo.com/kb/grant-temporary-access-outdated-apps-account-settings-sln27791.html). see [here](https://help.yahoo.com/kb/grant-temporary-access-outdated-apps-account-settings-sln27791.html) for more information.
You can directly access this setting [here](https://login.yahoo.com/account/security#less-secure-apps). You can directly access this setting [here](https://login.yahoo.com/account/security#less-secure-apps).
Note that FairEmail is using the standard [IMAP protocol](https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol), which is really not outdated. Note that FairEmail is using the standard [IMAP protocol](https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol), which is really not outdated.

@ -59,6 +59,7 @@ public class EmailProvider {
public int smtp_port; public int smtp_port;
public boolean smtp_starttls; public boolean smtp_starttls;
public UserType user = UserType.EMAIL; public UserType user = UserType.EMAIL;
public String helpUrl = null;
public StringBuilder documentation = null; // html public StringBuilder documentation = null; // html
enum UserType {LOCAL, EMAIL} enum UserType {LOCAL, EMAIL}
@ -410,14 +411,14 @@ public class EmailProvider {
private static EmailProvider addSpecials(Context context, EmailProvider provider) { private static EmailProvider addSpecials(Context context, EmailProvider provider) {
if ("imap.gmail.com".equals(provider.imap_host)) if ("imap.gmail.com".equals(provider.imap_host))
addDocumentation(provider, provider.helpUrl = Helper.FAQ_URI + "#user-content-faq6";
"https://github.com/M66B/open-source-email/blob/master/FAQ.md#user-content-faq6",
context.getString(R.string.title_setup_instructions)); if (provider.imap_host.endsWith("office365.com") ||
provider.imap_host.endsWith("live.com"))
provider.helpUrl = Helper.FAQ_URI + "#user-content-faq14";
if (provider.imap_host.endsWith("yahoo.com")) if (provider.imap_host.endsWith("yahoo.com"))
addDocumentation(provider, provider.helpUrl = Helper.FAQ_URI + "#user-content-faq88";
"https://github.com/M66B/open-source-email/blob/master/FAQ.md#user-content-faq88",
context.getString(R.string.title_setup_instructions));
return provider; return provider;
} }

@ -24,6 +24,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@ -127,6 +128,7 @@ public class FragmentAccount extends FragmentBase {
private Button btnSave; private Button btnSave;
private ContentLoadingProgressBar pbSave; private ContentLoadingProgressBar pbSave;
private TextView tvError; private TextView tvError;
private Button btnHelp;
private TextView tvInstructions; private TextView tvInstructions;
private ContentLoadingProgressBar pbWait; private ContentLoadingProgressBar pbWait;
@ -207,7 +209,9 @@ public class FragmentAccount 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);
btnHelp = view.findViewById(R.id.btnHelp);
tvInstructions = view.findViewById(R.id.tvInstructions); tvInstructions = view.findViewById(R.id.tvInstructions);
pbWait = view.findViewById(R.id.pbWait); pbWait = view.findViewById(R.id.pbWait);
@ -351,6 +355,22 @@ public class FragmentAccount extends FragmentBase {
} }
}); });
addBackPressedListener(new ActivityBase.IBackPressedListener() {
@Override
public boolean onBackPressed() {
onSave(true);
return true;
}
});
btnHelp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, (Uri) btnHelp.getTag());
Helper.view(getContext(), intent);
}
});
adapter = new ArrayAdapter<>(getContext(), R.layout.spinner_item1, android.R.id.text1, new ArrayList<EntityFolder>()); adapter = new ArrayAdapter<>(getContext(), R.layout.spinner_item1, android.R.id.text1, new ArrayList<EntityFolder>());
adapter.setDropDownViewResource(R.layout.spinner_item1_dropdown); adapter.setDropDownViewResource(R.layout.spinner_item1_dropdown);
@ -366,14 +386,6 @@ public class FragmentAccount extends FragmentBase {
spLeft.setAdapter(adapterSwipe); spLeft.setAdapter(adapterSwipe);
spRight.setAdapter(adapterSwipe); spRight.setAdapter(adapterSwipe);
addBackPressedListener(new ActivityBase.IBackPressedListener() {
@Override
public boolean onBackPressed() {
onSave(true);
return true;
}
});
// Initialize // Initialize
Helper.setViewsEnabled(view, false); Helper.setViewsEnabled(view, false);
@ -393,7 +405,9 @@ public class FragmentAccount 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);
btnHelp.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE);
tvInstructions.setMovementMethod(LinkMovementMethod.getInstance()); tvInstructions.setMovementMethod(LinkMovementMethod.getInstance());
@ -467,6 +481,7 @@ public class FragmentAccount extends FragmentBase {
tvUtf8.setVisibility(View.GONE); tvUtf8.setVisibility(View.GONE);
grpFolders.setVisibility(View.GONE); grpFolders.setVisibility(View.GONE);
tvError.setVisibility(View.GONE); tvError.setVisibility(View.GONE);
btnHelp.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE);
} }
@ -701,6 +716,8 @@ public class FragmentAccount 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);
btnHelp.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE);
} }
@Override @Override
@ -838,17 +855,17 @@ 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 || !account.synchronize || account.error != null ||
account.insecure != insecure || !account.insecure.equals(insecure) ||
!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)));
account.error != null));
boolean reload = (check || account == null || boolean reload = (check || account == null ||
account.synchronize != synchronize || account.synchronize != synchronize ||
account.notify != notify || account.notify != notify ||
!account.poll_interval.equals(Integer.parseInt(interval)) || !account.poll_interval.equals(Integer.parseInt(interval)) ||
account.partial_fetch != partial_fetch); account.partial_fetch != partial_fetch);
Log.i("Account check=" + check + " reload=" + reload);
Long last_connected = null; Long last_connected = null;
if (account != null && synchronize == account.synchronize) if (account != null && synchronize == account.synchronize)
@ -1053,20 +1070,27 @@ public class FragmentAccount extends FragmentBase {
tvError.setText(Helper.formatThrowable(ex, false)); tvError.setText(Helper.formatThrowable(ex, false));
tvError.setVisibility(View.VISIBLE); tvError.setVisibility(View.VISIBLE);
final View target; final EmailProvider provider = (EmailProvider) spProvider.getSelectedItem();
if (provider != null && provider.helpUrl != null) {
Uri uri = Uri.parse(provider.helpUrl);
btnHelp.setTag(uri);
btnHelp.setVisibility(View.VISIBLE);
}
EmailProvider provider = (EmailProvider) spProvider.getSelectedItem();
if (provider != null && provider.documentation != null) { if (provider != null && provider.documentation != null) {
tvInstructions.setText(HtmlHelper.fromHtml(provider.documentation.toString())); tvInstructions.setText(HtmlHelper.fromHtml(provider.documentation.toString()));
tvInstructions.setVisibility(View.VISIBLE); tvInstructions.setVisibility(View.VISIBLE);
target = tvInstructions; }
} else
target = tvError;
new Handler().post(new Runnable() { new Handler().post(new Runnable() {
@Override @Override
public void run() { public void run() {
scroll.smoothScrollTo(0, target.getBottom()); if (provider != null && provider.documentation != null)
scroll.smoothScrollTo(0, tvInstructions.getBottom());
else if (provider != null && provider.helpUrl != null)
scroll.smoothScrollTo(0, btnHelp.getBottom());
else
scroll.smoothScrollTo(0, tvError.getBottom());
} }
}); });
} }

@ -26,6 +26,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.text.Editable; import android.text.Editable;
@ -122,6 +123,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 Button btnHelp;
private TextView tvInstructions; private TextView tvInstructions;
private ContentLoadingProgressBar pbWait; private ContentLoadingProgressBar pbWait;
@ -198,6 +200,7 @@ 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);
btnHelp = view.findViewById(R.id.btnHelp);
tvInstructions = view.findViewById(R.id.tvInstructions); tvInstructions = view.findViewById(R.id.tvInstructions);
tvInstructions.setMovementMethod(LinkMovementMethod.getInstance()); tvInstructions.setMovementMethod(LinkMovementMethod.getInstance());
@ -214,6 +217,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);
btnHelp.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE);
grpAdvanced.setVisibility(View.GONE); grpAdvanced.setVisibility(View.GONE);
} }
@ -400,6 +404,14 @@ public class FragmentIdentity extends FragmentBase {
} }
}); });
btnHelp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, (Uri) btnHelp.getTag());
Helper.view(getContext(), intent);
}
});
// Initialize // Initialize
Helper.setViewsEnabled(view, false); Helper.setViewsEnabled(view, false);
btnAutoConfig.setEnabled(false); btnAutoConfig.setEnabled(false);
@ -411,6 +423,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);
btnHelp.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE);
grpAuthorize.setVisibility(View.GONE); grpAuthorize.setVisibility(View.GONE);
@ -508,6 +521,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);
btnHelp.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE);
} }
@ -645,13 +659,13 @@ 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 || !identity.synchronize || identity.error != null ||
identity.insecure != insecure || !identity.insecure.equals(insecure) ||
!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));
identity.error != null)); Log.i("Identity check=" + check);
Long last_connected = null; Long last_connected = null;
if (identity != null && synchronize == identity.synchronize) if (identity != null && synchronize == identity.synchronize)
@ -774,20 +788,27 @@ public class FragmentIdentity extends FragmentBase {
tvError.setText(Helper.formatThrowable(ex, false)); tvError.setText(Helper.formatThrowable(ex, false));
tvError.setVisibility(View.VISIBLE); tvError.setVisibility(View.VISIBLE);
final View target; final EmailProvider provider = (EmailProvider) spProvider.getSelectedItem();
if (provider != null && provider.helpUrl != null) {
Uri uri = Uri.parse(provider.helpUrl);
btnHelp.setTag(uri);
btnHelp.setVisibility(View.VISIBLE);
}
EmailProvider provider = (EmailProvider) spProvider.getSelectedItem();
if (provider != null && provider.documentation != null) { if (provider != null && provider.documentation != null) {
tvInstructions.setText(HtmlHelper.fromHtml(provider.documentation.toString())); tvInstructions.setText(HtmlHelper.fromHtml(provider.documentation.toString()));
tvInstructions.setVisibility(View.VISIBLE); tvInstructions.setVisibility(View.VISIBLE);
target = tvInstructions; }
} else
target = tvError;
new Handler().post(new Runnable() { new Handler().post(new Runnable() {
@Override @Override
public void run() { public void run() {
scroll.smoothScrollTo(0, target.getBottom()); if (provider != null && provider.documentation != null)
scroll.smoothScrollTo(0, tvInstructions.getBottom());
else if (provider != null && provider.helpUrl != null)
scroll.smoothScrollTo(0, btnHelp.getBottom());
else
scroll.smoothScrollTo(0, tvError.getBottom());
} }
}); });
} }

@ -24,7 +24,9 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.util.Patterns; import android.util.Patterns;
@ -38,6 +40,7 @@ import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -64,6 +67,7 @@ import static android.app.Activity.RESULT_OK;
public class FragmentQuickSetup extends FragmentBase { public class FragmentQuickSetup extends FragmentBase {
private ViewGroup view; private ViewGroup view;
private ScrollView scroll;
private EditText etName; private EditText etName;
private EditText etEmail; private EditText etEmail;
@ -71,6 +75,7 @@ public class FragmentQuickSetup extends FragmentBase {
private Button btnCheck; private Button btnCheck;
private TextView tvError; private TextView tvError;
private Button btnHelp;
private TextView tvInstructions; private TextView tvInstructions;
private TextView tvImap; private TextView tvImap;
@ -87,6 +92,7 @@ public class FragmentQuickSetup extends FragmentBase {
setHasOptionsMenu(true); setHasOptionsMenu(true);
view = (ViewGroup) inflater.inflate(R.layout.fragment_quick_setup, container, false); view = (ViewGroup) inflater.inflate(R.layout.fragment_quick_setup, container, false);
scroll = view.findViewById(R.id.scroll);
// Get controls // Get controls
etName = view.findViewById(R.id.etName); etName = view.findViewById(R.id.etName);
@ -95,6 +101,7 @@ public class FragmentQuickSetup extends FragmentBase {
btnCheck = view.findViewById(R.id.btnCheck); btnCheck = view.findViewById(R.id.btnCheck);
tvError = view.findViewById(R.id.tvError); tvError = view.findViewById(R.id.tvError);
btnHelp = view.findViewById(R.id.btnHelp);
tvInstructions = view.findViewById(R.id.tvInstructions); tvInstructions = view.findViewById(R.id.tvInstructions);
tvImap = view.findViewById(R.id.tvImap); tvImap = view.findViewById(R.id.tvImap);
@ -130,8 +137,17 @@ public class FragmentQuickSetup extends FragmentBase {
} }
}); });
btnHelp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, (Uri) btnHelp.getTag());
Helper.view(getContext(), intent);
}
});
// Initialize // Initialize
tvError.setVisibility(View.GONE); tvError.setVisibility(View.GONE);
btnHelp.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE);
tvInstructions.setMovementMethod(LinkMovementMethod.getInstance()); tvInstructions.setMovementMethod(LinkMovementMethod.getInstance());
grpSetup.setVisibility(View.GONE); grpSetup.setVisibility(View.GONE);
@ -181,6 +197,7 @@ public class FragmentQuickSetup extends FragmentBase {
Helper.setViewsEnabled(view, false); Helper.setViewsEnabled(view, false);
tvError.setVisibility(View.GONE); tvError.setVisibility(View.GONE);
btnHelp.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE);
grpSetup.setVisibility(check ? View.GONE : View.VISIBLE); grpSetup.setVisibility(check ? View.GONE : View.VISIBLE);
} }
@ -207,6 +224,8 @@ public class FragmentQuickSetup extends FragmentBase {
String[] dparts = email.split("@"); String[] dparts = email.split("@");
EmailProvider provider = EmailProvider.fromDomain(context, dparts[1]); EmailProvider provider = EmailProvider.fromDomain(context, dparts[1]);
if (provider.helpUrl != null)
args.putString("help", provider.helpUrl);
if (provider.documentation != null) if (provider.documentation != null)
args.putString("documentation", provider.documentation.toString()); args.putString("documentation", provider.documentation.toString());
@ -377,18 +396,37 @@ public class FragmentQuickSetup extends FragmentBase {
} }
@Override @Override
protected void onException(Bundle args, Throwable ex) { protected void onException(final Bundle args, Throwable ex) {
if (args.containsKey("documentation")) {
tvInstructions.setText(HtmlHelper.fromHtml(args.getString("documentation")));
tvInstructions.setVisibility(View.VISIBLE);
}
if (ex instanceof IllegalArgumentException || ex instanceof UnknownHostException) if (ex instanceof IllegalArgumentException || ex instanceof UnknownHostException)
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, false)); tvError.setText(Helper.formatThrowable(ex, false));
tvError.setVisibility(View.VISIBLE); tvError.setVisibility(View.VISIBLE);
} }
if (args.containsKey("help")) {
Uri uri = Uri.parse(args.getString("help"));
btnHelp.setTag(uri);
btnHelp.setVisibility(View.VISIBLE);
}
if (args.containsKey("documentation")) {
tvInstructions.setText(HtmlHelper.fromHtml(args.getString("documentation")));
tvInstructions.setVisibility(View.VISIBLE);
}
new Handler().post(new Runnable() {
@Override
public void run() {
if (args.containsKey("documentation"))
scroll.smoothScrollTo(0, tvInstructions.getBottom());
else if (args.containsKey("help"))
scroll.smoothScrollTo(0, btnHelp.getBottom());
else if (tvError.getVisibility() == View.VISIBLE)
scroll.smoothScrollTo(0, tvError.getBottom());
}
});
} }
}.execute(FragmentQuickSetup.this, args, "setup:quick"); }.execute(FragmentQuickSetup.this, args, "setup:quick");
} }

@ -703,6 +703,18 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnSave" /> app:layout_constraintTop_toBottomOf="@id/btnSave" />
<Button
android:id="@+id/btnHelp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:backgroundTint="@color/colorAccent"
android:text="@string/title_setup_help"
android:textColor="?android:textColorPrimaryInverse"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvError" />
<TextView <TextView
android:id="@+id/tvInstructions" android:id="@+id/tvInstructions"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -711,7 +723,7 @@
android:text="provider instructions" android:text="provider instructions"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" 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/btnHelp" />
<eu.faircode.email.ContentLoadingProgressBar <eu.faircode.email.ContentLoadingProgressBar
android:id="@+id/pbWait" android:id="@+id/pbWait"

@ -613,6 +613,18 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnSave" /> app:layout_constraintTop_toBottomOf="@id/btnSave" />
<Button
android:id="@+id/btnHelp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:backgroundTint="@color/colorAccent"
android:text="@string/title_setup_help"
android:textColor="?android:textColorPrimaryInverse"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvError" />
<TextView <TextView
android:id="@+id/tvInstructions" android:id="@+id/tvInstructions"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -621,7 +633,7 @@
android:text="provider instructions" android:text="provider instructions"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" 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/btnHelp" />
<eu.faircode.email.ContentLoadingProgressBar <eu.faircode.email.ContentLoadingProgressBar
android:id="@+id/pbWait" android:id="@+id/pbWait"

@ -7,6 +7,7 @@
tools:context=".ActivitySetup"> tools:context=".ActivitySetup">
<ScrollView <ScrollView
android:id="@+id/scroll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
@ -90,7 +91,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:autoLink="web" android:autoLink="web"
android:gravity="center_horizontal"
android:text="error" android:text="error"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="?attr/colorWarning" android:textColor="?attr/colorWarning"
@ -98,6 +98,18 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnCheck" /> app:layout_constraintTop_toBottomOf="@id/btnCheck" />
<Button
android:id="@+id/btnHelp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:backgroundTint="@color/colorAccent"
android:text="@string/title_setup_help"
android:textColor="?android:textColorPrimaryInverse"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvError" />
<TextView <TextView
android:id="@+id/tvInstructions" android:id="@+id/tvInstructions"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -106,7 +118,7 @@
android:text="provider instructions" android:text="provider instructions"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" 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/btnHelp" />
<TextView <TextView
android:id="@+id/tvImapTitle" android:id="@+id/tvImapTitle"

@ -228,7 +228,7 @@
<string name="title_advanced_english_hint">Dadurch wird die App neu gestartet</string> <string name="title_advanced_english_hint">Dadurch wird die App neu gestartet</string>
<string name="title_advanced_paranoid_hint">Details finden Sie in der FAQ</string> <string name="title_advanced_paranoid_hint">Details finden Sie in der FAQ</string>
<string name="title_advanced_debug_hint">Aktiviert zusätzliche Protokollierung und zeigt Fehlerbehebungsinformationen an verschiedenen Stellen an</string> <string name="title_advanced_debug_hint">Aktiviert zusätzliche Protokollierung und zeigt Fehlerbehebungsinformationen an verschiedenen Stellen an</string>
<string name="title_select">Wählen Sie &#8230;</string> <string name="title_select">Auswählen &#8230;</string>
<string name="title_identity_name">Ihr Name</string> <string name="title_identity_name">Ihr Name</string>
<string name="title_identity_email">Ihre E-Mail-Adresse</string> <string name="title_identity_email">Ihre E-Mail-Adresse</string>
<string name="title_advanced_sender">Bearbeitung der Absenderadresse erlauben</string> <string name="title_advanced_sender">Bearbeitung der Absenderadresse erlauben</string>

@ -80,6 +80,7 @@
<string name="title_edit_folder">Editar carpeta</string> <string name="title_edit_folder">Editar carpeta</string>
<string name="title_setup">Ajustes</string> <string name="title_setup">Ajustes</string>
<string name="title_setup_help">Ayuda</string> <string name="title_setup_help">Ayuda</string>
<string name="title_setup_welcome">Recibir y enviar mensajes requiere configurar una cuenta y una identidad como en cualquier otra aplicación de correo electrónico.</string>
<string name="title_setup_quick">Configuración rápida</string> <string name="title_setup_quick">Configuración rápida</string>
<string name="title_setup_quick_remark">Para configurar rápidamente una cuenta y una identidad para la mayoría de los proveedores</string> <string name="title_setup_quick_remark">Para configurar rápidamente una cuenta y una identidad para la mayoría de los proveedores</string>
<string name="title_setup_quick_hint">La configuración rápida obtendrá información de configuración de autoconfig.thunderbird.net</string> <string name="title_setup_quick_hint">La configuración rápida obtendrá información de configuración de autoconfig.thunderbird.net</string>

@ -80,6 +80,7 @@
<string name="title_edit_folder">Muokkaa kansiota</string> <string name="title_edit_folder">Muokkaa kansiota</string>
<string name="title_setup">Asetukset</string> <string name="title_setup">Asetukset</string>
<string name="title_setup_help">Ohje</string> <string name="title_setup_help">Ohje</string>
<string name="title_setup_welcome">Viestien vastaanottaminen ja lähettäminen vaatii tilin ja identiteetin asettamisen, kuten missä tahansa sähköpostisovelluksessa.</string>
<string name="title_setup_quick">Pika-asetukset</string> <string name="title_setup_quick">Pika-asetukset</string>
<string name="title_setup_quick_remark">Tilin ja identiteetin nopeaan asettamiseen useimmille palveluntarjoajille</string> <string name="title_setup_quick_remark">Tilin ja identiteetin nopeaan asettamiseen useimmille palveluntarjoajille</string>
<string name="title_setup_quick_hint">Pika-asennus hakee asetustiedot osoitteesta autoconfig.thunderbird.net</string> <string name="title_setup_quick_hint">Pika-asennus hakee asetustiedot osoitteesta autoconfig.thunderbird.net</string>

@ -80,6 +80,7 @@
<string name="title_edit_folder">Modifier le dossier</string> <string name="title_edit_folder">Modifier le dossier</string>
<string name="title_setup">Configuration</string> <string name="title_setup">Configuration</string>
<string name="title_setup_help">Aide</string> <string name="title_setup_help">Aide</string>
<string name="title_setup_welcome">La réception et l\'envoi de messages nécessitent la création d\'un compte et d\'une identité comme dans toute autre application de courriel.</string>
<string name="title_setup_quick">Configuration rapide</string> <string name="title_setup_quick">Configuration rapide</string>
<string name="title_setup_quick_remark">Pour configurer rapidement un compte et une identité pour la plupart des fournisseurs</string> <string name="title_setup_quick_remark">Pour configurer rapidement un compte et une identité pour la plupart des fournisseurs</string>
<string name="title_setup_quick_hint">La configuration rapide récupérera les informations de configuration de autoconfig.thunderbird.net</string> <string name="title_setup_quick_hint">La configuration rapide récupérera les informations de configuration de autoconfig.thunderbird.net</string>

Loading…
Cancel
Save