Skip to content
This repository was archived by the owner on Feb 20, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ dependencies {
})
compile 'com.android.support:appcompat-v7:25.3.0'
compile 'com.android.support:design:25.3.0'
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
testCompile 'junit:junit:4.12'
}
164 changes: 29 additions & 135 deletions app/src/main/java/edu/galileo/mvp/LoginActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,46 @@

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
* A login screen that offers login via email/password.
*/
public class LoginActivity extends AppCompatActivity {
public class LoginActivity extends AppCompatActivity implements LoginView {

/**
* A dummy authentication store containing known user names and passwords.
* TODO: remove after connecting to a real authentication system.
*/
private static final String[] DUMMY_CREDENTIALS = new String[] {
"test@galileo.edu", "testtest"
};
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
private UserLoginTask mAuthTask = null;
private LoginPresenter loginPresenter;

// UI references.
private AutoCompleteTextView mEmailView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
@BindView(R.id.email) AutoCompleteTextView mEmailView;
@BindView(R.id.password) EditText mPasswordView;
@BindView(R.id.login_form) View mLoginFormView;
@BindView(R.id.login_progress) View mProgressView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Set up the login form.
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
ButterKnife.bind(this);

mPasswordView = (EditText) findViewById(R.id.password);

Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View view) {
attemptLogin();
}
});

mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
loginPresenter = new LoginPresenterImpl(this);
}

/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
private void attemptLogin() {
if (mAuthTask != null) {
return;
}

@OnClick(R.id.email_sign_in_button)
public void attemptLogin() {
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
Expand All @@ -76,53 +50,13 @@ private void attemptLogin() {
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();

boolean cancel = false;
View focusView = null;

// Check for a valid password, if the user entered one.
if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}

// Check for a valid email address.
if (TextUtils.isEmpty(email)) {
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!isEmailValid(email)) {
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}

if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password);
mAuthTask.execute((Void) null);
}
}

private boolean isEmailValid(String email) {
//TODO: Replace this with your own logic
return email.contains("@");
}

private boolean isPasswordValid(String password) {
//TODO: Replace this with your own logic
return password.length() > 4;
loginPresenter.validateCredentials(email, password);
}

/**
* Shows the progress UI and hides the login form.
*/
@Override
public void showProgress(final boolean show) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);

Expand All @@ -147,61 +81,21 @@ public void onAnimationEnd(Animator animation) {
});
}

/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {

private final String mEmail;
private final String mPassword;

UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}

@Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.

try {
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}

for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail)) {
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}

// TODO: register the new account here.
return true;
}

@Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
@Override
public void setUsernameError(int messageResId) {
mEmailView.setError(getString(messageResId));
mEmailView.requestFocus();
}

if (success) {
Toast.makeText(LoginActivity.this, "Success", Toast.LENGTH_SHORT).show();
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
@Override
public void setPasswordError(int messageResId) {
mPasswordView.setError(getString(messageResId));
mPasswordView.requestFocus();
}

@Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
@Override
public void successAction() {
Toast.makeText(LoginActivity.this, "Success", Toast.LENGTH_SHORT).show();
}
}

15 changes: 15 additions & 0 deletions app/src/main/java/edu/galileo/mvp/LoginModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package edu.galileo.mvp;

public interface LoginModel {

interface OnLoginFinishedListener {

void onCanceled();

void onPasswordError();

void onSuccess();
}

void login(String username, String password, OnLoginFinishedListener listener);
}
71 changes: 71 additions & 0 deletions app/src/main/java/edu/galileo/mvp/LoginModelImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package edu.galileo.mvp;

import android.os.AsyncTask;

public class LoginModelImpl implements LoginModel {

private OnLoginFinishedListener listener;

/**
* A dummy authentication store containing known user names and passwords.
* TODO: remove after connecting to a real authentication system.
*/
private static final String[] DUMMY_CREDENTIALS = new String[] {
"test@galileo.edu:asdfasdf", "test2@galileo.edu:asdfasdf"
};

@Override
public void login(String username, String password, OnLoginFinishedListener listener) {
this.listener = listener;

new UserLoginTask(username, password).execute((Void) null);
}

public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {

private final String mEmail;
private final String mPassword;

UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}

@Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.

try {
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}

for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail)) {
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}

// TODO: register the new account here.
return false;
}

@Override
protected void onPostExecute(final Boolean success) {
if (success) {
listener.onSuccess();
} else {
listener.onPasswordError();
}
}

@Override
protected void onCancelled() {
listener.onCanceled();
}
}
}
6 changes: 6 additions & 0 deletions app/src/main/java/edu/galileo/mvp/LoginPresenter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package edu.galileo.mvp;

public interface LoginPresenter {

void validateCredentials(String username, String password);
}
Loading