diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 9d83d954c..17e152c6a 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -155,7 +155,7 @@ android { buildConfigField "String", "TESTING_LEVEL", "\"production\"" resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW" - versionCode 3070 + versionCode 3077 versionName "3.4.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/Habitica/res/values-ja/strings.xml b/Habitica/res/values-ja/strings.xml index 37f3599e7..a8ce0d610 100644 --- a/Habitica/res/values-ja/strings.xml +++ b/Habitica/res/values-ja/strings.xml @@ -900,7 +900,7 @@ 有料プランを再開する 有料プランにご加入いただきありがとうございます 有料プランの期間をあなたのご都合に合わせて選びましょう - %@に止める + %sに止める くり返さない キャンセルしました 招待状を送る diff --git a/Habitica/res/values-tr/strings.xml b/Habitica/res/values-tr/strings.xml index a2263a37a..fc1b4b85e 100644 --- a/Habitica/res/values-tr/strings.xml +++ b/Habitica/res/values-tr/strings.xml @@ -1096,6 +1096,6 @@ %s gönderdin Beni geri al Şimdi olmaz - Sorularınızın bir başka oyuncu tarafından cevaplanması için% s içinde bir mesaj gönderin. + Sorularınızın bir başka oyuncu tarafından cevaplanması için%s içinde bir mesaj gönderin. Bir Alışkanlık, Günlük İş veya Yapılacak İş \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt index 27f27e7bc..9de557ca3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt @@ -103,6 +103,7 @@ abstract class HabiticaBaseApplication : Application() { } var builder = ImageLoader.Builder(this) .transition(CrossfadeTransition()) + .allowHardware(false) .componentRegistry { if (SDK_INT >= 28) { add(ImageDecoderDecoder(this@HabiticaBaseApplication)) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaPurchaseVerifier.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaPurchaseVerifier.kt index 5d062fcb8..541294ea8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaPurchaseVerifier.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaPurchaseVerifier.kt @@ -20,6 +20,7 @@ import org.solovyev.android.checkout.RequestListener import org.solovyev.android.checkout.ResponseCodes import retrofit2.HttpException import java.util.* +import kotlin.math.abs class HabiticaPurchaseVerifier(context: Context, apiClient: ApiClient) : BasePurchaseVerifier() { private val apiClient: ApiClient @@ -40,8 +41,8 @@ class HabiticaPurchaseVerifier(context: Context, apiClient: ApiClient) : BasePur purchasedOrderList.add(purchase.orderId) verifiedPurchases.add(purchase) processedPurchase(purchase, allPurchases, verifiedPurchases, requestListener) - val giftedID = removeGift(purchase.sku) - EventBus.getDefault().post(ConsumablePurchasedEvent(purchase, giftedID)) + val gift = removeGift(purchase.sku) + EventBus.getDefault().post(ConsumablePurchasedEvent(purchase, gift?.second)) }) { throwable: Throwable -> handleError(throwable, purchase, allPurchases, requestListener, verifiedPurchases) } @@ -52,8 +53,8 @@ class HabiticaPurchaseVerifier(context: Context, apiClient: ApiClient) : BasePur purchasedOrderList.add(purchase.orderId) verifiedPurchases.add(purchase) processedPurchase(purchase, allPurchases, verifiedPurchases, requestListener) - val giftedID = removeGift(purchase.sku) - EventBus.getDefault().post(ConsumablePurchasedEvent(purchase, giftedID)) + val gift = removeGift(purchase.sku) + EventBus.getDefault().post(ConsumablePurchasedEvent(purchase, gift?.second)) }) { throwable: Throwable -> handleError(throwable, purchase, allPurchases, requestListener, verifiedPurchases) } @@ -104,9 +105,14 @@ class HabiticaPurchaseVerifier(context: Context, apiClient: ApiClient) : BasePur validationRequest.transaction = Transaction() validationRequest.transaction?.receipt = purchase.data validationRequest.transaction?.signature = purchase.signature - if (pendingGifts.containsKey(purchase.sku)) { - validationRequest.gift = IAPGift() - validationRequest.gift?.uuid = pendingGifts[purchase.sku] + pendingGifts[purchase.sku]?.let { gift -> + // If the gift and the purchase happened within 5 minutes, we consider them to match. + // Otherwise the gift is probably an old one that wasn't cleared out correctly + if (abs(gift.first.time - purchase.time) < 300000) { + validationRequest.gift = IAPGift(gift.second) + } else { + removeGift(purchase.sku) + } } return validationRequest } @@ -132,16 +138,16 @@ class HabiticaPurchaseVerifier(context: Context, apiClient: ApiClient) : BasePur processedPurchase(purchase, allPurchases, verifiedPurchases, requestListener) } - private fun loadPendingGifts(): MutableMap { - val outputMap: MutableMap = HashMap() + private fun loadPendingGifts(): MutableMap> { + val outputMap: MutableMap> = HashMap() try { val jsonString = preferences?.getString(PENDING_GIFTS_KEY, JSONObject().toString()) ?: "" val jsonObject = JSONObject(jsonString) val keysItr = jsonObject.keys() while (keysItr.hasNext()) { val key = keysItr.next() - val value = jsonObject[key] as String - outputMap[key] = value + val value = jsonObject.getJSONArray(key) + outputMap[key] = Pair(value[0] as Date, value[1] as String) } } catch (e: Exception) { RxErrorHandler.reportError(e) @@ -151,19 +157,19 @@ class HabiticaPurchaseVerifier(context: Context, apiClient: ApiClient) : BasePur companion object { private const val PURCHASED_PRODUCTS_KEY = "PURCHASED_PRODUCTS" - private const val PENDING_GIFTS_KEY = "PENDING_GIFTS" - private var pendingGifts: MutableMap = HashMap() + private const val PENDING_GIFTS_KEY = "PENDING_GIFTS_DATED" + private var pendingGifts: MutableMap> = HashMap() private var preferences: SharedPreferences? = null - fun addGift(sku: String?, userID: String?) { - pendingGifts[sku] = userID + fun addGift(sku: String, userID: String) { + pendingGifts[sku] = Pair(Date(), userID) savePendingGifts() } - private fun removeGift(sku: String): String? { - val giftedID = pendingGifts.remove(sku) + private fun removeGift(sku: String): Pair? { + val gift = pendingGifts.remove(sku) savePendingGifts() - return giftedID + return gift } private fun savePendingGifts() { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/KeyHelper.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/KeyHelper.kt index 11baf7aab..05740288b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/KeyHelper.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/KeyHelper.kt @@ -25,12 +25,12 @@ import javax.security.cert.CertificateException // https://stackoverflow.com/a/42716982 class KeyHelper @Throws(NoSuchPaddingException::class, NoSuchProviderException::class, NoSuchAlgorithmException::class, InvalidAlgorithmParameterException::class, KeyStoreException::class, CertificateException::class, IOException::class) -constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore: KeyStore) { +constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore: KeyStore?) { private val aesKeyFromKS: Key? @Throws(NoSuchProviderException::class, NoSuchAlgorithmException::class, InvalidAlgorithmParameterException::class, KeyStoreException::class, CertificateException::class, IOException::class, UnrecoverableKeyException::class) get() { - return keyStore.getKey(KEY_ALIAS, null) as? SecretKey + return keyStore?.getKey(KEY_ALIAS, null) as? SecretKey } init { @@ -48,10 +48,10 @@ constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore @Throws(NoSuchProviderException::class, NoSuchAlgorithmException::class, InvalidAlgorithmParameterException::class, KeyStoreException::class, CertificateException::class, IOException::class) private fun generateEncryptKey(ctx: Context) { - keyStore.load(null) + keyStore?.load(null) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (!keyStore.containsAlias(KEY_ALIAS)) { + if (keyStore?.containsAlias(KEY_ALIAS) == false) { val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, AndroidKeyStore) keyGenerator.init( KeyGenParameterSpec.Builder( @@ -66,7 +66,7 @@ constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore keyGenerator.generateKey() } } else { - if (!keyStore.containsAlias(KEY_ALIAS)) { + if (keyStore?.containsAlias(KEY_ALIAS) == false) { // Generate a key pair for encryption val start = Calendar.getInstance() val end = Calendar.getInstance() @@ -87,7 +87,7 @@ constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore @Throws(Exception::class) private fun rsaEncrypt(secret: ByteArray): ByteArray { - val privateKeyEntry = keyStore.getEntry(KEY_ALIAS, null) as? KeyStore.PrivateKeyEntry + val privateKeyEntry = keyStore?.getEntry(KEY_ALIAS, null) as? KeyStore.PrivateKeyEntry // Encrypt the text val inputCipher = Cipher.getInstance(RSA_MODE, "AndroidOpenSSL") inputCipher.init(Cipher.ENCRYPT_MODE, privateKeyEntry?.certificate?.publicKey) @@ -102,7 +102,7 @@ constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore @Throws(Exception::class) private fun rsaDecrypt(encrypted: ByteArray): ByteArray { - val privateKeyEntry = keyStore.getEntry(KEY_ALIAS, null) as? KeyStore.PrivateKeyEntry + val privateKeyEntry = keyStore?.getEntry(KEY_ALIAS, null) as? KeyStore.PrivateKeyEntry val output = Cipher.getInstance(RSA_MODE, "AndroidOpenSSL") output.init(Cipher.DECRYPT_MODE, privateKeyEntry?.privateKey) val cipherInputStream = CipherInputStream( diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt index 65fb1736b..5959c6f57 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt @@ -84,7 +84,7 @@ open class PurchaseHandler(activity: Activity, val analyticsManager: AnalyticsMa cont.resume(it) } } catch (e: NullPointerException) { - cont.resumeWithException(e) + cont.resume(null) } if (inventory == null) cont.resume(null) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/SoundFile.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/SoundFile.kt index 8d4fdbd7b..ba4073e66 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/SoundFile.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/SoundFile.kt @@ -5,10 +5,10 @@ import android.media.AudioManager import android.media.MediaPlayer import java.io.File -class SoundFile(val theme: String, private val fileName: String) : MediaPlayer.OnCompletionListener { +class SoundFile(val theme: String, private val fileName: String) { + private var player: MediaPlayer? = null var file: File? = null private var playerPrepared: Boolean = false - private var isPlaying: Boolean = false val webUrl: String get() = "https://s3.amazonaws.com/habitica-assets/mobileApp/sounds/$theme/$fileName.mp3" @@ -17,37 +17,37 @@ class SoundFile(val theme: String, private val fileName: String) : MediaPlayer.O get() = theme + "_" + fileName + ".mp3" fun play() { - if (isPlaying || file?.path == null) { + if (player?.isPlaying == true || file?.path == null) { return } - val m = MediaPlayer() + if (player?.isPlaying == false) { + player?.release() + player = null + } - m.setOnCompletionListener { mp -> - isPlaying = false + player = MediaPlayer() + + player?.setOnCompletionListener { mp -> mp.release() + player = null } try { - m.setDataSource(file?.path) + player?.setDataSource(file?.path) val attributes = AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setLegacyStreamType(AudioManager.STREAM_NOTIFICATION) .build() - m.setAudioAttributes(attributes) - m.prepare() + player?.setAudioAttributes(attributes) + player?.prepare() playerPrepared = true - m.setVolume(100f, 100f) - m.isLooping = false - isPlaying = true - m.start() + player?.setVolume(100f, 100f) + player?.isLooping = false + player?.start() } catch (e: Exception) { RxErrorHandler.reportError(e) } } - - override fun onCompletion(mediaPlayer: MediaPlayer) { - isPlaying = false - } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/NotifyUserUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/NotifyUserUseCase.kt index 7145fe98b..99091706b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/NotifyUserUseCase.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/NotifyUserUseCase.kt @@ -70,7 +70,9 @@ constructor( container.addView(createTextView(context, xp, HabiticaIconsHelper.imageOfExperience())) } if (hp != null && hp != 0.0) { - displayType = SnackbarDisplayType.FAILURE + if (hp < 0) { + displayType = SnackbarDisplayType.FAILURE + } container.addView(createTextView(context, hp, HabiticaIconsHelper.imageOfHeartDarkBg())) } if (gold != null && gold != 0.0) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/IAPGift.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/IAPGift.kt index c912c79c1..cebe2a96f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/IAPGift.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/IAPGift.kt @@ -1,5 +1,3 @@ package com.habitrpg.android.habitica.models -class IAPGift { - var uuid: String? = null -} +class IAPGift(var uuid: String? = null) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftGemsActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftGemsActivity.kt index 49047ec92..cff57e69e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftGemsActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftGemsActivity.kt @@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.extensions.addOkButton import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.PurchaseHandler import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.members.Member import com.habitrpg.android.habitica.proxy.AnalyticsManager import com.habitrpg.android.habitica.ui.fragments.purchases.GiftBalanceGemsFragment import com.habitrpg.android.habitica.ui.fragments.purchases.GiftPurchaseGemsFragment @@ -48,6 +49,7 @@ class GiftGemsActivity : BaseActivity() { private var giftedUsername: String? = null private var giftedUserID: String? = null + private var giftedMember: Member? = null private var purchaseFragment: GiftPurchaseGemsFragment? = null private var balanceFragment: GiftBalanceGemsFragment? = null @@ -89,6 +91,7 @@ class GiftGemsActivity : BaseActivity() { compositeSubscription.add( socialRepository.getMember(giftedUsername ?: giftedUserID).firstElement().subscribe( { + giftedMember = it giftedUserID = it.id giftedUsername = it.username purchaseFragment?.giftedMember = it @@ -139,6 +142,7 @@ class GiftGemsActivity : BaseActivity() { fragment.setPurchaseHandler(purchaseHandler) fragment.setupCheckout() purchaseFragment = fragment + purchaseFragment?.giftedMember = giftedMember fragment } else { val fragment = GiftBalanceGemsFragment() @@ -146,6 +150,7 @@ class GiftGemsActivity : BaseActivity() { displayConfirmationDialog() } balanceFragment = fragment + balanceFragment?.giftedMember = giftedMember fragment } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt index 2a518ddda..ac5cf699f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt @@ -185,11 +185,13 @@ class GiftSubscriptionActivity : BaseActivity() { } private fun purchaseSubscription(sku: Sku) { - if (giftedUserID?.isNotEmpty() != true) { - return + giftedUserID?.let { id -> + if (id.isEmpty()) { + return + } + HabiticaPurchaseVerifier.addGift(sku.id.code, id) + purchaseHandler?.purchaseNoRenewSubscription(sku) } - HabiticaPurchaseVerifier.addGift(sku.id.code, giftedUserID) - purchaseHandler?.purchaseNoRenewSubscription(sku) } @Subscribe diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt index 6d48c28cb..be167f316 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt @@ -35,7 +35,10 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl field = value for (item in items) { if (item.isHeader) { - notifyItemChanged(getVisibleItemPosition(item.identifier)) + val visiblePosition = getVisibleItemPosition(item.identifier) + if (visiblePosition >= 0) { + notifyItemChanged(visiblePosition) + } } } } @@ -70,7 +73,10 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl notifyItemInserted(items.size - 1) } else { items[position] = item - notifyItemChanged(getVisibleItemPosition(item.identifier)) + val visiblePosition = getVisibleItemPosition(item.identifier) + if (visiblePosition in 0 until itemCount) { + notifyItemChanged(visiblePosition) + } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt index 1b0594e9f..df4293962 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt @@ -70,7 +70,7 @@ class ItemsFragment : BaseMainFragment() { } fragment.user = this@ItemsFragment.user fragment.itemTypeText = - if (position == 4) getString(R.string.special_items) + if (position == 4 && isAdded) getString(R.string.special_items) else getPageTitle(position) return fragment diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt index 56abe878c..cff54dc66 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt @@ -34,7 +34,7 @@ class TimePreferenceDialogFragment : PreferenceDialogFragmentCompat() { } override fun onCreateDialogView(context: Context?): View { - picker = TimePicker(getContext()) + picker = TimePicker(context) return picker } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftPurchaseGemsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftPurchaseGemsFragment.kt index d77903a25..23fb5e860 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftPurchaseGemsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftPurchaseGemsFragment.kt @@ -91,7 +91,9 @@ class GiftPurchaseGemsFragment : BaseFragment() } private fun purchaseGems(identifier: String) { - HabiticaPurchaseVerifier.addGift(identifier, giftedMember?.id) - purchaseHandler?.purchaseGems(identifier) + giftedMember?.id?.let { + HabiticaPurchaseVerifier.addGift(identifier, it) + purchaseHandler?.purchaseGems(identifier) + } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt index a8d96e67d..1a657818d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt @@ -21,6 +21,7 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import io.reactivex.rxjava3.core.Completable +import io.reactivex.rxjava3.schedulers.Schedulers import javax.inject.Inject import javax.inject.Named @@ -57,7 +58,9 @@ class BugFixFragment : BaseMainFragment() { compositeSubscription.add( Completable.fromAction { deviceInfo = context?.let { DeviceName.getDeviceInfo(it) } - }.subscribe() + } + .subscribeOn(Schedulers.io()) + .subscribe() ) binding?.reportBugButton?.setOnClickListener { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt index bd0840106..4ab31a12d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt @@ -16,6 +16,7 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import io.reactivex.rxjava3.core.Completable +import io.reactivex.rxjava3.schedulers.Schedulers import javax.inject.Inject import javax.inject.Named @@ -63,7 +64,9 @@ class SupportMainFragment : BaseMainFragment() { compositeSubscription.add( Completable.fromAction { deviceInfo = context?.let { DeviceName.getDeviceInfo(it) } - }.subscribe() + } + .subscribeOn(Schedulers.io()) + .subscribe() ) binding?.resetTutorialButton?.setOnClickListener {