Armoire UX improvements

This commit is contained in:
Phillip Thelen 2022-04-26 13:35:19 +02:00
parent d8138fdfdf
commit 57f748de77
7 changed files with 83 additions and 31 deletions

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#4DFEDEAD" />
<corners android:radius="20dip"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -15,9 +15,13 @@
android:left="3dp"
android:right="3dp"
android:top="3dp">
<shape android:shape="rectangle" >
<shape
android:shape="rectangle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<solid android:color="@color/brand_400" />
<corners android:radius="6dp" />
</shape>
<ripple android:color="@color/white" />
</item>
</layer-list>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#66FEDEAD"/>
<corners android:radius="20dip"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -20,7 +20,7 @@
android:id="@+id/gold_view"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:background="@drawable/pill_bg_yellow_500"
android:background="@drawable/armoire_gold_background"
android:gravity="center"
android:paddingStart="6dp"
android:paddingEnd="8dp"
@ -36,8 +36,8 @@
android:layout_marginBottom="23dp">
<ImageView
android:id="@+id/icon_view"
android:layout_width="@dimen/shopitem_image_size"
android:layout_height="@dimen/shopitem_image_size"
android:layout_width="136dp"
android:layout_height="136dp"
android:layout_gravity="center"/>
</FrameLayout>
@ -70,7 +70,7 @@
android:orientation="vertical"
android:gravity="center"
android:paddingHorizontal="12dp"
android:paddingTop="24dp">
android:paddingTop="28dp">
<TextView
android:id="@+id/equipment_count_view"
android:layout_width="wrap_content"
@ -122,7 +122,7 @@
android:layout_height="wrap_content"
android:text="@string/armoire_drop_rates"
android:textColor="@color/brand_500"
android:layout_marginTop="12dp"
android:layout_marginTop="22dp"
style="@style/Body2"/>
</LinearLayout>
</LinearLayout>

View file

@ -17,4 +17,11 @@
android:layout_height="wrap_content"
app:currency="gold"
android:layout_marginStart="24dp" />
<ProgressBar
android:id="@+id/loading_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:indeterminateBehavior="cycle"
android:indeterminateTint="@color/white"/>
</merge>

View file

@ -17,6 +17,7 @@ import com.google.android.gms.ads.rewarded.RewardItem
import com.google.android.gms.ads.rewarded.RewardedAd
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.habitrpg.android.habitica.BuildConfig
import com.habitrpg.android.habitica.proxy.AnalyticsManager
import java.io.UnsupportedEncodingException
@ -32,11 +33,11 @@ enum class AdType {
val adUnitID: String
get() {
if (BuildConfig.DEBUG) {
if (BuildConfig.DEBUG || BuildConfig.TESTING_LEVEL == "staff" || BuildConfig.TESTING_LEVEL == "alpha") {
return "ca-app-pub-3940256099942544/5224354917"
}
return when (this) {
ARMOIRE -> "ca-app-pub-5911973472413421/9392092486\n"
ARMOIRE -> "ca-app-pub-5911973472413421/9392092486"
SPELL -> "ca-app-pub-5911973472413421/1738504765"
FAINT -> "ca-app-pub-5911973472413421/1738504765"
}
@ -107,6 +108,7 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
MobileAds.initialize(context) {
currentAdStatus = AdStatus.READY
onComplete()
FirebaseCrashlytics.getInstance().recordException(Throwable("Ads Initialized"))
}
}
@ -142,7 +144,7 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
}
}
fun prepare() {
fun prepare(onComplete: ((Boolean) -> Unit)? = null) {
whenAdsInitialized(activity) {
val adRequest = AdRequest.Builder()
.build()
@ -150,19 +152,22 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
if (BuildConfig.DEBUG || BuildConfig.TESTING_LEVEL == "staff" || BuildConfig.TESTING_LEVEL == "alpha") {
if (!adRequest.isTestDevice(activity)) {
// users in this group need to be configured as Test device. better to fail if they aren't
currentAdStatus = AdStatus.DISABLED
return@whenAdsInitialized
// currentAdStatus = AdStatus.DISABLED
FirebaseCrashlytics.getInstance().recordException(Throwable("Device not test device"))
}
}
RewardedAd.load(activity, type.adUnitID, adRequest, object : RewardedAdLoadCallback() {
override fun onAdFailedToLoad(adError: LoadAdError) {
FirebaseCrashlytics.getInstance().recordException(Throwable(adError.message))
rewardAction(false)
onComplete?.invoke(false)
}
override fun onAdLoaded(rewardedAd: RewardedAd) {
this@AdHandler.rewardedAd = rewardedAd
configureReward()
onComplete?.invoke(true)
}
})
}

View file

@ -3,7 +3,6 @@ package com.habitrpg.android.habitica.ui.views.ads
import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleCoroutineScope
@ -26,6 +25,19 @@ class AdButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : LinearLayout(context, attrs) {
var state: State = State.EMPTY
set(value) {
field = value
updateViews()
}
enum class State {
EMPTY,
READY,
LOADING,
UNAVAILABLE
}
private var updateJob: Job? = null
private var nextAdDate: Date? = null
private val binding = AdButtonBinding.inflate(context.layoutInflater, this)
@ -36,12 +48,6 @@ class AdButton @JvmOverloads constructor(
updateViews()
}
var isAvailable: Boolean = true
set(value) {
field = value
updateViews()
}
init {
context.theme?.obtainStyledAttributes(
attrs,
@ -55,21 +61,39 @@ class AdButton @JvmOverloads constructor(
binding.currencyView.setTextColor(ContextCompat.getColor(context, R.color.white))
binding.currencyView.value = 0.0
gravity = Gravity.CENTER
state = State.EMPTY
}
private fun updateViews() {
if (isAvailable) {
binding.textView.text = text
binding.textView.alpha = 1.0f
binding.currencyView.visibility = View.VISIBLE
setBackgroundResource(R.drawable.ad_button_background)
} else {
binding.textView.text = context.getString(R.string.available_in, nextAdDate?.getShortRemainingString() ?: "")
binding.textView.alpha = 0.75f
binding.currencyView.visibility = View.GONE
setBackgroundResource(R.drawable.ad_button_background_disabled)
when (state) {
State.READY -> {
binding.loadingIndicator.visibility = GONE
binding.textView.text = text
binding.textView.alpha = 1.0f
binding.textView.visibility = VISIBLE
binding.currencyView.visibility = VISIBLE
setBackgroundResource(R.drawable.ad_button_background)
}
State.UNAVAILABLE -> {
binding.loadingIndicator.visibility = GONE
binding.textView.text = context.getString(R.string.available_in, nextAdDate?.getShortRemainingString() ?: "")
binding.textView.alpha = 0.75f
binding.textView.visibility = VISIBLE
binding.currencyView.visibility = GONE
setBackgroundResource(R.drawable.ad_button_background_disabled)
}
State.EMPTY -> {
binding.loadingIndicator.visibility = GONE
binding.textView.visibility = GONE
binding.currencyView.visibility = GONE
}
State.LOADING -> {
binding.loadingIndicator.visibility = VISIBLE
binding.textView.visibility = GONE
binding.currencyView.visibility = GONE
}
}
isEnabled = isAvailable
isEnabled = state == State.READY
}
fun updateForAdType(type: AdType, lifecycleScope: LifecycleCoroutineScope) {
@ -81,11 +105,11 @@ class AdButton @JvmOverloads constructor(
updateJob = lifecycleScope.launch(Dispatchers.Main) {
while (nextAdDate?.after(Date()) == true) {
val remaining = ((nextAdDate?.time ?: 0L) - Date().time).toDuration(DurationUnit.MILLISECONDS)
isAvailable = remaining.isNegative()
state = if (remaining.isNegative()) State.READY else State.UNAVAILABLE
updateViews()
delay(1.toDuration(remaining.getMinuteOrSeconds()))
}
isAvailable = true
state = State.READY
}
}
}