Notify user when they are ratelimited

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2023-04-23 16:21:40 +05:30
parent 2daa434dea
commit 2e024150de
6 changed files with 105 additions and 7 deletions

View File

@@ -28,7 +28,10 @@ import android.view.KeyEvent
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.aurora.Constants
import com.aurora.extensions.close
import com.aurora.extensions.open
@@ -48,6 +51,7 @@ import com.aurora.store.view.ui.downloads.DownloadActivity
import com.aurora.store.view.ui.sheets.FilterSheet
import com.aurora.store.viewmodel.search.SearchResultViewModel
import com.google.android.material.textfield.TextInputEditText
import kotlinx.coroutines.launch
class SearchResultsActivity : BaseActivity(), OnSharedPreferenceChangeListener {
@@ -101,6 +105,18 @@ class SearchResultsActivity : BaseActivity(), OnSharedPreferenceChangeListener {
query?.let {
updateQuery(it)
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
VM.responseCode.collect {
when (it) {
429 -> attachErrorLayout(getString(R.string.rate_limited))
else -> detachErrorLayout()
}
}
}
}
}
override fun onDestroy() {
@@ -110,6 +126,19 @@ class SearchResultsActivity : BaseActivity(), OnSharedPreferenceChangeListener {
super.onDestroy()
}
private fun attachErrorLayout(message: String) {
B.recycler.visibility = View.GONE
B.filterFab.visibility = View.GONE
B.errorLayout.visibility = View.VISIBLE
B.errorMessage.text = message
}
private fun detachErrorLayout() {
B.recycler.visibility = View.VISIBLE
B.filterFab.visibility = View.VISIBLE
B.errorLayout.visibility = View.GONE
}
private fun attachToolbar() {
searchView = B.layoutViewToolbar.inputSearch
@@ -253,4 +282,4 @@ class SearchResultsActivity : BaseActivity(), OnSharedPreferenceChangeListener {
}
}
}
}
}

View File

@@ -21,18 +21,25 @@ package com.aurora.store.viewmodel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.aurora.store.data.RequestState
import com.aurora.store.data.network.HttpClient
import com.aurora.store.data.providers.NetworkProvider
import com.aurora.store.util.Log
import com.google.android.material.snackbar.Snackbar
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import java.lang.reflect.Modifier
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel(application),
NetworkProvider.NetworkListener {
private lateinit var networkListener: NetworkProvider.NetworkListener
val responseCode = HttpClient.getPreferredClient().responseCode
protected val gson: Gson = GsonBuilder()
.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.STATIC)
.create()
@@ -45,6 +52,9 @@ abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel
requestState = RequestState.Init
NetworkProvider.addListener(this)
// Start collecting response code for requests
responseCode.launchIn(viewModelScope)
}
abstract fun observe()
@@ -77,4 +87,4 @@ abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel
NetworkProvider.removeListener(this)
super.onCleared()
}
}
}

View File

@@ -20,7 +20,6 @@
package com.aurora.store.viewmodel.search
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.aurora.gplayapi.data.models.AuthData
@@ -29,11 +28,13 @@ import com.aurora.gplayapi.helpers.SearchHelper
import com.aurora.store.data.network.HttpClient
import com.aurora.store.data.providers.AuthProvider
import com.aurora.extensions.flushAndAdd
import com.aurora.store.data.RequestState
import com.aurora.store.viewmodel.BaseAndroidViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope
class SearchResultViewModel(application: Application) : AndroidViewModel(application) {
class SearchResultViewModel(application: Application) : BaseAndroidViewModel(application) {
private val authData: AuthData = AuthProvider
.with(application)
@@ -91,4 +92,8 @@ class SearchResultViewModel(application: Application) : AndroidViewModel(applica
}
}
}
}
override fun observe() {
requestState = RequestState.Init
}
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022, Google LLC
~
~ Aurora Store 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 2 of the License, or
~ (at your option) any later version.
~
~ Aurora Store 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 Aurora Store. If not, see <http://www.gnu.org/licenses/>.
~
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="@color/colorAccent">
<path
android:fillColor="@android:color/white"
android:pathData="M261,638Q273,638 282,629Q291,620 291,608Q291,596 282,587Q273,578 261,578Q249,578 240,587Q231,596 231,608Q231,620 240,629Q249,638 261,638ZM231,508L291,508L291,317L231,317L231,508ZM410,588L729,588L729,528L410,528L410,588ZM410,417L729,417L729,357L410,357L410,417ZM132,800Q108,800 90,782Q72,764 72,740L72,220Q72,196 90,178Q108,160 132,160L828,160Q852,160 870,178Q888,196 888,220L888,740Q888,764 870,782Q852,800 828,800L132,800ZM132,740L828,740Q828,740 828,740Q828,740 828,740L828,220Q828,220 828,220Q828,220 828,220L132,220Q132,220 132,220Q132,220 132,220L132,740Q132,740 132,740Q132,740 132,740ZM132,740L132,740Q132,740 132,740Q132,740 132,740L132,220Q132,220 132,220Q132,220 132,220L132,220Q132,220 132,220Q132,220 132,220L132,740Q132,740 132,740Q132,740 132,740Z"/>
</vector>

View File

@@ -40,6 +40,29 @@
app:itemSpacing="@dimen/margin_normal" />
</RelativeLayout>
<LinearLayout
android:id="@+id/error_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center|center_vertical"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:layout_width="96dp"
android:layout_height="96dp"
android:contentDescription="@string/error"
android:src="@drawable/ic_problem" />
<TextView
android:id="@+id/error_message"
style="@style/TextAppearance.Aurora.SubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rate_limited" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/filter_fab"
style="@style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
@@ -53,4 +76,4 @@
app:backgroundTint="@color/colorAccent"
app:icon="@drawable/ic_filter"
app:iconTint="@color/colorWhite" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -400,4 +400,6 @@
<string name="ui_accent_13">Deep blue</string>
<string name="update_available">update available</string>
<string name="updates_available">updates available</string>
</resources>
<string name="rate_limited">Oops, This account is rate limited!</string>
<string name="error">An error occurred!</string>
</resources>