/***************************************************************************************
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
* Foundation; either version 3 of the License, or (at your option) any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
package com.ichi2.anki;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.ichi2.anim.ActivityTransitionAnimation;
import com.ichi2.async.Connection;
import com.ichi2.async.Connection.Payload;
import com.ichi2.themes.StyledProgressDialog;
import timber.log.Timber;
public class MyAccount extends AnkiActivity {
private final static int STATE_LOG_IN = 1;
private final static int STATE_LOGGED_IN = 2;
private View mLoginToMyAccountView;
private View mLoggedIntoMyAccountView;
private EditText mUsername;
private EditText mPassword;
private TextView mUsernameLoggedIn;
private MaterialDialog mProgressDialog;
Toolbar mToolbar = null;
private void switchToState(int newState) {
switch (newState) {
case STATE_LOGGED_IN:
String username = AnkiDroidApp.getSharedPrefs(getBaseContext()).getString("username", "");
mUsernameLoggedIn.setText(username);
mToolbar = (Toolbar) mLoggedIntoMyAccountView.findViewById(R.id.toolbar);
if (mToolbar!= null) {
mToolbar.setTitle(getString(R.string.sync_account)); // This can be cleaned up if all three main layouts are guaranteed to share the same toolbar object
setSupportActionBar(mToolbar);
}
setContentView(mLoggedIntoMyAccountView);
break;
case STATE_LOG_IN:
mToolbar = (Toolbar) mLoginToMyAccountView.findViewById(R.id.toolbar);
if (mToolbar!= null) {
mToolbar.setTitle(getString(R.string.sync_account)); // This can be cleaned up if all three main layouts are guaranteed to share the same toolbar object
setSupportActionBar(mToolbar);
}
setContentView(mLoginToMyAccountView);
break;
}
supportInvalidateOptionsMenu(); // Needed?
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mayOpenUrl(Uri.parse(getResources().getString(R.string.register_url)));
initAllContentViews();
SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
if (preferences.getString("hkey", "").length() > 0) {
switchToState(STATE_LOGGED_IN);
} else {
switchToState(STATE_LOG_IN);
}
}
// Commented awaiting the resolution of the next issue: http://code.google.com/p/anki/issues/detail?id=1932
// private boolean isUsernameAndPasswordValid(String username, String password) {
// return isLoginFieldValid(username) && isLoginFieldValid(password);
// }
//
//
// private boolean isLoginFieldValid(String loginField) {
// boolean loginFieldValid = false;
//
// if (loginField.length() >= 2 && loginField.matches("[A-Za-z0-9]+")) {
// loginFieldValid = true;
// }
//
// return loginFieldValid;
// }
private void saveUserInformation(String username, String hkey) {
SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
Editor editor = preferences.edit();
editor.putString("username", username);
editor.putString("hkey", hkey);
editor.commit();
}
private void login() {
// Hide soft keyboard
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(mUsername.getWindowToken(), 0);
String username = mUsername.getText().toString().trim(); // trim spaces, issue 1586
String password = mPassword.getText().toString();
/*
* Commented awaiting the resolution of the next issue: http://code.google.com/p/anki/issues/detail?id=1932
* if(isUsernameAndPasswordValid(username, password)) { Connection.login(loginListener, new
* Connection.Payload(new Object[] {username, password})); } else { mInvalidUserPassAlert.show(); }
*/
if (!"".equalsIgnoreCase(username) && !"".equalsIgnoreCase(password)) {
Connection.login(loginListener, new Connection.Payload(new Object[]{username, password}));
} else {
UIUtils.showSimpleSnackbar(this, R.string.invalid_username_password, true);
}
}
private void logout() {
SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
Editor editor = preferences.edit();
editor.putString("username", "");
editor.putString("hkey", "");
editor.commit();
// force media resync on deauth
getCol().getMedia().forceResync();
switchToState(STATE_LOG_IN);
}
private void resetPassword() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(getResources().getString(R.string.resetpw_url)));
startActivity(intent);
}
private void initAllContentViews() {
mLoginToMyAccountView = getLayoutInflater().inflate(R.layout.my_account, null);
mUsername = (EditText) mLoginToMyAccountView.findViewById(R.id.username);
mPassword = (EditText) mLoginToMyAccountView.findViewById(R.id.password);
Button loginButton = (Button) mLoginToMyAccountView.findViewById(R.id.login_button);
loginButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
login();
}
});
Button resetPWButton = (Button) mLoginToMyAccountView.findViewById(R.id.reset_password_button);
resetPWButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
resetPassword();
}
});
Button signUpButton = (Button) mLoginToMyAccountView.findViewById(R.id.sign_up_button);
signUpButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
openUrl(Uri.parse(getResources().getString(R.string.register_url)));
}
});
mLoggedIntoMyAccountView = getLayoutInflater().inflate(R.layout.my_account_logged_in, null);
mUsernameLoggedIn = (TextView) mLoggedIntoMyAccountView.findViewById(R.id.username_logged_in);
Button logoutButton = (Button) mLoggedIntoMyAccountView.findViewById(R.id.logout_button);
logoutButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
logout();
}
});
}
/**
* Listeners
*/
Connection.TaskListener loginListener = new Connection.TaskListener() {
@Override
public void onProgressUpdate(Object... values) {
// Pass
}
@Override
public void onPreExecute() {
Timber.d("loginListener.onPreExcecute()");
if (mProgressDialog == null || !mProgressDialog.isShowing()) {
mProgressDialog = StyledProgressDialog.show(MyAccount.this, "",
getResources().getString(R.string.alert_logging_message), false);
}
}
@Override
public void onPostExecute(Payload data) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
if (data.success) {
Timber.i("User successfully logged in!");
saveUserInformation((String) data.data[0], (String) data.data[1]);
Intent i = MyAccount.this.getIntent();
if (i.hasExtra("notLoggedIn") && i.getExtras().getBoolean("notLoggedIn", false)) {
MyAccount.this.setResult(RESULT_OK, i);
finishWithAnimation(ActivityTransitionAnimation.FADE);
} else {
// Show logged view
mUsernameLoggedIn.setText((String) data.data[0]);
switchToState(STATE_LOGGED_IN);
}
} else {
Timber.e("Login failed, error code %d",data.returnType);
if (data.returnType == 403) {
UIUtils.showSimpleSnackbar(MyAccount.this, R.string.invalid_username_password, true);
} else {
UIUtils.showSimpleSnackbar(MyAccount.this, R.string.connection_error_message, true);
}
}
}
@Override
public void onDisconnected() {
UIUtils.showSimpleSnackbar(MyAccount.this, R.string.youre_offline, true);
}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
Timber.i("MyAccount - onBackPressed()");
finishWithAnimation(ActivityTransitionAnimation.FADE);
return true;
}
return super.onKeyDown(keyCode, event);
}
}