/* * Copyright 2015 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.plaidapp.ui; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.transition.TransitionManager; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; import butterknife.BindView; import butterknife.ButterKnife; import io.plaidapp.BuildConfig; import io.plaidapp.R; import io.plaidapp.data.api.dribbble.DribbbleAuthService; import io.plaidapp.data.api.dribbble.model.AccessToken; import io.plaidapp.data.api.dribbble.model.User; import io.plaidapp.data.prefs.DribbblePrefs; import io.plaidapp.ui.transitions.FabTransform; import io.plaidapp.ui.transitions.MorphTransform; import io.plaidapp.util.ScrimUtil; import io.plaidapp.util.glide.CircleTransform; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class DribbbleLogin extends Activity { private static final String STATE_LOGIN_FAILED = "loginFailed"; boolean isDismissing = false; boolean isLoginFailed = false; @BindView(R.id.container) ViewGroup container; @BindView(R.id.login_message) TextView message; @BindView(R.id.login) Button login; @BindView(R.id.loading) ProgressBar loading; @BindView(R.id.login_failed_message) TextView loginFailed; DribbblePrefs dribbblePrefs; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dribbble_login); ButterKnife.bind(this); loading.setVisibility(View.GONE); dribbblePrefs = DribbblePrefs.get(this); if (!FabTransform.setup(this, container)) { MorphTransform.setup(this, container, ContextCompat.getColor(this, R.color.background_light), getResources().getDimensionPixelSize(R.dimen.dialog_corners)); } if (savedInstanceState != null) { isLoginFailed = savedInstanceState.getBoolean(STATE_LOGIN_FAILED, false); loginFailed.setVisibility(isLoginFailed ? View.VISIBLE : View.GONE); } checkAuthCallback(getIntent()); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); checkAuthCallback(intent); } public void doLogin(View view) { showLoading(); dribbblePrefs.login(DribbbleLogin.this); } public void dismiss(View view) { isDismissing = true; setResult(Activity.RESULT_CANCELED); finishAfterTransition(); } @Override public void onBackPressed() { dismiss(null); } @Override protected void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); savedInstanceState.putBoolean(STATE_LOGIN_FAILED, isLoginFailed); } void showLoginFailed() { isLoginFailed = true; showLogin(); loginFailed.setVisibility(View.VISIBLE); } void showLoggedInUser() { final Call<User> authenticatedUser = dribbblePrefs.getApi().getAuthenticatedUser(); authenticatedUser.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { final User user = response.body(); dribbblePrefs.setLoggedInUser(user); final Toast confirmLogin = new Toast(getApplicationContext()); final View v = LayoutInflater.from(DribbbleLogin.this).inflate(R.layout .toast_logged_in_confirmation, null, false); ((TextView) v.findViewById(R.id.name)).setText(user.name.toLowerCase()); // need to use app context here as the activity will be destroyed shortly Glide.with(getApplicationContext()) .load(user.avatar_url) .placeholder(R.drawable.ic_player) .transform(new CircleTransform(getApplicationContext())) .into((ImageView) v.findViewById(R.id.avatar)); v.findViewById(R.id.scrim).setBackground(ScrimUtil.makeCubicGradientScrimDrawable (ContextCompat.getColor(DribbbleLogin.this, R.color.scrim), 5, Gravity.BOTTOM)); confirmLogin.setView(v); confirmLogin.setGravity(Gravity.BOTTOM | Gravity.FILL_HORIZONTAL, 0, 0); confirmLogin.setDuration(Toast.LENGTH_LONG); confirmLogin.show(); } @Override public void onFailure(Call<User> call, Throwable t) { } }); } private void showLoading() { TransitionManager.beginDelayedTransition(container); message.setVisibility(View.GONE); login.setVisibility(View.GONE); loginFailed.setVisibility(View.GONE); loading.setVisibility(View.VISIBLE); } private void showLogin() { TransitionManager.beginDelayedTransition(container); message.setVisibility(View.VISIBLE); login.setVisibility(View.VISIBLE); loading.setVisibility(View.GONE); } private void checkAuthCallback(Intent intent) { if (intent != null && intent.getData() != null && !TextUtils.isEmpty(intent.getData().getAuthority()) && DribbblePrefs.LOGIN_CALLBACK.equals(intent.getData().getAuthority())) { showLoading(); getAccessToken(intent.getData().getQueryParameter("code")); } } private void getAccessToken(String code) { final DribbbleAuthService dribbbleAuthApi = new Retrofit.Builder() .baseUrl(DribbbleAuthService.ENDPOINT) .addConverterFactory(GsonConverterFactory.create()) .build() .create((DribbbleAuthService.class)); final Call<AccessToken> accessTokenCall = dribbbleAuthApi.getAccessToken(BuildConfig .DRIBBBLE_CLIENT_ID, BuildConfig.DRIBBBLE_CLIENT_SECRET, code); accessTokenCall.enqueue(new Callback<AccessToken>() { @Override public void onResponse(Call<AccessToken> call, Response<AccessToken> response) { if (response.body() == null) { showLoginFailed(); return; } isLoginFailed = false; dribbblePrefs.setAccessToken(response.body().access_token); showLoggedInUser(); setResult(Activity.RESULT_OK); finishAfterTransition(); } @Override public void onFailure(Call<AccessToken> call, Throwable t) { Log.e(getClass().getCanonicalName(), t.getMessage(), t); showLoginFailed(); } }); } }