Skip to content

Commit

Permalink
Placements (#73)
Browse files Browse the repository at this point in the history
* add placements
* globar refactors
  • Loading branch information
ren6 authored Dec 15, 2023
1 parent 261076f commit 60e303c
Show file tree
Hide file tree
Showing 62 changed files with 1,668 additions and 1,236 deletions.
15 changes: 14 additions & 1 deletion demo/src/main/java/com/apphud/demo/ApphudApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ package com.apphud.demo

import android.app.Application
import android.content.Context
import android.util.Log
import androidx.lifecycle.lifecycleScope
import com.apphud.sdk.Apphud
import com.apphud.sdk.ApphudUtils
import com.apphud.sdk.client.ApiClient
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

class ApphudApplication : Application() {
val API_KEY = "app_4sY9cLggXpMDDQMmvc5wXUPGReMp8G"
var API_KEY = "app_4sY9cLggXpMDDQMmvc5wXUPGReMp8G"

companion object {
private lateinit var instance: ApphudApplication
Expand All @@ -28,6 +34,13 @@ class ApphudApplication : Application() {

Apphud.enableDebugLogs()
// Apphud.optOutOfTracking()

if (BuildConfig.DEBUG) {
ApphudUtils.enableAllLogs()
}

// check again restore cache from previous sdk version

Apphud.start(this, API_KEY)
Apphud.collectDeviceIdentifiers()
}
Expand Down
23 changes: 11 additions & 12 deletions demo/src/main/java/com/apphud/demo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,18 @@ class MainActivity : AppCompatActivity() {
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
} else {
if (!findNavController(R.id.nav_host_fragment_content_main).navigateUp())
{
if (backPress + 2000 > System.currentTimeMillis()) {
super.onBackPressed()
} else {
Toast.makeText(
baseContext,
"Please press again to exit!",
Toast.LENGTH_SHORT,
).show()
backPress = System.currentTimeMillis()
}
if (!findNavController(R.id.nav_host_fragment_content_main).navigateUp()) {
if (backPress + 2000 > System.currentTimeMillis()) {
super.onBackPressed()
} else {
Toast.makeText(
baseContext,
"Please press again to exit!",
Toast.LENGTH_SHORT,
).show()
backPress = System.currentTimeMillis()
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class BillingClientWrapper(
context: Context,
) : PurchasesUpdatedListener, ProductDetailsResponseListener {
companion object {
private const val TAG = "BillingClient"
private const val TAG = "ApphudLogs"

// List of subscription product offerings
private const val PEACH = "com.apphud.demo.consumable.peach"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class BillingFragment : Fragment() {
viewAdapter.selectProduct = { product ->
activity?.let { activity ->
val offers = product.subscriptionOfferDetails?.map { it.pricingPhases.pricingPhaseList[0].formattedPrice }
offers?.let { offers ->
offers?.let { _ ->

product.subscriptionOfferDetails?.let {
val fragment = OffersFragment()
Expand Down
31 changes: 14 additions & 17 deletions demo/src/main/java/com/apphud/demo/ui/billing/BillingViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.apphud.sdk.Apphud

class BillingViewModel : ViewModel() {
companion object {
private const val TAG: String = "BillingViewModel"
private const val TAG: String = "ApphudLogs"
private const val MAX_CURRENT_PURCHASES_ALLOWED = 1
}

Expand All @@ -29,7 +29,7 @@ class BillingViewModel : ViewModel() {

var items = mutableListOf<Any>()

fun updateData() {
fun updateData() {
items.clear()
for (item in billingClient.productWithProductDetails) {
items.add(item.value)
Expand Down Expand Up @@ -171,23 +171,20 @@ class BillingViewModel : ViewModel() {
val oldPurchaseToken: String

billingClient.purchaseSuccessListener = { purchase, billingResult ->
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK)
{
purchase?.let { p ->
if (p.purchaseState == Purchase.PurchaseState.PURCHASED) {
Log.d(TAG, "Purchase SUCCESS notify Apphud")
Apphud.trackPurchase(p, productDetails, offerIdToken)
} else
{
Log.e(TAG, "Purchase SUCCESS but purchase state is " + p.purchaseState)
}
} ?: run {
Log.e(TAG, "Purchase SUCCESS but purchase is null")
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
purchase?.let { p ->
if (p.purchaseState == Purchase.PurchaseState.PURCHASED) {
Log.d(TAG, "Purchase SUCCESS notify Apphud")
Apphud.trackPurchase(p, productDetails, offerIdToken)
} else {
Log.e(TAG, "Purchase SUCCESS but purchase state is " + p.purchaseState)
}
} else
{
Log.e(TAG, "Purchase ERROR: code=" + billingResult.responseCode)
} ?: run {
Log.e(TAG, "Purchase SUCCESS but purchase is null")
}
} else {
Log.e(TAG, "Purchase ERROR: code=" + billingResult.responseCode)
}
}

// Get current purchase. In this app, a user can only have one current purchase at
Expand Down
47 changes: 34 additions & 13 deletions demo/src/main/java/com/apphud/demo/ui/customer/CustomerFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
Expand All @@ -18,8 +19,13 @@ import com.apphud.sdk.Apphud
import com.apphud.sdk.ApphudListener
import com.apphud.sdk.domain.ApphudNonRenewingPurchase
import com.apphud.sdk.domain.ApphudPaywall
import com.apphud.sdk.domain.ApphudPlacement
import com.apphud.sdk.domain.ApphudSubscription
import com.apphud.sdk.domain.ApphudUser
import com.apphud.sdk.managers.HeadersInterceptor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class CustomerFragment : Fragment() {
private var _binding: FragmentCustomerBinding? = null
Expand Down Expand Up @@ -48,8 +54,8 @@ class CustomerFragment : Fragment() {

paywallsViewModel = ViewModelProvider(this)[PaywallsViewModel::class.java]
viewAdapter = PaywallsAdapter(paywallsViewModel, context)
viewAdapter.selectPaywall = { paywall ->
findNavController().navigate(CustomerFragmentDirections.actionNavCustomerToProductsFragment(paywall.identifier))
viewAdapter.selectItem = { item ->
findNavController().navigate(CustomerFragmentDirections.actionNavCustomerToProductsFragment(item.paywall?.identifier, item.placement?.identifier))
}

val recyclerView: RecyclerView = binding.paywallsList
Expand All @@ -58,6 +64,11 @@ class CustomerFragment : Fragment() {
addItemDecoration(DividerItemDecoration(this.context, DividerItemDecoration.VERTICAL))
}

binding.toggleButton.setOnCheckedChangeListener { buttonView, isChecked ->
paywallsViewModel.showPlacements = isChecked
updateData()
}

binding.swipeRefresh.setOnRefreshListener {
updateData()
binding.swipeRefresh.isRefreshing = false
Expand All @@ -66,30 +77,36 @@ class CustomerFragment : Fragment() {
val listener =
object : ApphudListener {
override fun apphudSubscriptionsUpdated(subscriptions: List<ApphudSubscription>) {
Log.d("Apphud", "apphudSubscriptionsUpdated")
Log.d("ApphudDemo", "apphudSubscriptionsUpdated")
}

override fun apphudNonRenewingPurchasesUpdated(purchases: List<ApphudNonRenewingPurchase>) {
Log.d("Apphud", "apphudNonRenewingPurchasesUpdated")
Log.d("ApphudDemo", "apphudNonRenewingPurchasesUpdated")
}

override fun apphudFetchProductDetails(details: List<ProductDetails>) {
Log.d("Apphud", "apphudFetchProductDetails()")
Log.d("ApphudDemo", "apphudFetchProductDetails()")
// TODO handle loaded sku details
}

override fun apphudDidChangeUserID(userId: String) {
Log.d("Apphud", "apphudDidChangeUserID()")
Log.d("ApphudDemo", "apphudDidChangeUserID()")
// TODO handle User ID changed event
}

override fun userDidLoad() {
Log.d("Apphud", "userDidLoad()")
override fun userDidLoad(user: ApphudUser) {
Log.d("ApphudDemo", "userDidLoad()")
// TODO handle user registered event
updateData()
}

override fun paywallsDidFullyLoad(paywalls: List<ApphudPaywall>) {
Log.d("Apphud", "paywallsDidFullyLoad()")
override fun paywallsDidFullyLoad(paywalls: List<ApphudPaywall>) {
Log.d("ApphudDemo", "paywallsDidFullyLoad()")
updateData()
}

override fun placementsDidFullyLoad(placements: List<ApphudPlacement>) {
Log.d("ApphudDemo", "placementsDidFullyLoad()")
updateData()
}
}
Expand All @@ -100,9 +117,13 @@ class CustomerFragment : Fragment() {
return root
}

private fun updateData() {
paywallsViewModel.updateData()
viewAdapter.notifyDataSetChanged()
private fun updateData() {
lifecycleScope.launch {
paywallsViewModel.updateData()
withContext(Dispatchers.Main) {
viewAdapter.notifyDataSetChanged()
}
}
}

override fun onDestroyView() {
Expand Down
36 changes: 24 additions & 12 deletions demo/src/main/java/com/apphud/demo/ui/customer/PaywallsAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.apphud.demo.R
import com.apphud.sdk.domain.ApphudPaywall

class PaywallsAdapter(private val paywallsViewModel: PaywallsViewModel, private val context: Context?) : RecyclerView.Adapter<PaywallsAdapter.BaseViewHolder<*>>() {
var selectPaywall: ((account: ApphudPaywall) -> Unit)? = null
var selectItem: ((item: AdapterItem) -> Unit)? = null

abstract class BaseViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
abstract fun bind(
Expand All @@ -21,24 +20,35 @@ class PaywallsAdapter(private val paywallsViewModel: PaywallsViewModel, private
)
}

inner class PaywallViewHolder(itemView: View) : BaseViewHolder<ApphudPaywall>(itemView) {
inner class PaywallViewHolder(itemView: View) : BaseViewHolder<AdapterItem>(itemView) {
private val paywallName: TextView = itemView.findViewById(R.id.paywallName)
private val paywallIdentifier: TextView = itemView.findViewById(R.id.paywallIdentifier)
private val paywallDefault: TextView = itemView.findViewById(R.id.paywallDefault)
private val paywallExperiment: TextView = itemView.findViewById(R.id.paywallExperiment)
private val paywallVariation: TextView = itemView.findViewById(R.id.paywallVariation)
private val paywallJson: TextView = itemView.findViewById(R.id.paywallJson)
private val layoutHolder: LinearLayout = itemView.findViewById(R.id.layoutHolder)

override fun bind(
item: ApphudPaywall,
item: AdapterItem,
position: Int,
) {
paywallName.text = item.name
paywallDefault.text = item.default.toString()
paywallExperiment.text = item.experimentName ?: "-"
val paywall = item.paywall ?: item.placement?.paywall

val experimentName = item.placement?.experimentName ?: paywall?.experimentName

paywallName.text =
if (item.placement != null) {
"${item.placement.identifier} -> ${paywall?.name}"
} else {
paywall?.name
}
paywallIdentifier.text = "Paywall ID: " + (paywall?.identifier ?: "N/A")
paywallDefault.text = paywall?.default.toString()
paywallExperiment.text = item.placement?.experimentName ?: paywall?.experimentName ?: "N/A"
paywallVariation.text = "N/A"
paywallJson.text = if (item.json != null) "true" else "false"
item.experimentName?.let {
paywallJson.text = if (paywall?.json != null) "true" else "false"
experimentName?.let {
layoutHolder.setBackgroundResource(R.color.teal_200)
paywallDefault.setTextColor(Color.WHITE)
paywallExperiment.setTextColor(Color.WHITE)
Expand All @@ -51,7 +61,9 @@ class PaywallsAdapter(private val paywallsViewModel: PaywallsViewModel, private
}

itemView.setOnClickListener {
selectPaywall?.invoke(item)
paywall?.let { paywall ->
selectItem?.invoke(item)
}
}
}
}
Expand Down Expand Up @@ -81,14 +93,14 @@ class PaywallsAdapter(private val paywallsViewModel: PaywallsViewModel, private
) {
val element = paywallsViewModel.items[position]
when (holder) {
is PaywallViewHolder -> holder.bind(element as ApphudPaywall, position)
is PaywallViewHolder -> holder.bind(element as AdapterItem, position)
else -> throw IllegalArgumentException()
}
}

override fun getItemViewType(position: Int): Int {
return when (paywallsViewModel.items[position]) {
is ApphudPaywall -> TYPE_PAYWALL
is AdapterItem -> TYPE_PAYWALL
else -> throw IllegalArgumentException("Invalid type of data " + position)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,31 @@ package com.apphud.demo.ui.customer

import androidx.lifecycle.ViewModel
import com.apphud.sdk.Apphud
import com.apphud.sdk.domain.ApphudPaywall
import com.apphud.sdk.domain.ApphudPlacement

class AdapterItem(
val paywall: ApphudPaywall?,
val placement: ApphudPlacement?,
)

class PaywallsViewModel : ViewModel() {
var items = mutableListOf<Any>()
var showPlacements: Boolean = false

fun updateData() {
val list = Apphud.paywalls()
items.clear()
list.forEach {
items.add(it)
suspend fun updateData() {
if (showPlacements) {
items.clear()
val placements = Apphud.placements()
placements.forEach {
items.add(AdapterItem(null, it))
}
} else {
val list = Apphud.paywalls()
items.clear()
list.forEach {
items.add(AdapterItem(it, null))
}
}
}
}
14 changes: 6 additions & 8 deletions demo/src/main/java/com/apphud/demo/ui/groups/GroupsAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,14 @@ class GroupsAdapter(private val groupsViewModel: GroupsViewModel, private val co
position: Int,
) {
productName.text = item.name
productId.text = item.product_id
productId.text = item.productId

item.productDetails?.let { details ->
if (details.productType == BillingClient.ProductType.SUBS)
{
productPrice.text = details.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList?.firstOrNull()?.formattedPrice ?: ""
} else
{
productPrice.text = details.oneTimePurchaseOfferDetails?.formattedPrice ?: ""
}
if (details.productType == BillingClient.ProductType.SUBS) {
productPrice.text = details.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList?.firstOrNull()?.formattedPrice ?: ""
} else {
productPrice.text = details.oneTimePurchaseOfferDetails?.formattedPrice ?: ""
}
} ?: run {
productPrice.text = ""
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class GroupsFragment : Fragment() {
return root
}

private fun updateData() {
private fun updateData() {
groupsViewModel.updateData()
}

Expand Down
Loading

0 comments on commit 60e303c

Please sign in to comment.