Skip to content

Commit

Permalink
Merge branch 'release/3.1.10'
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitletondor committed Feb 26, 2024
2 parents d6b57a1 + e7c7219 commit 4547fb7
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 37 deletions.
16 changes: 8 additions & 8 deletions Android/EasyBudget/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ android {
defaultConfig {
applicationId = "com.benoitletondor.easybudgetapp"
compileSdk = 34
minSdk = 21
minSdk = 23
targetSdk = 34
versionCode = 128
versionName = "3.1.9"
versionCode = 130
versionName = "3.1.10"
vectorDrawables.useSupportLibrary = true
}

Expand Down Expand Up @@ -93,7 +93,7 @@ android {
}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.9"
kotlinCompilerExtensionVersion = "1.5.10"
}

buildFeatures {
Expand Down Expand Up @@ -145,8 +145,8 @@ dependencies {
implementation("androidx.work:work-gcm:2.9.0")
implementation("com.google.android.play:core:1.10.3")

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")

implementation(platform("com.google.firebase:firebase-bom:32.7.2"))
implementation("com.google.firebase:firebase-messaging-ktx")
Expand All @@ -156,7 +156,7 @@ dependencies {
implementation("com.google.firebase:firebase-firestore-ktx")
implementation("com.firebaseui:firebase-ui-auth:8.0.2")

val composeBom = platform("androidx.compose:compose-bom:2024.02.00")
val composeBom = platform("androidx.compose:compose-bom:2024.02.01")
implementation(composeBom)
androidTestImplementation(composeBom)
debugImplementation("androidx.compose.ui:ui-tooling")
Expand All @@ -183,7 +183,7 @@ dependencies {

implementation("io.realm.kotlin:library-sync:$realmVersion")

implementation("com.kizitonwose.calendar:compose:2.5.0-beta01")
implementation("com.kizitonwose.calendar:compose:2.5.0")
implementation("net.sf.biweekly:biweekly:0.6.8")

implementation("net.lingala.zip4j:zip4j:2.11.5")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,10 @@ fun Activity.setStatusBarColor(@ColorRes colorRes: Int) {
}

fun Activity.setNavigationBarColor(@ColorRes colorRes: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
var flags = window.decorView.systemUiVisibility
flags = flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
var flags = window.decorView.systemUiVisibility
flags = flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()

window.decorView.systemUiVisibility = flags
}
window.decorView.systemUiVisibility = flags
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.first

private const val SKU_PREMIUM_LEGACY = "premium"
Expand Down Expand Up @@ -101,9 +102,15 @@ class IabImpl(
* @return true if we could verify that the user is premium, false otherwise
*/
override suspend fun isUserPremium(): Boolean {
iabStatusMutableFlow.first { it.isFinal() }
var status = iabStatusMutableFlow.first { it.isFinal() }

return when(iabStatusMutableFlow.value) {
// Try to avoid sending false negative, it seems that it can happen when launching the app
if (status === PremiumCheckStatus.NOT_PREMIUM || status === PremiumCheckStatus.ERROR) {
delay(250)
status = iabStatusMutableFlow.first { it.isFinal() }
}

return when(status) {
PremiumCheckStatus.INITIALIZING,
PremiumCheckStatus.CHECKING,
PremiumCheckStatus.ERROR,
Expand All @@ -115,9 +122,15 @@ class IabImpl(
}

override suspend fun isUserPro(): Boolean {
iabStatusMutableFlow.first { it.isFinal() }
var status = iabStatusMutableFlow.first { it.isFinal() }

return when(iabStatusMutableFlow.value) {
// Try to avoid sending false negative, it seems that it can happen when launching the app
if (status === PremiumCheckStatus.NOT_PREMIUM || status === PremiumCheckStatus.ERROR) {
delay(250)
status = iabStatusMutableFlow.first { it.isFinal() }
}

return when(status) {
PremiumCheckStatus.INITIALIZING,
PremiumCheckStatus.CHECKING,
PremiumCheckStatus.ERROR,
Expand Down Expand Up @@ -215,33 +228,70 @@ class IabImpl(

// Is it a failure?
if (subscriptionsResult.billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Logger.error("Error while querying iab inventory: " + subscriptionsResult.billingResult.responseCode)
Logger.error(
"Error while querying iab inventory: ${subscriptionsResult.billingResult.responseCode}",
Exception("Unable to query subscriptions"),
)
setIabStatusAndNotify(PremiumCheckStatus.ERROR)
return@launch
}

val premiumSubscribed = subscriptionsResult.purchasesList.any { it.products.contains(SKU_PREMIUM_SUBSCRIPTION) }
val proSubscribed = subscriptionsResult.purchasesList.any { it.products.contains(SKU_PRO_SUBSCRIPTION) }
val premiumSubscriptions = subscriptionsResult.purchasesList.filter { it.products.contains(SKU_PREMIUM_SUBSCRIPTION) }
val proSubscriptions = subscriptionsResult.purchasesList.filter { it.products.contains(SKU_PRO_SUBSCRIPTION) }

Logger.debug("iab query inventory was successful: premium subscribed: $premiumSubscribed, pro subscribed: $proSubscribed")
Logger.debug("iab query inventory was successful: premium subscribed: ${premiumSubscriptions.isNotEmpty()}, pro subscribed: ${proSubscriptions.isNotEmpty()}")

if (premiumSubscribed) {
setIabStatusAndNotify(PremiumCheckStatus.PREMIUM_SUBSCRIBED)
if (proSubscriptions.isNotEmpty()) {
proSubscriptions
.filter { !it.isAcknowledged }
.forEach { purchase ->
Logger.warning("Found a not ACKed Pro purchase, taking care of it", Exception("Non ACKed Pro purchase"))

val ackResult = billingClient.acknowledgePurchase(AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build())

if( ackResult.responseCode != BillingClient.BillingResponseCode.OK ) {
Logger.error(
"Error while sending ACK for old Pro purchase: ${ackResult.responseCode}: ${ackResult.debugMessage}",
Exception("Pro subscription late ACK error"),
)
}
}

setIabStatusAndNotify(PremiumCheckStatus.PRO_SUBSCRIBED)
return@launch
}

if (proSubscribed) {
setIabStatusAndNotify(PremiumCheckStatus.PRO_SUBSCRIBED)
if (premiumSubscriptions.isNotEmpty()) {
premiumSubscriptions
.filter { !it.isAcknowledged }
.forEach { purchase ->
Logger.warning("Found a not ACKed premium purchase, taking care of it", Exception("Non ACKed Premium purchase"))

val ackResult = billingClient.acknowledgePurchase(AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build())

if( ackResult.responseCode != BillingClient.BillingResponseCode.OK ) {
Logger.error(
"Error while sending ACK for old Premium purchase: ${ackResult.responseCode}: ${ackResult.debugMessage}",
Exception("Premium subscription late ACK error"),
)
}
}

setIabStatusAndNotify(PremiumCheckStatus.PREMIUM_SUBSCRIBED)
return@launch
}


val legacyPremiumResult = billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build(),
)

// Is it a failure?
if (legacyPremiumResult.billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Logger.error("Error while querying iab inventory: " + legacyPremiumResult.billingResult.responseCode)
Logger.error(
"Error while querying iab inventory: ${legacyPremiumResult.billingResult.responseCode}: ${legacyPremiumResult.billingResult.debugMessage}",
Exception("Unable to query legacy purchase")
)
setIabStatusAndNotify(PremiumCheckStatus.ERROR)
return@launch
}
Expand Down Expand Up @@ -377,13 +427,19 @@ class IabImpl(
)

if (subscriptionsResult.billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Logger.error("Error while querying iab inventory: " + subscriptionsResult.billingResult.responseCode)
Logger.error(
"Error while querying iab inventory: ${subscriptionsResult.billingResult.responseCode}: ${subscriptionsResult.billingResult.debugMessage}",
Exception("Unable to query current subscriptions for upgrade"),
)
return PurchaseFlowResult.Error("Unable to fetch content from PlayStore (premium subscription fetch response code: ${subscriptionsResult.billingResult.responseCode}). Please restart the app and try again")
}

val premiumSubscription = subscriptionsResult.purchasesList.firstOrNull { it.products.contains(SKU_PREMIUM_SUBSCRIPTION) }
if (premiumSubscription == null) {
Logger.error("Unable to find premium subscription")
Logger.error(
"Unable to find premium subscription",
Exception("Unable to find premium subscription to upgrade")
)
return PurchaseFlowResult.Error("Unable to find your premium subscription. Please restart the app and try again")
}

Expand Down Expand Up @@ -420,7 +476,10 @@ class IabImpl(

if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
setIabStatusAndNotify(PremiumCheckStatus.ERROR)
Logger.error("Error while setting-up iab: " + billingResult.responseCode)
Logger.error(
"Error while setting-up iab: ${billingResult.responseCode}: ${billingResult.debugMessage}",
Exception("Unable to setup IAB"),
)
return
}

Expand All @@ -444,10 +503,18 @@ class IabImpl(

scope.launch {
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Logger.error("Error while purchasing premium: " + billingResult.responseCode)
when (billingResult.responseCode) {
BillingClient.BillingResponseCode.USER_CANCELED -> pendingPurchaseEventMutableFlow.emit(PurchaseFlowResult.Cancelled)
else -> pendingPurchaseEventMutableFlow.emit(PurchaseFlowResult.Error("An error occurred (status code: " + billingResult.responseCode + ")"))
BillingClient.BillingResponseCode.USER_CANCELED -> {
Logger.debug("Purchase cancelled")
pendingPurchaseEventMutableFlow.emit(PurchaseFlowResult.Cancelled)
}
else -> {
Logger.error(
"Error while purchasing: ${billingResult.responseCode}: ${billingResult.debugMessage}",
Exception("Error while purchasing")
)
pendingPurchaseEventMutableFlow.emit(PurchaseFlowResult.Error("An error occurred (status code: " + billingResult.responseCode + ")"))
}
}

return@launch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,10 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
setStatusBarColor(fragment.statusBarColor)
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
var flags = window.decorView.systemUiVisibility
flags = flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
var flags = window.decorView.systemUiVisibility
flags = flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()

window.decorView.systemUiVisibility = flags
}
window.decorView.systemUiVisibility = flags
}

override fun onDestroy() {
Expand Down

0 comments on commit 4547fb7

Please sign in to comment.