From 208e77d14de741fdeaab07b7e874adb939c34aa1 Mon Sep 17 00:00:00 2001 From: Christian Maier Date: Wed, 27 Mar 2024 13:47:41 +0100 Subject: [PATCH 1/5] Add support for custom properties --- CHANGELOG.md | 9 ++++++++- core/src/main/java/io/snabble/sdk/Snabble.kt | 10 ++++++++++ .../io/snabble/sdk/config/CustomProperty.kt | 8 ++++++++ gradle/libs.versions.toml | 6 +++--- .../java/io/snabble/sdk/ui/cart/CheckoutBar.kt | 17 ++++++++++++++++- .../ui/widgets/SubjectAlertDialog.kt | 5 ++++- .../res/layout/snabble_subject_alert_dialog.xml | 3 +-- 7 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/io/snabble/sdk/config/CustomProperty.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 05d11e28e9..a555e3e572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,18 @@ All notable changes to this project will be documented in this file. ## UNRELEASED ### Added * ui/ui-toolkit: i18n using the Lokalise +* core/ui: Add support for project specific custom properties + * Make the external billing subject text max length configurable ### Changed -* ui: The `ProductResolver.Builder` now requires a project as constructor param, since the default value has been removed ### Removed * ui: Remove phrase for i18n ### Fixed + + +## [0.72.5] +### Changed +* ui: The `ProductResolver.Builder` now requires a project as constructor param, since the default value has been removed +### Fixed * core: Handle `SQLiteDatabaseLockedException` to fix app crash when updating the database * ui: Avoid npe caused by `isEmpty()` check on a null shopping cart * ui: Change project reference in `ProductResolver.kt` to get rid of IllegalArgumentException diff --git a/core/src/main/java/io/snabble/sdk/Snabble.kt b/core/src/main/java/io/snabble/sdk/Snabble.kt index 528fbe77a8..5d9c9c9a22 100644 --- a/core/src/main/java/io/snabble/sdk/Snabble.kt +++ b/core/src/main/java/io/snabble/sdk/Snabble.kt @@ -17,6 +17,8 @@ import com.google.gson.JsonObject import io.snabble.sdk.auth.TokenRegistry import io.snabble.sdk.checkin.CheckInLocationManager import io.snabble.sdk.checkin.CheckInManager +import io.snabble.sdk.config.CustomProperty +import io.snabble.sdk.config.ProjectId import io.snabble.sdk.customization.IsMergeable import io.snabble.sdk.events.Events import io.snabble.sdk.extensions.getPackageInfoCompat @@ -313,6 +315,14 @@ object Snabble { */ var isMergeable: IsMergeable? = null + /** + * Set [CustomProperty]'s to override the default behavior. + * + * Every [CustomProperty] has to be explicitly defined and implemented beforehand + * to be applicable for the given project. + */ + val customProperties: MutableMap, Any> = mutableMapOf() + /** * Setup the snabble SDK. * diff --git a/core/src/main/java/io/snabble/sdk/config/CustomProperty.kt b/core/src/main/java/io/snabble/sdk/config/CustomProperty.kt new file mode 100644 index 0000000000..e4d930e22c --- /dev/null +++ b/core/src/main/java/io/snabble/sdk/config/CustomProperty.kt @@ -0,0 +1,8 @@ +package io.snabble.sdk.config + +@JvmInline +value class ProjectId(val id: String) + +sealed interface CustomProperty + +data object ExternalBillingSubjectLength : CustomProperty diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 950d6d5f30..5cb686aa23 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,13 +2,13 @@ compileSdk = "33" targetSdk = "32" minSdk = "21" -gradlePlugin = "8.1.4" +gradlePlugin = "8.2.2" desugarVersion = "1.1.5" okhttpVersion = "4.10.0" # @pin always, manually updated to ensure overall dependency support -kotlin = "1.8.22" +kotlin = "1.9.23" # @pin always, manually updated to ensure overall dependency support -compose-compiler = "1.4.8" +compose-compiler = "1.5.11" navigation = "2.6.0" # @pin compose_version = "1.2.1" 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 7c30555f94..02e9602cab 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 @@ -28,6 +28,8 @@ import io.snabble.sdk.Snabble import io.snabble.sdk.Snabble.instance import io.snabble.sdk.checkout.Checkout 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.ui.Keyguard import io.snabble.sdk.ui.R @@ -320,7 +322,7 @@ open class CheckoutBar @JvmOverloads constructor( if (entry.paymentMethod == PaymentMethod.TEGUT_EMPLOYEE_CARD) { project.checkout.pay(entry.paymentMethod, entry.paymentCredentials) } else if (entry.paymentMethod == PaymentMethod.EXTERNAL_BILLING) { - SubjectAlertDialog(context) + SubjectAlertDialog(context, maxSubjectLength = getMaxSubjectLength()) .addMessageClickListener { message -> entry.paymentCredentials.additionalData["subject"] = message project.checkout.pay(entry.paymentMethod, entry.paymentCredentials) @@ -471,6 +473,19 @@ open class CheckoutBar @JvmOverloads constructor( } } } + + private fun getMaxSubjectLength(): Int = Snabble.checkedInProject.value + ?.id + ?.let { id -> + Snabble.customProperties + .getOrDefault( + ExternalBillingSubjectLength to ProjectId(id), + defaultValue = null + ) + ?.toString() + ?.toInt() + } + ?: -1 } fun interface CheckoutPreconditionHandler { diff --git a/ui/src/main/java/io/snabble/sdk/ui/payment/externalbilling/ui/widgets/SubjectAlertDialog.kt b/ui/src/main/java/io/snabble/sdk/ui/payment/externalbilling/ui/widgets/SubjectAlertDialog.kt index ecc8a37213..6951d73b87 100644 --- a/ui/src/main/java/io/snabble/sdk/ui/payment/externalbilling/ui/widgets/SubjectAlertDialog.kt +++ b/ui/src/main/java/io/snabble/sdk/ui/payment/externalbilling/ui/widgets/SubjectAlertDialog.kt @@ -6,6 +6,7 @@ import android.content.Context import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle +import android.text.InputFilter import android.view.ViewGroup.LayoutParams import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager @@ -15,7 +16,7 @@ import com.google.android.material.button.MaterialButton import com.google.android.material.textfield.TextInputLayout import io.snabble.sdk.ui.R -class SubjectAlertDialog(context: Context) : Dialog(context) { +class SubjectAlertDialog(context: Context, private val maxSubjectLength: Int = -1) : Dialog(context) { private var subjectMessageClickListener: SubjectMessageClickListener? = null private var skipClick: SubjectClickListener? = null @@ -41,6 +42,8 @@ class SubjectAlertDialog(context: Context) : Dialog(context) { add.isEnabled = it?.isNotEmpty() == true } + editTextField.filters = arrayOf(InputFilter.LengthFilter(if (maxSubjectLength > 0) maxSubjectLength else 150)) + add.setOnClickListener { subjectMessageClickListener?.onClick(input.editText?.text.toString()) dismiss() diff --git a/ui/src/main/res/layout/snabble_subject_alert_dialog.xml b/ui/src/main/res/layout/snabble_subject_alert_dialog.xml index 747f6eef0f..d42bdbc833 100644 --- a/ui/src/main/res/layout/snabble_subject_alert_dialog.xml +++ b/ui/src/main/res/layout/snabble_subject_alert_dialog.xml @@ -35,8 +35,7 @@ android:id="@+id/text_edit_subject" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="textCapSentences" - android:maxLength="150" /> + android:inputType="textCapSentences"/> From 8b0cabd156a930b7298ca87f2f6e6316c51cf673 Mon Sep 17 00:00:00 2001 From: Christian Maier Date: Wed, 27 Mar 2024 14:14:03 +0100 Subject: [PATCH 2/5] Add missing core library desugaring to kotlin-sample --- kotlin-sample/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/kotlin-sample/build.gradle.kts b/kotlin-sample/build.gradle.kts index 6bfe118a71..b318b3d73d 100644 --- a/kotlin-sample/build.gradle.kts +++ b/kotlin-sample/build.gradle.kts @@ -31,6 +31,7 @@ android { } compileOptions { + isCoreLibraryDesugaringEnabled = true sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } From 2310a4d8c7975a2fdb6e0cfab141d988c828b226 Mon Sep 17 00:00:00 2001 From: Christian Maier Date: Thu, 28 Mar 2024 08:25:11 +0100 Subject: [PATCH 3/5] Ignore restriction since lacking alternative --- .../java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/src/main/java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java b/ui/src/main/java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java index 06f70a8c2a..49db499347 100644 --- a/ui/src/main/java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java +++ b/ui/src/main/java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java @@ -1,5 +1,6 @@ package io.snabble.sdk.ui.utils; +import android.annotation.SuppressLint; import android.content.Context; import android.util.AttributeSet; import android.view.View; @@ -18,6 +19,7 @@ public SnackbarPushUpBehavior(Context context, AttributeSet attrs) { super(context, attrs); } + @SuppressLint("RestrictedApi") @Override public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull View child, From b7cf60baa7280fba5e9f4d30880e09407ab77c2b Mon Sep 17 00:00:00 2001 From: Christian Maier Date: Thu, 28 Mar 2024 08:32:17 +0100 Subject: [PATCH 4/5] Remove obsolete SnackbarPushUpBehavior.java --- .../sdk/ui/utils/SnackbarPushUpBehavior.java | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 ui/src/main/java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java diff --git a/ui/src/main/java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java b/ui/src/main/java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java deleted file mode 100644 index 49db499347..0000000000 --- a/ui/src/main/java/io/snabble/sdk/ui/utils/SnackbarPushUpBehavior.java +++ /dev/null @@ -1,45 +0,0 @@ -package io.snabble.sdk.ui.utils; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; - -import androidx.annotation.NonNull; -import androidx.coordinatorlayout.widget.CoordinatorLayout; - -import com.google.android.material.snackbar.Snackbar; - -public class SnackbarPushUpBehavior extends CoordinatorLayout.Behavior { - public SnackbarPushUpBehavior() { - - } - - public SnackbarPushUpBehavior(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @SuppressLint("RestrictedApi") - @Override - public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, - @NonNull View child, - @NonNull View dependency) { - return dependency instanceof Snackbar.SnackbarLayout; - } - - @Override - public void onDependentViewRemoved(@NonNull CoordinatorLayout parent, - View child, - @NonNull View dependency) { - child.setTranslationY(0); - } - - @Override - public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, - View child, - View dependency) { - float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight()); - child.setTranslationY(translationY); - return true; - } -} From f9a594e2014929d495f0e07acff0744b8a2c2dd1 Mon Sep 17 00:00:00 2001 From: Christian Maier Date: Thu, 28 Mar 2024 12:07:53 +0100 Subject: [PATCH 5/5] Use null instead of -1 as default value --- ui/src/main/java/io/snabble/sdk/ui/cart/CheckoutBar.kt | 3 +-- .../payment/externalbilling/ui/widgets/SubjectAlertDialog.kt | 4 ++-- 2 files changed, 3 insertions(+), 4 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 02e9602cab..e783c81072 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 @@ -474,7 +474,7 @@ open class CheckoutBar @JvmOverloads constructor( } } - private fun getMaxSubjectLength(): Int = Snabble.checkedInProject.value + private fun getMaxSubjectLength(): Int? = Snabble.checkedInProject.value ?.id ?.let { id -> Snabble.customProperties @@ -485,7 +485,6 @@ open class CheckoutBar @JvmOverloads constructor( ?.toString() ?.toInt() } - ?: -1 } fun interface CheckoutPreconditionHandler { diff --git a/ui/src/main/java/io/snabble/sdk/ui/payment/externalbilling/ui/widgets/SubjectAlertDialog.kt b/ui/src/main/java/io/snabble/sdk/ui/payment/externalbilling/ui/widgets/SubjectAlertDialog.kt index 6951d73b87..5af11e558d 100644 --- a/ui/src/main/java/io/snabble/sdk/ui/payment/externalbilling/ui/widgets/SubjectAlertDialog.kt +++ b/ui/src/main/java/io/snabble/sdk/ui/payment/externalbilling/ui/widgets/SubjectAlertDialog.kt @@ -16,7 +16,7 @@ import com.google.android.material.button.MaterialButton import com.google.android.material.textfield.TextInputLayout import io.snabble.sdk.ui.R -class SubjectAlertDialog(context: Context, private val maxSubjectLength: Int = -1) : Dialog(context) { +class SubjectAlertDialog(context: Context, private val maxSubjectLength: Int? = null) : Dialog(context) { private var subjectMessageClickListener: SubjectMessageClickListener? = null private var skipClick: SubjectClickListener? = null @@ -42,7 +42,7 @@ class SubjectAlertDialog(context: Context, private val maxSubjectLength: Int = - add.isEnabled = it?.isNotEmpty() == true } - editTextField.filters = arrayOf(InputFilter.LengthFilter(if (maxSubjectLength > 0) maxSubjectLength else 150)) + editTextField.filters = arrayOf(InputFilter.LengthFilter(maxSubjectLength ?: 150)) add.setOnClickListener { subjectMessageClickListener?.onClick(input.editText?.text.toString())