From 21d129779c3ac4a26de73daf9caafb2d37dd51cf Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Tue, 10 Sep 2024 11:56:39 +0200 Subject: [PATCH 01/31] fix bug in PurchasesRepository --- .../purchase/repository/PurchasesRepository.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ui-toolkit/src/main/kotlin/io/snabble/sdk/widgets/snabble/purchase/repository/PurchasesRepository.kt b/ui-toolkit/src/main/kotlin/io/snabble/sdk/widgets/snabble/purchase/repository/PurchasesRepository.kt index 80f2a228f7..a0418e2717 100644 --- a/ui-toolkit/src/main/kotlin/io/snabble/sdk/widgets/snabble/purchase/repository/PurchasesRepository.kt +++ b/ui-toolkit/src/main/kotlin/io/snabble/sdk/widgets/snabble/purchase/repository/PurchasesRepository.kt @@ -41,8 +41,12 @@ internal class PurchasesRepositoryImpl( } } - private fun Array.mapToPurchases(count: Int): List = - this.filter { it.pdfUrl != null } - .slice(0 until size.coerceAtMost(count)) - .map { it.toPurchase(timeFormatter) } + private fun Array.mapToPurchases(count: Int): List { + val receipts = filter { it.pdfUrl != null } + return when { + receipts.isEmpty() -> emptyList() + else -> receipts.slice(0 until size.coerceAtMost(count)) + .map { it.toPurchase(timeFormatter) } + } + } } From e0588c37701c694be8cddc9824e93c8bc726646d Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Tue, 10 Sep 2024 11:59:59 +0200 Subject: [PATCH 02/31] replace old primary button with new on to keep colors for states like disables, hovered, etc. --- .../ui/remotetheme/SnabblePrimaryButton.kt | 99 ++++++++++++++++--- .../res/layout/snabble_primary_button.xml | 11 +++ 2 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 ui/src/main/res/layout/snabble_primary_button.xml diff --git a/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt index 22db2379ff..b7ca80cd51 100644 --- a/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt +++ b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt @@ -2,27 +2,100 @@ package io.snabble.sdk.ui.remotetheme import android.content.Context import android.util.AttributeSet -import com.google.android.material.button.MaterialButton -import io.snabble.sdk.Snabble +import android.util.DisplayMetrics +import android.view.ViewGroup +import android.widget.LinearLayout +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import io.snabble.sdk.extensions.xx import io.snabble.sdk.ui.R +import io.snabble.sdk.ui.utils.ThemeWrapper +import kotlinx.coroutines.flow.MutableStateFlow -/** - * A default Materialbutton which automatically sets the remote theme colors of the - * current checked in project. - */ class SnabblePrimaryButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = R.attr.materialButtonStyle, -) : MaterialButton(context, attrs, defStyleAttr) { + defStyleAttr: Int = 0, +) : LinearLayout(context, attrs, defStyleAttr) { + + private var isButtonEnabled = MutableStateFlow(isEnabled) + private var textRes: MutableStateFlow = MutableStateFlow(getDefaultString(attrs)) + private var setHeight: MutableStateFlow = MutableStateFlow(null) init { - setProjectAppTheme() + init() + } + + private fun init() { + inflate(context, R.layout.snabble_primary_button, this).apply { + + findViewById(R.id.button_container).setContent { + ThemeWrapper { + val isEnable = isButtonEnabled.collectAsStateWithLifecycle().value + val text = textRes.collectAsStateWithLifecycle().value + val height = setHeight.collectAsStateWithLifecycle().value + + Button( + modifier = Modifier + .fillMaxWidth() + .height(height ?: ButtonDefaults.MinHeight), + onClick = { callOnClick() }, + enabled = isEnable + ) { + Text(text = text) + } + } + } + } + } + + private fun getDefaultString(attrs: AttributeSet?): String { + context.theme.obtainStyledAttributes(attrs, intArrayOf(android.R.attr.text), 0, 0) + .apply { + try { + return getString(0) ?: "" + } finally { + recycle() + } + } + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + if (layoutParams.height != ViewGroup.LayoutParams.WRAP_CONTENT) { + setHeight.value = pxToDp(context, layoutParams.height).dp.xx() + } } - private fun setProjectAppTheme() { - val project = Snabble.checkedInProject.value - setBackgroundColor(context.getPrimaryColorForProject(project)) - setTextColor(context.getOnPrimaryColorForProject(project)) + fun setText(@StringRes value: Int) { + textRes.value = context.getString(value) + } + + fun setText(value: String) { + textRes.value = value + } + + override fun setEnabled(enabled: Boolean) { + super.setEnabled(enabled) + isButtonEnabled.value = enabled.xx("set it") + } + + private fun pxToDp(context: Context, px: Int): Float { + val metrics: DisplayMetrics = context.resources.displayMetrics + return px / (metrics.densityDpi / BASELINE_DENSITY) + } + + companion object { + + private const val BASELINE_DENSITY = 160f } } diff --git a/ui/src/main/res/layout/snabble_primary_button.xml b/ui/src/main/res/layout/snabble_primary_button.xml new file mode 100644 index 0000000000..ae66046141 --- /dev/null +++ b/ui/src/main/res/layout/snabble_primary_button.xml @@ -0,0 +1,11 @@ + + + + + + From 8ace08320bb0664aa7855162a4ad0a097bd87680 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Tue, 10 Sep 2024 12:42:03 +0200 Subject: [PATCH 03/31] remove logs --- .../io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt index b7ca80cd51..069b7bdc04 100644 --- a/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt +++ b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt @@ -16,7 +16,6 @@ import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle -import io.snabble.sdk.extensions.xx import io.snabble.sdk.ui.R import io.snabble.sdk.ui.utils.ThemeWrapper import kotlinx.coroutines.flow.MutableStateFlow @@ -72,7 +71,7 @@ class SnabblePrimaryButton @JvmOverloads constructor( override fun onAttachedToWindow() { super.onAttachedToWindow() if (layoutParams.height != ViewGroup.LayoutParams.WRAP_CONTENT) { - setHeight.value = pxToDp(context, layoutParams.height).dp.xx() + setHeight.value = pxToDp(context, layoutParams.height).dp } } @@ -86,7 +85,7 @@ class SnabblePrimaryButton @JvmOverloads constructor( override fun setEnabled(enabled: Boolean) { super.setEnabled(enabled) - isButtonEnabled.value = enabled.xx("set it") + isButtonEnabled.value = enabled } private fun pxToDp(context: Context, px: Int): Float { From 545279885a423bc2782ac92fda7254da7bc9d03e Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Tue, 10 Sep 2024 12:43:26 +0200 Subject: [PATCH 04/31] remove obsolete styles --- ui/src/main/res/layout/snabble_view_checkout_bar.xml | 1 - ui/src/main/res/values/styles.xml | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ui/src/main/res/layout/snabble_view_checkout_bar.xml b/ui/src/main/res/layout/snabble_view_checkout_bar.xml index 0c77119f00..a92da7962b 100644 --- a/ui/src/main/res/layout/snabble_view_checkout_bar.xml +++ b/ui/src/main/res/layout/snabble_view_checkout_bar.xml @@ -93,7 +93,6 @@ - From 773a2aa6b00a92315a7c5d33414cc29d259b90dd Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Tue, 10 Sep 2024 12:45:05 +0200 Subject: [PATCH 05/31] change to cast to primary button --- ui/src/main/java/io/snabble/sdk/ui/cart/CheckoutBar.kt | 6 +++--- .../java/io/snabble/sdk/ui/coupon/CouponDetailFragment.kt | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ui/src/main/java/io/snabble/sdk/ui/cart/CheckoutBar.kt b/ui/src/main/java/io/snabble/sdk/ui/cart/CheckoutBar.kt index b4b74c97d9..3d0f4b82e2 100644 --- a/ui/src/main/java/io/snabble/sdk/ui/cart/CheckoutBar.kt +++ b/ui/src/main/java/io/snabble/sdk/ui/cart/CheckoutBar.kt @@ -11,7 +11,6 @@ import android.util.AttributeSet import android.view.KeyEvent import android.view.View import android.widget.ArrayAdapter -import android.widget.Button import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView @@ -23,7 +22,6 @@ import androidx.fragment.app.FragmentActivity import io.snabble.accessibility.accessibility import io.snabble.sdk.PaymentMethod import io.snabble.sdk.Project -import io.snabble.sdk.shoppingcart.ShoppingCart import io.snabble.sdk.Snabble import io.snabble.sdk.Snabble.instance import io.snabble.sdk.checkout.Checkout @@ -31,6 +29,7 @@ import io.snabble.sdk.checkout.CheckoutState import io.snabble.sdk.config.ExternalBillingSubjectLength import io.snabble.sdk.config.ProjectId import io.snabble.sdk.extensions.getApplicationInfoCompat +import io.snabble.sdk.shoppingcart.ShoppingCart import io.snabble.sdk.shoppingcart.data.Taxation import io.snabble.sdk.shoppingcart.data.listener.SimpleShoppingCartListener import io.snabble.sdk.ui.Keyguard @@ -41,6 +40,7 @@ import io.snabble.sdk.ui.payment.PaymentInputViewHelper import io.snabble.sdk.ui.payment.SEPALegalInfoHelper import io.snabble.sdk.ui.payment.SelectPaymentMethodFragment import io.snabble.sdk.ui.payment.externalbilling.ui.widgets.SubjectAlertDialog +import io.snabble.sdk.ui.remotetheme.SnabblePrimaryButton import io.snabble.sdk.ui.telemetry.Telemetry import io.snabble.sdk.ui.utils.DelayedProgressDialog import io.snabble.sdk.ui.utils.I18nUtils @@ -63,7 +63,7 @@ open class CheckoutBar @JvmOverloads constructor( private val paymentSelectorButton = findViewById(R.id.payment_selector_button) private val paymentSelectorButtonBig = findViewById(R.id.payment_selector_button_big) - private val payButton = findViewById