From cd3cd6f9b7fef209859e6713ef4f96d3687a0109 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Sat, 27 May 2023 18:51:43 +0530 Subject: [PATCH] Handle account UI login UI progress better * Show server down error message on 503 status * Don't allow users to click another login option if another login is in progress * Reset progress bar's visibility properly Signed-off-by: Aayush Gupta --- .../java/com/aurora/extensions/Activity.kt | 1 + .../java/com/aurora/extensions/Context.kt | 8 +++ .../main/java/com/aurora/store/data/State.kt | 1 + .../store/view/ui/account/AccountActivity.kt | 43 +++++++++++++-- .../store/view/ui/splash/SplashActivity.kt | 55 +++++++++++++++++-- .../store/viewmodel/auth/AuthViewModel.kt | 12 +++- app/src/main/res/values/strings.xml | 2 + 7 files changed, 110 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/aurora/extensions/Activity.kt b/app/src/main/java/com/aurora/extensions/Activity.kt index 1e76dcd31..8beb763f9 100644 --- a/app/src/main/java/com/aurora/extensions/Activity.kt +++ b/app/src/main/java/com/aurora/extensions/Activity.kt @@ -27,6 +27,7 @@ import androidx.appcompat.app.AppCompatActivity fun AppCompatActivity.close() { + setResult(AppCompatActivity.RESULT_OK) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { finishAfterTransition() } else { diff --git a/app/src/main/java/com/aurora/extensions/Context.kt b/app/src/main/java/com/aurora/extensions/Context.kt index 52271b51f..20b8c4d90 100644 --- a/app/src/main/java/com/aurora/extensions/Context.kt +++ b/app/src/main/java/com/aurora/extensions/Context.kt @@ -127,6 +127,14 @@ fun Context.restartApp() { exitProcess(0) } +fun Context.getEmptyActivityAnimation(): ActivityOptionsCompat { + return ActivityOptionsCompat.makeCustomAnimation( + this, + android.R.anim.fade_in, + android.R.anim.fade_out + ) +} + fun Context.getEmptyActivityBundle(): Bundle? { return ActivityOptionsCompat.makeCustomAnimation( this, diff --git a/app/src/main/java/com/aurora/store/data/State.kt b/app/src/main/java/com/aurora/store/data/State.kt index 732508a41..b5f86bd73 100644 --- a/app/src/main/java/com/aurora/store/data/State.kt +++ b/app/src/main/java/com/aurora/store/data/State.kt @@ -40,5 +40,6 @@ sealed class AuthState { object SignedIn : AuthState() object SignedOut : AuthState() object Valid : AuthState() + object Fetching: AuthState() data class Status(val status: String?) : AuthState() } \ No newline at end of file diff --git a/app/src/main/java/com/aurora/store/view/ui/account/AccountActivity.kt b/app/src/main/java/com/aurora/store/view/ui/account/AccountActivity.kt index ff8efbd6d..403a3fadc 100644 --- a/app/src/main/java/com/aurora/store/view/ui/account/AccountActivity.kt +++ b/app/src/main/java/com/aurora/store/view/ui/account/AccountActivity.kt @@ -19,11 +19,14 @@ package com.aurora.store.view.ui.account +import android.content.Intent import android.os.Bundle import android.view.View +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.aurora.extensions.browse import com.aurora.extensions.close +import com.aurora.extensions.getEmptyActivityAnimation import com.aurora.extensions.load import com.aurora.gplayapi.data.models.AuthData import com.aurora.store.R @@ -32,6 +35,7 @@ import com.aurora.store.data.event.BusEvent import com.aurora.store.data.providers.AccountProvider import com.aurora.store.data.providers.AuthProvider import com.aurora.store.databinding.ActivityAccountBinding +import com.aurora.store.util.Preferences import com.aurora.store.view.ui.commons.BaseActivity import com.aurora.store.viewmodel.auth.AuthViewModel import com.bumptech.glide.load.resource.bitmap.RoundedCorners @@ -53,6 +57,15 @@ class AccountActivity : BaseActivity() { private val URL_LICENSE = "https://gitlab.com/AuroraOSS/AuroraStore/blob/master/LICENSE" private val URL_DISCLAIMER = "https://gitlab.com/AuroraOSS/AuroraStore/blob/master/DISCLAIMER.md" + private val startForResult = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == RESULT_CANCELED) { + resetActions() + } else { + B.btnGoogle.updateProgress(true) + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -74,6 +87,9 @@ class AccountActivity : BaseActivity() { VM.liveData.observe(this) { when (it) { + AuthState.Fetching -> { + updateStatus(getString(R.string.requesting_new_session)) + } AuthState.Valid -> { } @@ -99,6 +115,7 @@ class AccountActivity : BaseActivity() { is AuthState.Status -> { updateStatus(it.status) + resetActions() } } } @@ -173,13 +190,19 @@ class AccountActivity : BaseActivity() { B.btnGoogle.updateProgress(false) B.btnAnonymous.addOnClickListener { - B.btnAnonymous.updateProgress(true) - VM.buildAnonymousAuthData() + if (VM.liveData.value != AuthState.Fetching) { + B.btnAnonymous.updateProgress(true) + VM.buildAnonymousAuthData() + } } B.btnGoogle.addOnClickListener { - B.btnGoogle.updateProgress(true) - openGoogleActivity() + if (VM.liveData.value != AuthState.Fetching) { + B.btnGoogle.updateProgress(true) + Preferences.putBoolean(this, Preferences.PREFERENCE_ADVANCED_SEARCH_IN_CTT, false) + val intent = Intent(this, GoogleActivity::class.java) + startForResult.launch(intent, getEmptyActivityAnimation()) + } } B.btnLogout.addOnClickListener { @@ -195,6 +218,18 @@ class AccountActivity : BaseActivity() { } } + private fun resetActions() { + B.btnGoogle.apply { + updateProgress(false) + isEnabled = true + } + + B.btnAnonymous.apply { + updateProgress(false) + isEnabled = true + } + } + private fun updateUserProfile() { authData = AuthProvider.with(this).getAuthData() diff --git a/app/src/main/java/com/aurora/store/view/ui/splash/SplashActivity.kt b/app/src/main/java/com/aurora/store/view/ui/splash/SplashActivity.kt index a9b257bfa..5d11b3758 100644 --- a/app/src/main/java/com/aurora/store/view/ui/splash/SplashActivity.kt +++ b/app/src/main/java/com/aurora/store/view/ui/splash/SplashActivity.kt @@ -19,10 +19,13 @@ package com.aurora.store.view.ui.splash +import android.content.Intent import android.os.Bundle import android.view.Menu import android.view.MenuItem +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider +import com.aurora.extensions.getEmptyActivityAnimation import com.aurora.extensions.hide import com.aurora.extensions.load import com.aurora.extensions.open @@ -32,7 +35,9 @@ import com.aurora.store.R import com.aurora.store.data.AuthState import com.aurora.store.data.event.BusEvent import com.aurora.store.databinding.ActivitySplashBinding +import com.aurora.store.util.Preferences import com.aurora.store.view.ui.account.AccountActivity +import com.aurora.store.view.ui.account.GoogleActivity import com.aurora.store.view.ui.commons.BaseActivity import com.aurora.store.view.ui.commons.BlacklistActivity import com.aurora.store.view.ui.preferences.SettingsActivity @@ -47,6 +52,15 @@ class SplashActivity : BaseActivity() { private lateinit var VM: AuthViewModel private lateinit var B: ActivitySplashBinding + private val startForResult = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == RESULT_CANCELED) { + resetActions() + } else { + B.btnGoogle.updateProgress(true) + } + } + override fun onConnected() { hideNetworkConnectivitySheet() } @@ -81,6 +95,9 @@ class SplashActivity : BaseActivity() { VM.liveData.observe(this) { when (it) { + AuthState.Fetching -> { + updateStatus(getString(R.string.requesting_new_session)) + } AuthState.Valid -> { moveToContent() } @@ -106,6 +123,7 @@ class SplashActivity : BaseActivity() { is AuthState.Status -> { updateStatus(it.status) + resetActions() } } } @@ -194,18 +212,43 @@ class SplashActivity : BaseActivity() { private fun attachActions() { B.btnAnonymous.addOnClickListener { - B.btnAnonymous.updateProgress(true) - VM.buildAnonymousAuthData() + if (VM.liveData.value != AuthState.Fetching) { + B.btnAnonymous.updateProgress(true) + VM.buildAnonymousAuthData() + } } B.btnAnonymousInsecure.addOnClickListener { - B.btnAnonymousInsecure.updateProgress(true) - VM.buildInSecureAnonymousAuthData() + if (VM.liveData.value != AuthState.Fetching) { + B.btnAnonymousInsecure.updateProgress(true) + VM.buildInSecureAnonymousAuthData() + } } B.btnGoogle.addOnClickListener { - B.btnGoogle.updateProgress(true) - openGoogleActivity() + if (VM.liveData.value != AuthState.Fetching) { + B.btnGoogle.updateProgress(true) + Preferences.putBoolean(this, Preferences.PREFERENCE_ADVANCED_SEARCH_IN_CTT, false) + val intent = Intent(this, GoogleActivity::class.java) + startForResult.launch(intent, getEmptyActivityAnimation()) + } + } + } + + private fun resetActions() { + B.btnGoogle.apply { + updateProgress(false) + isEnabled = true + } + + B.btnAnonymous.apply { + updateProgress(false) + isEnabled = true + } + + B.btnAnonymousInsecure.apply { + updateProgress(false) + isEnabled = true } } diff --git a/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt index 1dce316ee..0ccd6547d 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt @@ -20,6 +20,7 @@ package com.aurora.store.viewmodel.auth import android.app.Application +import android.content.Context import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.aurora.Constants @@ -28,6 +29,7 @@ import com.aurora.gplayapi.data.providers.DeviceInfoProvider import com.aurora.gplayapi.helpers.AuthHelper import com.aurora.gplayapi.helpers.AuthValidator import com.aurora.store.AccountType +import com.aurora.store.R import com.aurora.store.data.AuthState import com.aurora.store.data.RequestState import com.aurora.store.data.model.InsecureAuth @@ -102,7 +104,7 @@ class AuthViewModel(application: Application) : BaseAndroidViewModel(application } private fun buildSecureAnonymousAuthData() { - updateStatus("Requesting new session") + liveData.postValue(AuthState.Fetching) task { var properties = NativeDeviceInfoProvider(getApplication()) @@ -127,6 +129,9 @@ class AuthViewModel(application: Application) : BaseAndroidViewModel(application when (playResponse.code) { 404 -> throw Exception("Server unreachable") 429 -> throw Exception("Oops, You are rate limited") + 503 -> throw Exception( + (getApplication() as Context).getString(R.string.server_maintenance) + ) else -> throw Exception(playResponse.errorString) } } @@ -140,7 +145,7 @@ class AuthViewModel(application: Application) : BaseAndroidViewModel(application } fun buildInSecureAnonymousAuthData() { - updateStatus("Requesting new session") + liveData.postValue(AuthState.Fetching) task { var properties = NativeDeviceInfoProvider(getApplication()) @@ -166,6 +171,9 @@ class AuthViewModel(application: Application) : BaseAndroidViewModel(application when (playResponse.code) { 404 -> throw Exception("Server unreachable") 429 -> throw Exception("Oops, You are rate limited") + 503 -> throw Exception( + (getApplication() as Context).getString(R.string.server_maintenance) + ) else -> throw Exception(playResponse.errorString) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 54f917ef4..2e28c67ba 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -349,4 +349,6 @@ %1$s • API %2$s Required permissions were denied. Please grant them in order to continue the action Search for Apps & Games + Requesting new session + Server down for maintenance