diff --git a/Habitica/res/drawable-night/armoire_gold_background.xml b/Habitica/res/drawable-night/armoire_gold_background.xml new file mode 100644 index 000000000..1f8085a95 --- /dev/null +++ b/Habitica/res/drawable-night/armoire_gold_background.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Habitica/res/drawable/ad_button_background.xml b/Habitica/res/drawable/ad_button_background.xml index 70e52471b..87c8b59d1 100644 --- a/Habitica/res/drawable/ad_button_background.xml +++ b/Habitica/res/drawable/ad_button_background.xml @@ -15,9 +15,13 @@ android:left="3dp" android:right="3dp" android:top="3dp"> - + + diff --git a/Habitica/res/drawable/armoire_gold_background.xml b/Habitica/res/drawable/armoire_gold_background.xml new file mode 100644 index 000000000..5db42576d --- /dev/null +++ b/Habitica/res/drawable/armoire_gold_background.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/activity_armoire.xml b/Habitica/res/layout/activity_armoire.xml index e6867e5ce..43eacc7bc 100644 --- a/Habitica/res/layout/activity_armoire.xml +++ b/Habitica/res/layout/activity_armoire.xml @@ -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"> @@ -70,7 +70,7 @@ android:orientation="vertical" android:gravity="center" android:paddingHorizontal="12dp" - android:paddingTop="24dp"> + android:paddingTop="28dp"> diff --git a/Habitica/res/layout/ad_button.xml b/Habitica/res/layout/ad_button.xml index ba1d44206..b5a4e893f 100644 --- a/Habitica/res/layout/ad_button.xml +++ b/Habitica/res/layout/ad_button.xml @@ -17,4 +17,11 @@ android:layout_height="wrap_content" app:currency="gold" android:layout_marginStart="24dp" /> + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AdHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AdHandler.kt index 04013b870..67f9b7671 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AdHandler.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AdHandler.kt @@ -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) } }) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ads/AdButton.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ads/AdButton.kt index c0b385ae3..6f2ad0075 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ads/AdButton.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ads/AdButton.kt @@ -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 } } }