From b9e789dd7d2100f9b68b84b9dc04be617e73e354 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Wed, 29 Aug 2018 14:31:54 +0200 Subject: [PATCH] Implement AB Testing for subscription screen position --- .../android/habitica/models/user/ABTest.kt | 13 +++++++ .../android/habitica/models/user/User.kt | 5 +++ .../ui/activities/GemPurchaseActivity.kt | 34 +++++++++++++++---- .../habitica/utils/UserDeserializer.kt | 10 ++++++ 4 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/user/ABTest.kt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/ABTest.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/ABTest.kt new file mode 100644 index 000000000..6334dd938 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/ABTest.kt @@ -0,0 +1,13 @@ +package com.habitrpg.android.habitica.models.user + +import io.realm.RealmObject +import io.realm.annotations.PrimaryKey + +open class ABTest: RealmObject() { + + @PrimaryKey + var userID: String? = null + + var name: String = "" + var group: String = "" +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt index 87009a269..8ddcc1c03 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt @@ -52,6 +52,9 @@ open class User : RealmObject(), Avatar { if (this.invitations?.isManaged != true) { this.invitations?.userId = id } + for (test in abTests ?: emptyList()) { + test.userID = id + } } var balance: Double = 0.toDouble() private var stats: Stats? = null @@ -132,6 +135,8 @@ open class User : RealmObject(), Avatar { var challenges: RealmList? = null + var abTests: RealmList? = null + var lastCron: Date? = null var needsCron: Boolean = false var loginIncentives: Int = 0 diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.kt index a8bcbba23..4d9e60438 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.kt @@ -9,18 +9,21 @@ import android.support.v4.app.FragmentPagerAdapter import android.support.v4.view.ViewPager import android.support.v7.widget.Toolbar import android.view.MenuItem -import com.habitrpg.android.habitica.HabiticaApplication import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.AppComponent +import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.extensions.notNull import com.habitrpg.android.habitica.helpers.PurchaseTypes +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.user.ABTest import com.habitrpg.android.habitica.proxy.CrashlyticsProxy import com.habitrpg.android.habitica.ui.fragments.GemsPurchaseFragment import com.habitrpg.android.habitica.ui.fragments.SubscriptionFragment import com.habitrpg.android.habitica.ui.helpers.bindView import com.playseeds.android.sdk.Seeds import com.playseeds.android.sdk.inappmessaging.InAppMessageListener +import io.reactivex.functions.Consumer import org.solovyev.android.checkout.* import java.util.* import javax.inject.Inject @@ -29,6 +32,8 @@ class GemPurchaseActivity : BaseActivity(), InAppMessageListener { @Inject lateinit var crashlyticsProxy: CrashlyticsProxy + @Inject + lateinit var userRepository: UserRepository internal val tabLayout: TabLayout by bindView(R.id.tab_layout) internal val viewPager: ViewPager by bindView(R.id.viewPager) @@ -51,6 +56,8 @@ class GemPurchaseActivity : BaseActivity(), InAppMessageListener { activityCheckout?.onActivityResult(requestCode, resultCode, data) } + private var showSubscriptionPageFirst = false + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -111,6 +118,20 @@ class GemPurchaseActivity : BaseActivity(), InAppMessageListener { override fun onReady(billingRequests: BillingRequests, s: String, b: Boolean) {} }) + + compositeSubscription.add(userRepository.getUser().subscribe(Consumer { user -> + for (test in user.abTests ?: emptyList()) { + if (test.name == "subscriptionPageOrder") { + if (test.group == "subscriptionFirst") { + showSubscriptionPageFirst = true + viewPager.adapter?.notifyDataSetChanged() + return@Consumer + } + } + } + showSubscriptionPageFirst = false + viewPager.adapter?.notifyDataSetChanged() + }, RxErrorHandler.handleEmptyError())) } public override fun onDestroy() { @@ -184,7 +205,8 @@ class GemPurchaseActivity : BaseActivity(), InAppMessageListener { viewPager.adapter = object : FragmentPagerAdapter(fragmentManager) { override fun getItem(position: Int): Fragment { - val fragment: CheckoutFragment = if (position == 0) { + val gemPurchasePosition = if (showSubscriptionPageFirst) 1 else 0 + val fragment: CheckoutFragment = if (position == gemPurchasePosition) { GemsPurchaseFragment() } else { SubscriptionFragment() @@ -207,11 +229,11 @@ class GemPurchaseActivity : BaseActivity(), InAppMessageListener { } override fun getPageTitle(position: Int): CharSequence? { - when (position) { - 0 -> return getString(R.string.gems) - 1 -> return getString(R.string.subscriptions) + val gemPurchasePosition = if (showSubscriptionPageFirst) 1 else 0 + return when (position) { + gemPurchasePosition -> getString(R.string.gems) + else -> getString(R.string.subscriptions) } - return "" } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt index 7e032de81..97f4bd30e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt @@ -123,6 +123,16 @@ class UserDeserializer : JsonDeserializer { } } + if (obj.has("_ABTests")) { + user.abTests = RealmList() + for (testJSON in obj.getAsJsonObject("_ABTests").entrySet()) { + val test = ABTest() + test.name = testJSON.key + test.group = testJSON.value.asString + user.abTests?.add(test) + } + } + return user } } \ No newline at end of file