From 377ee3bcbc61b56a64b931b1376e177774f24588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mieszko=20Wrzeszczy=C5=84ski?= Date: Sat, 12 Jan 2019 18:46:52 +0100 Subject: [PATCH] Change to one get --- app/build.gradle | 2 + .../findmytutor/activity/LoginActivity.java | 365 +++++++++++++++++- .../wmi/findmytutor/activity/TutorTab.java | 42 +- .../activity/UsersListFragment.java | 2 +- .../adapters/TutorsListAdapter.java | 112 ++++++ .../com/uam/wmi/findmytutor/utils/Const.java | 2 +- app/src/main/res/layout/activity_login.xml | 7 +- .../res/layout/preference_button_widget.xml | 1 - app/src/main/res/values-pl/strings.xml | 3 + app/src/main/res/values/strings.xml | 1 + 10 files changed, 494 insertions(+), 43 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 42fbd3d..fb8c7e9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -75,4 +75,6 @@ dependencies { // spinner loaders library implementation 'com.github.ybq:Android-SpinKit:1.2.0' + // rx binding + implementation 'com.jakewharton.rxbinding:rxbinding:0.3.0' } diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java index bf49231..01dd3ec 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java @@ -1,3 +1,4 @@ +/* package com.uam.wmi.findmytutor.activity; import android.animation.Animator; @@ -9,6 +10,357 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.design.widget.Snackbar; +import android.support.design.widget.TextInputLayout; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; + +import com.auth0.android.jwt.Claim; +import com.auth0.android.jwt.JWT; +import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; +import com.jakewharton.rxbinding.widget.RxTextView; +import com.uam.wmi.findmytutor.R; +import com.uam.wmi.findmytutor.model.JwtToken; +import com.uam.wmi.findmytutor.model.LdapUser; +import com.uam.wmi.findmytutor.model.User; +import com.uam.wmi.findmytutor.network.ApiClient; +import com.uam.wmi.findmytutor.service.LdapService; +import com.uam.wmi.findmytutor.service.UserService; +import com.uam.wmi.findmytutor.utils.LocaleHelper; +import com.uam.wmi.findmytutor.utils.PrefUtils; +import com.uam.wmi.findmytutor.utils.RestApiHelper; + +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; + +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.ResponseBody; +import rx.functions.Func1; + +public class +LoginActivity extends AppCompatActivity { + + @BindView(R.id.email_til) + TextInputLayout emailInputLayout; + @BindView(R.id.password_til) + TextInputLayout passwordInputLayout; + @BindView(R.id.email) + EditText loginText; + @BindView(R.id.password) + EditText passwordText; + @BindView(R.id.email_login_form) + LinearLayout signInLinearLayout; + @BindView(R.id.sign_in_btn) + Button signInButton; + @BindView(R.id.login_progress) + View mProgressView; + @BindView(R.id.login_form) + View mLoginFormView; + + private LdapService ldapService; + private UserService userService; + private CompositeDisposable disposable = new CompositeDisposable(); + + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(LocaleHelper.onAttach(base)); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + ButterKnife.bind(this); + + rx.Observable loginObservable = RxTextView.textChanges(loginText); + rx.Observable passwordObservable = RxTextView.textChanges(passwordText); + */ +/* Observable combinedObservables = Observable + .combineLatest(loginObservable, passwordObservable, + (o1, o2) -> isValidEmail(o1) && isValidPassword(o2));*//* + + + Subscription emailSubscription = loginObservable + .doOnNext(charSequence -> hideEmailError()) + .debounce(400, TimeUnit.MILLISECONDS) + .filter(new Func1() { + @Override + public Boolean call(CharSequence charSequence) { + return !TextUtils.isEmpty(charSequence); + } + }) + .observeOn(AndroidSchedulers.mainThread()) // UI Thread + .subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + e.printStackTrace(); + } + + @Override + public void onComplete() { + + } + + @Override + public void onSubscribe(Subscription s) { + + } + + @Override + public void onNext(CharSequence charSequence) { + boolean isEmailValid = validateEmail(charSequence.toString()); + if (!isEmailValid) { + showEmailError(); + } else { + hideEmailError(); + } + } + }); + + + ldapService = ApiClient.getClient(getApplicationContext()) + .create(LdapService.class); + userService = ApiClient.getClient(getApplicationContext()) + .create(UserService.class); + + + passwordText.setOnEditorActionListener((textView, id, keyEvent) -> { + if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) { + attemptLogin(); + return true; + } + return false; + }); + + Button mEmailSignInButton = findViewById(R.id.email_sign_in_button); + mEmailSignInButton.setOnClickListener(view -> attemptLogin()); + } + + private void hideEmailError(){ + loginText.setError(null); + } + + + + // region Helper Methods + private void enableError(TextInputLayout textInputLayout) { + if (textInputLayout.getChildCount() == 2) + textInputLayout.getChildAt(1).setVisibility(View.VISIBLE); + } + + private void disableError(TextInputLayout textInputLayout) { + if (textInputLayout.getChildCount() == 2) + textInputLayout.getChildAt(1).setVisibility(View.GONE); + } + + + + private void showEmailError(){ + enableError(emailInputLayout); + // emailInputLayout.setErrorEnabled(true); + emailInputLayout.setError(getString(R.string.invalid_email)); + } + + private void hideEmailError(){ + disableError(emailInputLayout); + // emailInputLayout.setErrorEnabled(false); + emailInputLayout.setError(null); + } + + private void showPasswordError(){ + enableError(passwordInputLayout); + // passwordInputLayout.setErrorEnabled(true); + passwordInputLayout.setError(getString(R.string.invalid_password)); + } + + private void hidePasswordError(){ + disableError(passwordInputLayout); + // passwordInputLayout.setErrorEnabled(false); + passwordInputLayout.setError(null); + } + + private void enableSignIn(){ + signInLinearLayout.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorAccent)); + signInButton.setEnabled(true); + signInButton.setTextColor(ContextCompat.getColor(getContext(), android.R.color.white)); + } + + private void disableSignIn(){ + signInLinearLayout.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.grey_400)); + signInButton.setEnabled(false); + signInButton.setTextColor(ContextCompat.getColor(getContext(), R.color.grey_500)); + } + + private void attemptLogin() { + // Reset errors. + + passwordText.setError(null); + + // Store values at the time of the login attempt. + String loginName = loginText.getText().toString(); + String password = passwordText.getText().toString(); + + boolean cancel = false; + View focusView = null; + + // Check for a valid email address. + if (TextUtils.isEmpty(loginName)) { + loginText.setError(getString(R.string.error_field_required)); + focusView = loginText; + cancel = true; + } else if (!isEmailValid(loginName)) { + loginText.setError(getString(R.string.error_invalid_login_name)); + focusView = loginText; + cancel = true; + } + + // Check for a valid password address. + if (TextUtils.isEmpty(password)) { + passwordText.setError(getString(R.string.error_field_required)); + focusView = passwordText; + cancel = true; + } + + if (cancel) { + focusView.requestFocus(); + } else { + showProgress(true); + loginProcess(loginName, password); + + } + } + + private boolean isValidEmail(CharSequence value) { + Pattern pattern = Pattern.compile("\\s"); + Matcher matcher = pattern.matcher(value); + return !matcher.find(); + } + + private boolean isValidPassword(CharSequence value) { + return value.length() > 0; + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) + private void showProgress(final boolean show) { + int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); + + + mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); + mLoginFormView.animate().setDuration(shortAnimTime).alpha( + show ? 0 : 1).setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); + } + }); + + mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); + mProgressView.animate().setDuration(shortAnimTime).alpha( + show ? 1 : 0).setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); + } + }); + + } + + private void loginProcess(String email, String password) { + //ValidateUser user = new ValidateUser(email, password); + LdapUser fakeUser = new LdapUser(email, password,"wmi","tutor",email,"Fałszywy",email); + // disposable.add(ldapService.validate(user) + disposable.add(ldapService.fakeValidate(fakeUser) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(this::handleResponse, this::handleError)); + } + + private void getUserProfile(String userId) { + + disposable.add(userService.getUserById(userId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(this::saveUserProfileToSharedPreferences, this::handleError)); + } + + private void showSnackBarMessage(String message) { + Snackbar.make(findViewById(R.id.login_form), message, Snackbar.LENGTH_LONG) + .show(); + } + + private void handleResponse(JwtToken jwtToken) { + showProgress(false); + + String token = jwtToken.getToken(); + JWT jwt = new JWT(token); + Claim userId = jwt.getClaim("nameid"); + Claim role = jwt.getClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role"); + + if (Objects.requireNonNull(role.asString()).equals("Student")) { + PrefUtils.storeIsTutor(getApplicationContext(), false); + } else { + PrefUtils.storeIsTutor(getApplicationContext(), true); + } + + PrefUtils.storeIsLoggedIn(getApplicationContext(), true); + PrefUtils.storeApiKey(getApplicationContext(), token); + PrefUtils.storeUserId(getApplicationContext(), userId.asString()); + + getUserProfile(userId.asString()); + + Intent data = new Intent(); + String txt = "Main Activity"; + data.setData(Uri.parse(txt)); + setResult(RESULT_OK, data); + finish(); + } + + private void handleError(Throwable error) { + showProgress(false); + + if (error instanceof HttpException) { + + ResponseBody responseBody = ((HttpException) error).response().errorBody(); + showSnackBarMessage(RestApiHelper.getErrorMessage(responseBody)); + + } else { + showSnackBarMessage("Network Error !"); + } + } + + private void saveUserProfileToSharedPreferences(User user) { + PrefUtils.storeUserFirstName(getApplicationContext(), user.getFirstName()); + PrefUtils.storeUserLastName(getApplicationContext(), user.getLastName()); + PrefUtils.storeUserName(getApplicationContext(), user.getUserName()); + } +} + +*/ + + +package com.uam.wmi.findmytutor.activity; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.annotation.TargetApi; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; @@ -28,7 +380,6 @@ import com.uam.wmi.findmytutor.model.ValidateUser; import com.uam.wmi.findmytutor.network.ApiClient; import com.uam.wmi.findmytutor.service.LdapService; import com.uam.wmi.findmytutor.service.UserService; -import com.uam.wmi.findmytutor.utils.LocaleHelper; import com.uam.wmi.findmytutor.utils.PrefUtils; import com.uam.wmi.findmytutor.utils.RestApiHelper; @@ -41,8 +392,7 @@ import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; import okhttp3.ResponseBody; -public class -LoginActivity extends AppCompatActivity { +public class LoginActivity extends AppCompatActivity { private AutoCompleteTextView mLoginNameView; private EditText mPasswordView; @@ -52,11 +402,6 @@ LoginActivity extends AppCompatActivity { private UserService userService; private CompositeDisposable disposable = new CompositeDisposable(); - @Override - protected void attachBaseContext(Context base) { - super.attachBaseContext(LocaleHelper.onAttach(base)); - } - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -157,9 +502,9 @@ LoginActivity extends AppCompatActivity { private void loginProcess(String email, String password) { ValidateUser user = new ValidateUser(email, password); - //LdapUser fakeUser = new LdapUser(email, password,"wmi","tutor",email,"Fałszywy",email); + // LdapUser fakeUser = new LdapUser(email, password,"wmi","tutor",email,"Fałszywy",email); disposable.add(ldapService.validate(user) - //disposable.add(ldapService.fakeValidate(fakeUser) + //disposable.add(ldapService.fakeValidate(fakeUser) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::handleResponse, this::handleError)); diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java index 73034da..7ab81f7 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java @@ -66,28 +66,6 @@ public class TutorTab extends AppCompatActivity { private RecyclerView.LayoutManager dutyHoursLayoutManager; private TutorTabViewModel newTab; - - - public boolean isEmailValid(String email) - { - String regExpn = - "^(([\\w-]+\\.)+[\\w-]+|([a-zA-Z]{1}|[\\w-]{2,}))@" - +"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?" - +"[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\." - +"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?" - +"[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|" - +"([a-zA-Z]+[\\w-]+\\.)+[a-zA-Z]{2,4})$"; - - CharSequence inputStr = email; - - Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE); - Matcher matcher = pattern.matcher(inputStr); - - if(matcher.matches()) - return true; - else - return false; - } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -118,8 +96,6 @@ public class TutorTab extends AppCompatActivity { getTutorTab(); -// findViewById(R.id.contentTutorTabInfoImageButton).setOnClickListener(v-> InfoHelperUtils.infoPopUp(v,R.layout.info_popup_tutor_tab)); - userName.setText(String.format("%s %s", PrefUtils.getUserFirstName(getApplicationContext()), PrefUtils.getUserLastName(getApplicationContext()))); disposable.add( @@ -236,7 +212,6 @@ public class TutorTab extends AppCompatActivity { }else{ userEmail.setError(getString(R.string.error_invalid_email)); } - }); } @@ -286,7 +261,6 @@ public class TutorTab extends AppCompatActivity { Toast.makeText(getApplicationContext(), "Network error " + error.getMessage(), Toast.LENGTH_SHORT).show(); - Log.e("WMI SUCC", String.valueOf(error)); } @@ -309,5 +283,21 @@ public class TutorTab extends AppCompatActivity { super.attachBaseContext(LocaleHelper.onAttach(base)); } + public boolean isEmailValid(String email) + { + String regExpn = + "^(([\\w-]+\\.)+[\\w-]+|([a-zA-Z]{1}|[\\w-]{2,}))@" + +"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?" + +"[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\." + +"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?" + +"[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|" + +"([a-zA-Z]+[\\w-]+\\.)+[a-zA-Z]{2,4})$"; + CharSequence inputStr = email; + + Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(inputStr); + + return matcher.matches(); + } } diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/UsersListFragment.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/UsersListFragment.java index bb50897..3788485 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/UsersListFragment.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/UsersListFragment.java @@ -317,6 +317,7 @@ public class UsersListFragment extends Fragment { tutorsList.addAll(users); mAdapter.notifyDataSetChanged(); toggleEmptyNotes(); + fetchTopCords(); } @Override @@ -434,7 +435,6 @@ public class UsersListFragment extends Fragment { private void fetchTopCords(){ disposable.add( coordinateService.getTopCoordinates() - .doOnSubscribe(t -> tutorsTimeStamps.clear()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::addTimestamps,this::showError)); diff --git a/app/src/main/java/com/uam/wmi/findmytutor/adapters/TutorsListAdapter.java b/app/src/main/java/com/uam/wmi/findmytutor/adapters/TutorsListAdapter.java index 7c45f8f..6bb61d2 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/adapters/TutorsListAdapter.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/adapters/TutorsListAdapter.java @@ -1,3 +1,4 @@ +/* package com.uam.wmi.findmytutor.adapters; import android.content.Context; @@ -105,3 +106,114 @@ public class TutorsListAdapter extends RecyclerView.Adapter { + + private Context context; + private List tutorsList; + private HashMap tutorsTimeStamps; + + public TutorsListAdapter(Context context, List tutors, HashMap tutorsTimeStamps) { + this.context = context; + this.tutorsList = tutors; + this.tutorsTimeStamps = tutorsTimeStamps; + } + @NonNull + @Override + public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.tutor_list_row, parent, false); + + return new MyViewHolder(itemView); + } + + @Override + public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { + Drawable image = null; + User tutor = tutorsList.get(position); + + holder.firstName.setText(String.format("%s %s", tutor.getFirstName(), tutor.getLastName())); + String ts = tutorsTimeStamps.get(tutor.getId()); + + if (tutor.isIsOnline()) { + image = context.getResources().getDrawable(R.drawable.user_list_online); + holder.lastSeen.setText(R.string.available_now); + holder.lastSeen.setVisibility(View.VISIBLE); + holder.loader.setVisibility(View.GONE); + } else if(tutor.isIsActive()){ + image = context.getResources().getDrawable(R.drawable.user_list_offline); + + if (ts != null){ + holder.lastSeen.setText(R.string.last_sign); + holder.lastSeen.append(String.format(": %s", ts)); + holder.loader.setVisibility(View.GONE); + } + } else { + image = context.getResources().getDrawable(R.drawable.user_list_off); + + if(ts == null){ + holder.lastSeen.setText(R.string.never_logged_in); + }else{ + holder.lastSeen.setText(R.string.last_sign); + holder.lastSeen.append(String.format(": %s", ts)); + } + holder.loader.setVisibility(View.GONE); + } + + image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight()); + holder.isOnline.setCompoundDrawables(image, null, null, null); + } + + @Override + public int getItemCount() { + return tutorsList.size(); + } + + class MyViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.firstName) + TextView firstName; + + @BindView(R.id.lastSeen) + TextView lastSeen; + + @BindView(R.id.isOnline) + TextView isOnline; + + @BindView(R.id.loader) + SpinKitView loader; + + MyViewHolder(View view) { + super(view); + ButterKnife.bind(this, view); + } + } +} + + + diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java index f7aaacf..3ff119f 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java @@ -6,7 +6,7 @@ import java.util.Arrays; import java.util.List; public class Const { - public final static String BASE_URL = "https://s416084.projektstudencki.pl/master/"; + public final static String BASE_URL = "https://s416084.projektstudencki.pl/develop/"; public final static Integer mapRefreshInterval = 6000; public final static Integer onlineBackgroundLocationInterval = 7000; public final static Integer offlineBackgroundLocationInterval = 360000; diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index a96ee0c..ceb6c7b 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -43,9 +43,10 @@ - - - - - Dostępny teraz Profil użytkownika + Nigdy + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7fa8adc..77a24cd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -456,4 +456,5 @@ Status Available now Last seen + Never