Login helper

This commit is contained in:
stom79 2018-12-11 19:17:14 +01:00
parent d48c627c3b
commit 86dc89e764
6 changed files with 392 additions and 70 deletions

View File

@ -5,10 +5,11 @@ android {
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "fr.gouv.etalab.mastodon"
minSdkVersion 15
minSdkVersion 16
targetSdkVersion 28
versionCode 201
versionName "1.39.0"
multiDexEnabled true
}
flavorDimensions "default"
buildTypes {
@ -78,5 +79,6 @@ dependencies {
implementation 'com.github.franmontiel:LocaleChanger:0.9.2'
implementation 'com.github.stom79:SparkButton:1.0.10'
implementation 'com.github.GrenderG:Toasty:1.3.0'
implementation 'com.elconfidencial.bubbleshowcase:bubbleshowcase:1.3.1'
playstoreImplementation "io.github.kobakei:ratethisapp:$ratethisappLibraryVersion"
}

View File

@ -19,11 +19,13 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
@ -48,6 +50,10 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.elconfidencial.bubbleshowcase.BubbleShowCase;
import com.elconfidencial.bubbleshowcase.BubbleShowCaseBuilder;
import com.elconfidencial.bubbleshowcase.BubbleShowCaseListener;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -84,6 +90,7 @@ public class LoginActivity extends BaseActivity {
private EditText login_passwd;
boolean isLoadingInstance = false;
private String oldSearch;
private ImageView info_uid, info_instance, info_pwd, info_2FA;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -168,7 +175,38 @@ public class LoginActivity extends BaseActivity {
login_instance = findViewById(R.id.login_instance);
login_uid = findViewById(R.id.login_uid);
login_passwd = findViewById(R.id.login_passwd);
info_uid = findViewById(R.id.info_uid);
info_instance = findViewById(R.id.info_instance);
info_pwd = findViewById(R.id.info_pwd);
info_2FA = findViewById(R.id.info_2FA);
info_instance.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showcaseInstance(false);
}
});
info_uid.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showCaseLogin(false);
}
});
info_pwd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showCasePassword(false);
}
});
info_2FA.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showCase2FA(false);
}
});
showcaseInstance(true);
login_instance.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
@ -254,6 +292,7 @@ public class LoginActivity extends BaseActivity {
connectionButton.setEnabled(false);
login_two_step = findViewById(R.id.login_two_step);
login_two_step.setVisibility(View.GONE);
info_2FA.setVisibility(View.GONE);
login_two_step.setPaintFlags(login_two_step.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
login_two_step.setOnClickListener(new View.OnClickListener() {
@Override
@ -275,6 +314,7 @@ public class LoginActivity extends BaseActivity {
public void onFocusChange(View v, boolean hasFocus) {
connectionButton.setEnabled(false);
login_two_step.setVisibility(View.INVISIBLE);
info_2FA.setVisibility(View.INVISIBLE);
TextInputLayout login_instance_layout = findViewById(R.id.login_instance_layout);
if (!hasFocus) {
retrievesClientId();
@ -372,6 +412,8 @@ public class LoginActivity extends BaseActivity {
editor.apply();
connectionButton.setEnabled(true);
login_two_step.setVisibility(View.VISIBLE);
info_2FA.setVisibility(View.VISIBLE);
showCase2FA(true);
if( client_id_for_webview){
boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
if( embedded_browser) {
@ -525,4 +567,166 @@ public class LoginActivity extends BaseActivity {
queryString += "&" + Helper.SCOPE +"=" + Helper.OAUTH_SCOPES;
return Helper.instanceWithProtocol(instance) + Helper.EP_AUTHORIZE + "?" + queryString;
}
private void showcaseInstance(final boolean loop){
BubbleShowCaseBuilder showCaseBuilder = new BubbleShowCaseBuilder(LoginActivity.this)
.title(getString(R.string.instance))
.description(getString(R.string.showcase_instance))
.arrowPosition(BubbleShowCase.ArrowPosition.TOP)
.backgroundColor(ContextCompat.getColor(LoginActivity.this, R.color.mastodonC4))
.textColor(Color.WHITE)
.titleTextSize(17)
.descriptionTextSize(15);
if( loop)
showCaseBuilder.showOnce("BUBBLE_SHOW_CASE_INSTANCE_ID");
showCaseBuilder.listener(new BubbleShowCaseListener (){
@Override
public void onTargetClick(BubbleShowCase bubbleShowCase) {
if( loop) {
bubbleShowCase.finishSequence();
showCaseLogin(true);
}
}
@Override
public void onCloseActionImageClick(BubbleShowCase bubbleShowCase) {
if(loop) {
bubbleShowCase.finishSequence();
showCaseLogin(true);
}
}
@Override
public void onBubbleClick(BubbleShowCase bubbleShowCase) {
}
@Override
public void onBackgroundDimClick(BubbleShowCase bubbleShowCase) {
}
})
.targetView(login_instance)
.show();
}
private void showCaseLogin(final boolean loop){
BubbleShowCaseBuilder showCaseBuilder = new BubbleShowCaseBuilder(LoginActivity.this) //Activity instance
.title(getString(R.string.login))
.description(getString(R.string.showcase_uid))
.arrowPosition(BubbleShowCase.ArrowPosition.TOP)
.backgroundColor(ContextCompat.getColor(LoginActivity.this, R.color.mastodonC4))
.textColor(Color.WHITE)
.titleTextSize(17)
.descriptionTextSize(15);
if( loop)
showCaseBuilder.showOnce("BUBBLE_SHOW_CASE_UID_ID");
showCaseBuilder.listener(new BubbleShowCaseListener (){
@Override
public void onTargetClick(BubbleShowCase bubbleShowCase) {
if( loop) {
bubbleShowCase.finishSequence();
showCasePassword(true);
}
}
@Override
public void onCloseActionImageClick(BubbleShowCase bubbleShowCase) {
if( loop) {
bubbleShowCase.finishSequence();
showCasePassword(true);
}
}
@Override
public void onBubbleClick(BubbleShowCase bubbleShowCase) {
}
@Override
public void onBackgroundDimClick(BubbleShowCase bubbleShowCase) {
}
})
.targetView(login_uid)
.show();
}
private void showCasePassword(boolean loop){
BubbleShowCaseBuilder showCaseBuilder = new BubbleShowCaseBuilder(LoginActivity.this)
.title(getString(R.string.password))
.description(getString(R.string.showcase_pwd))
.arrowPosition(BubbleShowCase.ArrowPosition.BOTTOM)
.backgroundColor(ContextCompat.getColor(LoginActivity.this, R.color.mastodonC4))
.textColor(Color.WHITE)
.titleTextSize(17)
.descriptionTextSize(15);
if( loop)
showCaseBuilder.showOnce("BUBBLE_SHOW_CASE_PASSWORD_ID");
showCaseBuilder.listener(new BubbleShowCaseListener (){
@Override
public void onTargetClick(BubbleShowCase bubbleShowCase) {
}
@Override
public void onCloseActionImageClick(BubbleShowCase bubbleShowCase) {
}
@Override
public void onBubbleClick(BubbleShowCase bubbleShowCase) {
}
@Override
public void onBackgroundDimClick(BubbleShowCase bubbleShowCase) {
}
})
.targetView(login_passwd)
.show();
}
private void showCase2FA(boolean loop){
BubbleShowCaseBuilder showCaseBuilder = new BubbleShowCaseBuilder(LoginActivity.this)
.title(getString(R.string.two_factor_authentification))
.description(getString(R.string.showcase_2FA))
.arrowPosition(BubbleShowCase.ArrowPosition.BOTTOM)
.backgroundColor(ContextCompat.getColor(LoginActivity.this, R.color.mastodonC4))
.textColor(Color.WHITE)
.titleTextSize(17)
.descriptionTextSize(15);
if( loop)
showCaseBuilder.showOnce("BUBBLE_SHOW_CASE_2FA_ID");
showCaseBuilder.listener(new BubbleShowCaseListener (){
@Override
public void onTargetClick(BubbleShowCase bubbleShowCase) {
}
@Override
public void onCloseActionImageClick(BubbleShowCase bubbleShowCase) {
}
@Override
public void onBubbleClick(BubbleShowCase bubbleShowCase) {
}
@Override
public void onBackgroundDimClick(BubbleShowCase bubbleShowCase) {
}
})
.targetView(login_passwd)
.show();
}
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF2b90d9"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
</vector>

View File

@ -57,48 +57,93 @@
android:layout_width="300dp"
android:layout_height="wrap_content"
app:errorEnabled="true">
<AutoCompleteTextView
android:id="@+id/login_instance"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:maxLines="1"
android:inputType="textWebEmailAddress"
android:hint="@string/instance_example"
/>
android:orientation="horizontal">
<AutoCompleteTextView
android:id="@+id/login_instance"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:maxLines="1"
android:inputType="textWebEmailAddress"
android:hint="@string/instance_example"
/>
<ImageView
android:contentDescription="@string/more_information"
android:id="@+id/info_instance"
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
</android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/login_two_step"
android:textAllCaps="false"
android:gravity="center"
android:drawablePadding="10dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:visibility="gone"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/colorAccent"
android:text="@string/two_factor_authentification" />
<EditText
android:id="@+id/login_uid"
android:layout_width="300dp"
android:maxLines="1"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="@string/email"
/>
<EditText
android:id = "@+id/login_passwd"
android:inputType="textPassword"
android:maxLines="1"
android:hint="@string/password"
<LinearLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
/>
android:orientation="horizontal">
<TextView
android:id="@+id/login_two_step"
android:textAllCaps="false"
android:gravity="center"
android:drawablePadding="10dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:visibility="gone"
android:layout_gravity="center"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="?attr/colorAccent"
android:text="@string/two_factor_authentification" />
<ImageView
android:contentDescription="@string/more_information"
android:id="@+id/info_2FA"
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
<LinearLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/login_uid"
android:layout_width="0dp"
android:layout_weight="1"
android:maxLines="1"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="@string/email"
/>
<ImageView
android:contentDescription="@string/more_information"
android:id="@+id/info_uid"
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
<LinearLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id = "@+id/login_passwd"
android:inputType="textPassword"
android:maxLines="1"
android:hint="@string/password"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
/>
<ImageView
android:contentDescription="@string/more_information"
android:id="@+id/info_pwd"
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
<TextView
android:layout_gravity="center"
android:layout_marginTop="10dp"

View File

@ -62,47 +62,94 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<AutoCompleteTextView
android:id="@+id/login_instance"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="textWebEmailAddress"
android:maxLines="1"
android:hint="@string/instance_example"
/>
android:orientation="horizontal">
<AutoCompleteTextView
android:id="@+id/login_instance"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="textWebEmailAddress"
android:maxLines="1"
android:hint="@string/instance_example"
/>
<ImageView
android:contentDescription="@string/more_information"
android:id="@+id/info_instance"
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
</android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/login_two_step"
android:textAllCaps="false"
android:gravity="center"
android:visibility="gone"
android:drawablePadding="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_gravity="center"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/colorAccent"
android:text="@string/two_factor_authentification" />
<EditText
android:id="@+id/login_uid"
android:orientation="horizontal">
<TextView
android:id="@+id/login_two_step"
android:textAllCaps="false"
android:gravity="center"
android:visibility="gone"
android:drawablePadding="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_gravity="center"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="?attr/colorAccent"
android:text="@string/two_factor_authentification" />
<ImageView
android:contentDescription="@string/more_information"
android:id="@+id/info_2FA"
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:inputType="textEmailAddress"
android:hint="@string/email"
/>
<EditText
android:id = "@+id/login_passwd"
android:inputType="textPassword"
android:hint="@string/password"
android:maxLines="1"
android:orientation="horizontal">
<EditText
android:id="@+id/login_uid"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:maxLines="1"
android:inputType="textEmailAddress"
android:hint="@string/email"
/>
<ImageView
android:contentDescription="@string/more_information"
android:id="@+id/info_uid"
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
android:orientation="horizontal">
<EditText
android:id = "@+id/login_passwd"
android:inputType="textPassword"
android:hint="@string/password"
android:maxLines="1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
/>
<ImageView
android:contentDescription="@string/more_information"
android:id="@+id/info_pwd"
android:src="@drawable/ic_info_login"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
<TextView
android:layout_gravity="center"
android:layout_marginTop="10dp"

View File

@ -720,4 +720,19 @@
<item>1 day</item>
<item>1 week</item>
</string-array>
<string name="showcase_instance">
In this field, you need to write your instance host name.\nFor example, if you created your account on https://mastodon.social\nJust write <b>mastodon.social</b> (without https://)\n
You can start writing first letters and names will be suggested.\n\n
⚠ The Login button will only work if the instance name is valid and the instance is up!
</string>
<string name="showcase_uid">
In this field, write the email that is attached to your Mastodon account.
</string>
<string name="showcase_pwd">
Last step is to enter your password and click on Login.
</string>
<string name="more_information">More information</string>
<string name="showcase_2FA">If you use 2FA (Two-factor authentication), you need to use this link.\nYou can also use it if you do not want to enter your credentials here.</string>
</resources>