Adds custom tabs for login activity #321

This commit is contained in:
stom79 2018-02-16 15:15:04 +01:00
parent 3d2d19b417
commit 90688eacc3
4 changed files with 209 additions and 151 deletions

View File

@ -104,7 +104,14 @@
android:windowSoftInputMode="stateAlwaysHidden" android:windowSoftInputMode="stateAlwaysHidden"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/app_name" android:label="@string/app_name"
/> >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="backtomastalab" android:scheme="mastalab" />
</intent-filter>
</activity>
<activity android:name=".activities.ShowAccountActivity" <activity android:name=".activities.ShowAccountActivity"
android:windowSoftInputMode="stateAlwaysHidden" android:windowSoftInputMode="stateAlwaysHidden"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"

View File

@ -19,6 +19,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Paint; import android.graphics.Paint;
import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout;
@ -36,24 +37,20 @@ import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.HashMap; import java.util.HashMap;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
import fr.gouv.etalab.mastodon.client.HttpsConnection; import fr.gouv.etalab.mastodon.client.HttpsConnection;
import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.helper.Helper;
import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
import static fr.gouv.etalab.mastodon.helper.Helper.convertDpToPixel; import static fr.gouv.etalab.mastodon.helper.Helper.convertDpToPixel;
@ -65,11 +62,11 @@ import static fr.gouv.etalab.mastodon.helper.Helper.convertDpToPixel;
public class LoginActivity extends BaseActivity { public class LoginActivity extends BaseActivity {
private String client_id; private static String client_id;
private String client_secret; private static String client_secret;
private TextView login_two_step; private TextView login_two_step;
private static boolean client_id_for_webview = false; private static boolean client_id_for_webview = false;
private String instance; private static String instance;
private AutoCompleteTextView login_instance; private AutoCompleteTextView login_instance;
private EditText login_uid; private EditText login_uid;
private EditText login_passwd; private EditText login_passwd;
@ -80,154 +77,189 @@ public class LoginActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if( getIntent() != null && getIntent().getData() != null && getIntent().getData().toString().contains("mastalab://backtomastalab?code=")){
String url = getIntent().getData().toString();
String val[] = url.split("code=");
String code = val[1];
final String action = "/oauth/token";
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); final HashMap<String, String> parameters = new HashMap<>();
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); parameters.put(Helper.CLIENT_ID, client_id);
if( theme == Helper.THEME_LIGHT){ parameters.put(Helper.CLIENT_SECRET, client_secret);
setTheme(R.style.AppTheme); parameters.put(Helper.REDIRECT_URI,Helper.REDIRECT_CONTENT_WEB);
parameters.put("grant_type", "authorization_code");
parameters.put("code",code);
new Thread(new Runnable(){
@Override
public void run() {
try {
final String response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + action, 30, parameters, null);
JSONObject resobj;
try {
resobj = new JSONObject(response);
String token = resobj.get("access_token").toString();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
editor.apply();
//Update the account with the token;
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} catch (JSONException ignored) {}
} catch (Exception ignored) {}
}}).start();
}else { }else {
setTheme(R.style.AppThemeDark);
}
setContentView(R.layout.activity_login);
if( theme == Helper.THEME_DARK) {
changeDrawableColor(getApplicationContext(), R.drawable.mastodon_icon, R.color.mastodonC2);
}else {
changeDrawableColor(getApplicationContext(), R.drawable.mastodon_icon, R.color.mastodonC3);
}
final Button connectionButton = findViewById(R.id.login_button);
login_instance = findViewById(R.id.login_instance);
login_uid = findViewById(R.id.login_uid);
login_passwd = findViewById(R.id.login_passwd);
if( theme == Helper.THEME_LIGHT) {
connectionButton.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
}
login_instance.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
if (theme == Helper.THEME_LIGHT) {
setTheme(R.style.AppTheme);
} else {
setTheme(R.style.AppThemeDark);
} }
@Override setContentView(R.layout.activity_login);
public void afterTextChanged(Editable s) {
if( s.length() > 2 && !isLoadingInstance){ if (theme == Helper.THEME_DARK) {
final String action = "/instances/search"; changeDrawableColor(getApplicationContext(), R.drawable.mastodon_icon, R.color.mastodonC2);
final HashMap<String, String> parameters = new HashMap<>(); } else {
parameters.put("q", s.toString().trim()); changeDrawableColor(getApplicationContext(), R.drawable.mastodon_icon, R.color.mastodonC3);
parameters.put("count", String.valueOf(5)); }
parameters.put("name", String.valueOf(true)); final Button connectionButton = findViewById(R.id.login_button);
isLoadingInstance = true; login_instance = findViewById(R.id.login_instance);
new Thread(new Runnable(){ login_uid = findViewById(R.id.login_uid);
@Override login_passwd = findViewById(R.id.login_passwd);
public void run() {
try {
final String response = new HttpsConnection(LoginActivity.this).get("https://instances.social/api/1.0" + action, 30, parameters, Helper.THEKINRAR_SECRET_TOKEN ); if (theme == Helper.THEME_LIGHT) {
runOnUiThread(new Runnable() { connectionButton.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
public void run() { }
isLoadingInstance = false; login_instance.addTextChangedListener(new TextWatcher() {
String[] instances; @Override
try { public void beforeTextChanged(CharSequence s, int start, int count, int after) {
JSONObject jsonObject = new JSONObject(response); }
JSONArray jsonArray = jsonObject.getJSONArray("instances");
if( jsonArray != null){ @Override
instances = new String[jsonArray.length()]; public void onTextChanged(CharSequence s, int start, int before, int count) {
for(int i = 0 ; i < jsonArray.length() ; i++){
instances[i] = jsonArray.getJSONObject(i).get("name").toString(); }
@Override
public void afterTextChanged(Editable s) {
if (s.length() > 2 && !isLoadingInstance) {
final String action = "/instances/search";
final HashMap<String, String> parameters = new HashMap<>();
parameters.put("q", s.toString().trim());
parameters.put("count", String.valueOf(5));
parameters.put("name", String.valueOf(true));
isLoadingInstance = true;
new Thread(new Runnable() {
@Override
public void run() {
try {
final String response = new HttpsConnection(LoginActivity.this).get("https://instances.social/api/1.0" + action, 30, parameters, Helper.THEKINRAR_SECRET_TOKEN);
runOnUiThread(new Runnable() {
public void run() {
isLoadingInstance = false;
String[] instances;
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("instances");
if (jsonArray != null) {
instances = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
instances[i] = jsonArray.getJSONObject(i).get("name").toString();
}
} else {
instances = new String[]{};
} }
}else { login_instance.setAdapter(null);
instances = new String[]{}; ArrayAdapter<String> adapter =
new ArrayAdapter<>(LoginActivity.this, android.R.layout.simple_list_item_1, instances);
login_instance.setAdapter(adapter);
if (login_instance.hasFocus() && !LoginActivity.this.isFinishing())
login_instance.showDropDown();
} catch (JSONException ignored) {
isLoadingInstance = false;
} }
login_instance.setAdapter(null); }
ArrayAdapter<String> adapter = });
new ArrayAdapter<>(LoginActivity.this, android.R.layout.simple_list_item_1, instances);
login_instance.setAdapter(adapter);
if( login_instance.hasFocus() && !LoginActivity.this.isFinishing())
login_instance.showDropDown();
} catch (JSONException ignored) {isLoadingInstance = false;} } catch (HttpsConnection.HttpsConnectionException e) {
} isLoadingInstance = false;
}); } catch (Exception e) {
isLoadingInstance = false;
} catch (HttpsConnection.HttpsConnectionException e) { }
isLoadingInstance = false;
} catch (Exception e) {
isLoadingInstance = false;
} }
} }).start();
}).start(); }
} }
} });
});
connectionButton.setEnabled(false); connectionButton.setEnabled(false);
login_two_step = findViewById(R.id.login_two_step); login_two_step = findViewById(R.id.login_two_step);
login_two_step.setVisibility(View.GONE); login_two_step.setVisibility(View.GONE);
login_two_step.setPaintFlags(login_two_step.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); login_two_step.setPaintFlags(login_two_step.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
login_two_step.setOnClickListener(new View.OnClickListener() { login_two_step.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
client_id_for_webview = true; client_id_for_webview = true;
retrievesClientId();
}
});
login_instance.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
connectionButton.setEnabled(false);
login_two_step.setVisibility(View.INVISIBLE);
TextInputLayout login_instance_layout = findViewById(R.id.login_instance_layout);
if (!hasFocus) {
retrievesClientId(); retrievesClientId();
if(login_instance.getText() == null || login_instance.getText().toString().length() == 0 ) {
login_instance_layout.setError(getString(R.string.toast_error_instance));
login_instance_layout.setErrorEnabled(true);
}
}else{
login_instance_layout.setErrorEnabled(false);
} }
} });
});
login_instance.setOnFocusChangeListener(new View.OnFocusChangeListener() {
final TextView login_issue = findViewById(R.id.login_issue); @Override
SpannableString content = new SpannableString(getString(R.string.issue_login_title)); public void onFocusChange(View v, boolean hasFocus) {
content.setSpan(new UnderlineSpan(), 0, content.length(), 0); connectionButton.setEnabled(false);
login_issue.setText(content); login_two_step.setVisibility(View.INVISIBLE);
login_issue.setOnClickListener(new View.OnClickListener() { TextInputLayout login_instance_layout = findViewById(R.id.login_instance_layout);
@Override if (!hasFocus) {
public void onClick(View view) { retrievesClientId();
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this); if (login_instance.getText() == null || login_instance.getText().toString().length() == 0) {
builder.setTitle(R.string.issue_login_title); login_instance_layout.setError(getString(R.string.toast_error_instance));
TextView message = new TextView(LoginActivity.this); login_instance_layout.setErrorEnabled(true);
final SpannableString s = }
new SpannableString(getText(R.string.issue_login_message)); } else {
Linkify.addLinks(s, Linkify.WEB_URLS); login_instance_layout.setErrorEnabled(false);
message.setText(s);
message.setPadding((int) convertDpToPixel(10,LoginActivity.this), (int) convertDpToPixel(10,LoginActivity.this), (int) convertDpToPixel(10,LoginActivity.this), (int) convertDpToPixel(10,LoginActivity.this));
message.setMovementMethod(LinkMovementMethod.getInstance());
builder.setView(message);
builder.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
} }
}); }
builder.setIcon(android.R.drawable.ic_dialog_alert).show(); });
}
});
}
final TextView login_issue = findViewById(R.id.login_issue);
SpannableString content = new SpannableString(getString(R.string.issue_login_title));
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
login_issue.setText(content);
login_issue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
builder.setTitle(R.string.issue_login_title);
TextView message = new TextView(LoginActivity.this);
final SpannableString s =
new SpannableString(getText(R.string.issue_login_message));
Linkify.addLinks(s, Linkify.WEB_URLS);
message.setText(s);
message.setPadding((int) convertDpToPixel(10, LoginActivity.this), (int) convertDpToPixel(10, LoginActivity.this), (int) convertDpToPixel(10, LoginActivity.this), (int) convertDpToPixel(10, LoginActivity.this));
message.setMovementMethod(LinkMovementMethod.getInstance());
builder.setView(message);
builder.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.setIcon(android.R.drawable.ic_dialog_alert).show();
}
});
}
}
@Override @Override
protected void onResume(){ protected void onResume(){
super.onResume(); super.onResume();
Button connectionButton = findViewById(R.id.login_button); Button connectionButton = findViewById(R.id.login_button);
if (login_instance.getText() != null && login_instance.getText().toString().length() > 0 && client_id_for_webview) { if (login_instance != null &&login_instance.getText() != null && login_instance.getText().toString().length() > 0 && client_id_for_webview) {
connectionButton.setEnabled(false); connectionButton.setEnabled(false);
client_id_for_webview = false; client_id_for_webview = false;
retrievesClientId(); retrievesClientId();
@ -270,14 +302,19 @@ public class LoginActivity extends BaseActivity {
connectionButton.setEnabled(true); connectionButton.setEnabled(true);
login_two_step.setVisibility(View.VISIBLE); login_two_step.setVisibility(View.VISIBLE);
if( client_id_for_webview){ if( client_id_for_webview){
Intent i = new Intent(LoginActivity.this, WebviewConnectActivity.class); boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
i.putExtra("instance", instance); if( embedded_browser) {
startActivity(i); Intent i = new Intent(LoginActivity.this, WebviewConnectActivity.class);
i.putExtra("instance", instance);
startActivity(i);
}else{
String url = redirectUserToAuthorizeAndLogin(client_id, instance);
Helper.openBrowser(getApplicationContext(), url);
}
} }
} catch (JSONException ignored) {ignored.printStackTrace();} } catch (JSONException ignored) {ignored.printStackTrace();}
} }
}); });
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@ -365,7 +402,6 @@ public class LoginActivity extends BaseActivity {
} }
} }
}).start(); }).start();
} }
}); });
} }
@ -375,6 +411,10 @@ public class LoginActivity extends BaseActivity {
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present. // Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_login, menu); getMenuInflater().inflate(R.menu.main_login, menu);
CheckBox checkBox= (CheckBox) menu.findItem(R.id.action_custom_tabs).getActionView();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
checkBox.setChecked(!embedded_browser);
return true; return true;
} }
@ -395,7 +435,23 @@ public class LoginActivity extends BaseActivity {
}else if(id == R.id.action_proxy){ }else if(id == R.id.action_proxy){
Intent intent = new Intent(getApplicationContext(), ProxyActivity.class); Intent intent = new Intent(getApplicationContext(), ProxyActivity.class);
startActivity(intent); startActivity(intent);
}else if(id == R.id.action_custom_tabs){
item.setChecked(!item.isChecked());
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SET_EMBEDDED_BROWSER, !item.isChecked());
editor.apply();
return false;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
public static String redirectUserToAuthorizeAndLogin(String clientId, String instance) {
String queryString = Helper.CLIENT_ID + "="+ clientId;
queryString += "&" + Helper.REDIRECT_URI + "="+ Uri.encode(Helper.REDIRECT_CONTENT_WEB);
queryString += "&" + Helper.RESPONSE_TYPE +"=code";
queryString += "&" + Helper.SCOPE +"=" + Helper.OAUTH_SCOPES;
return Helper.instanceWithProtocol(instance) + Helper.EP_AUTHORIZE + "?" + queryString;
}
} }

View File

@ -139,7 +139,7 @@ public class WebviewConnectActivity extends BaseActivity {
} }
}); });
webView.loadUrl(redirectUserToAuthorizeAndLogin()); webView.loadUrl(LoginActivity.redirectUserToAuthorizeAndLogin(clientId, instance));
} }
@ -154,15 +154,6 @@ public class WebviewConnectActivity extends BaseActivity {
private String redirectUserToAuthorizeAndLogin() {
String queryString = Helper.CLIENT_ID + "="+ clientId;
queryString += "&" + Helper.REDIRECT_URI + "="+ Uri.encode(Helper.REDIRECT_CONTENT_WEB);
queryString += "&" + Helper.RESPONSE_TYPE +"=code";
queryString += "&" + Helper.SCOPE +"=" + Helper.OAUTH_SCOPES;
return Helper.instanceWithProtocol(instance) + Helper.EP_AUTHORIZE + "?" + queryString;
}
@Override @Override
public void onDestroy() { public void onDestroy() {

View File

@ -13,4 +13,8 @@
android:id="@+id/action_proxy" android:id="@+id/action_proxy"
android:title="@string/proxy_set" android:title="@string/proxy_set"
app:showAsAction="never" /> app:showAsAction="never" />
<item android:id="@+id/action_custom_tabs"
android:title="@string/custom_tabs"
app:actionViewClass="android.widget.CheckBox"
android:checkable="true"/>
</menu> </menu>