From a677fb90f0e69ab288f418f7b760d7d6e25d1418 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Tue, 27 Aug 2024 09:38:09 +0200 Subject: [PATCH 01/46] add new property to the project containing the app theme --- core/src/main/java/io/snabble/sdk/Project.kt | 88 +++++++++++++++++--- core/src/main/java/io/snabble/sdk/Snabble.kt | 2 +- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/io/snabble/sdk/Project.kt b/core/src/main/java/io/snabble/sdk/Project.kt index a912bca9a8..57857814d1 100644 --- a/core/src/main/java/io/snabble/sdk/Project.kt +++ b/core/src/main/java/io/snabble/sdk/Project.kt @@ -1,7 +1,10 @@ package io.snabble.sdk +import com.google.gson.Gson import com.google.gson.JsonElement import com.google.gson.JsonObject +import com.google.gson.JsonSyntaxException +import com.google.gson.annotations.SerializedName import com.google.gson.reflect.TypeToken import io.snabble.sdk.auth.SnabbleAuthorizationInterceptor import io.snabble.sdk.checkout.Checkout @@ -23,13 +26,22 @@ import io.snabble.sdk.utils.getIntOpt import io.snabble.sdk.utils.getString import io.snabble.sdk.utils.getStringListOpt import io.snabble.sdk.utils.getStringOpt +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.Call +import okhttp3.Callback import okhttp3.OkHttpClient import okhttp3.Request +import okhttp3.Response import org.apache.commons.lang3.LocaleUtils import java.io.File +import java.io.IOException import java.math.RoundingMode import java.util.Currency import java.util.Locale @@ -39,7 +51,10 @@ import java.util.concurrent.CopyOnWriteArrayList * A project contains configuration information and backend api urls needed for a * retailer. */ -class Project internal constructor(jsonObject: JsonObject) { +class Project internal constructor( + private val gson: Gson = GsonHolder.get(), + jsonObject: JsonObject +) { /** * The unique identifier of the Project @@ -164,7 +179,8 @@ class Project internal constructor(jsonObject: JsonObject) { // refresh encoded codes options for encoded codes that contain customer cards if (encodedCodesJsonObject != null) { - encodedCodesOptions = EncodedCodesOptions.fromJsonObject(this, encodedCodesJsonObject) + encodedCodesOptions = + EncodedCodesOptions.fromJsonObject(this, encodedCodesJsonObject) } } @@ -340,6 +356,10 @@ class Project internal constructor(jsonObject: JsonObject) { lateinit var assets: Assets private set + var appTheme: AppTheme? = null + + private val scope = CoroutineScope(Job() + Dispatchers.IO) + init { parse(jsonObject) } @@ -415,7 +435,8 @@ class Project internal constructor(jsonObject: JsonObject) { paymentMethodDescriptors = jsonObject["paymentMethodDescriptors"]?.let { val typeToken = object : TypeToken?>() {}.type - val paymentMethodDescriptors = GsonHolder.get().fromJson>(it, typeToken) + val paymentMethodDescriptors = + gson.fromJson>(it, typeToken) paymentMethodDescriptors.filter { desc -> PaymentMethod.fromString(desc.id) != null } @@ -428,12 +449,13 @@ class Project internal constructor(jsonObject: JsonObject) { } if (jsonObject.has("company")) { - company = GsonHolder.get().fromJson(jsonObject["company"], Company::class.java) + company = gson.fromJson(jsonObject["company"], Company::class.java) } - val codeTemplates = jsonObject["codeTemplates"]?.asJsonObject?.entrySet()?.map { (name, pattern) -> - CodeTemplate(name, pattern.asString) - }?.toMutableList() ?: mutableListOf() + val codeTemplates = + jsonObject["codeTemplates"]?.asJsonObject?.entrySet()?.map { (name, pattern) -> + CodeTemplate(name, pattern.asString) + }?.toMutableList() ?: mutableListOf() val hasDefaultTemplate = codeTemplates.any { it.name == "default" } if (!hasDefaultTemplate) { @@ -451,7 +473,8 @@ class Project internal constructor(jsonObject: JsonObject) { ) var matchingTemplate: CodeTemplate? = null if (priceOverride.has("transmissionTemplate")) { - matchingTemplate = getCodeTemplate(priceOverride["transmissionTemplate"].asString) + matchingTemplate = + getCodeTemplate(priceOverride["transmissionTemplate"].asString) } val priceOverrideTemplate = PriceOverrideTemplate( codeTemplate, @@ -494,7 +517,7 @@ class Project internal constructor(jsonObject: JsonObject) { if (jsonObject.has("coupons")) { val couponsJsonObject = jsonObject["coupons"] val couponsType = object : TypeToken?>() {}.type - couponList = GsonHolder.get().fromJson(couponsJsonObject, couponsType) + couponList = gson.fromJson(couponsJsonObject, couponsType) } } catch (e: Exception) { Logger.e("Could not parse coupons") @@ -508,13 +531,22 @@ class Project internal constructor(jsonObject: JsonObject) { .addInterceptor(AcceptedLanguageInterceptor()) .build() + scope.launch { + loadAppAppearance() + } + _shoppingCart.tryEmit(ShoppingCart(this)) shoppingCartStorage = ShoppingCartStorage(this) checkout = Checkout(this, shoppingCartFlow.value) - productDatabase = ProductDatabase(this, shoppingCartFlow.value, "$id.sqlite3", Snabble.config.generateSearchIndex) + productDatabase = ProductDatabase( + this, + shoppingCartFlow.value, + "$id.sqlite3", + Snabble.config.generateSearchIndex + ) events = Events(this, shoppingCartFlow.value) @@ -536,6 +568,35 @@ class Project internal constructor(jsonObject: JsonObject) { notifyUpdate() } + private suspend fun loadAppAppearance() = withContext(Dispatchers.IO) { + val path = urls["customizationConfig"] ?: return@withContext + val request = Request.Builder().get().url(Snabble.absoluteUrl(path)).build() + + okHttpClient.newCall(request).enqueue(object : Callback { + + override fun onResponse(call: Call, response: Response) { + when (response.code) { + HTTTP_STATUS_OK -> { + try { + appTheme = gson.fromJson(response.body?.string(), AppTheme::class.java) + Logger.d("AppTheme for $id loaded: $appTheme") + } catch (e: JsonSyntaxException) { + Logger.e(e.message) + } + } + + else -> { + Logger.d("No remote theme provided") + } + } + } + + override fun onFailure(call: Call, e: IOException) { + Logger.e("Failed to load remote theme: ${e.message}") + } + }) + } + var googlePayHelper = paymentMethodDescriptors .mapNotNull { it.paymentMethod } .firstOrNull { it == PaymentMethod.GOOGLE_PAY } @@ -659,3 +720,10 @@ class Project internal constructor(jsonObject: JsonObject) { fun onProjectUpdated(project: Project?) } } + +private const val HTTTP_STATUS_OK = 200 + +data class AppTheme( + @SerializedName("colorPrimary") val primaryColor: String, + @SerializedName("colorSecondary") val secondaryColor: String +) diff --git a/core/src/main/java/io/snabble/sdk/Snabble.kt b/core/src/main/java/io/snabble/sdk/Snabble.kt index d908edbb5f..ebd309d8dd 100644 --- a/core/src/main/java/io/snabble/sdk/Snabble.kt +++ b/core/src/main/java/io/snabble/sdk/Snabble.kt @@ -620,7 +620,7 @@ object Snabble { // if it does not exist, add it if (!updated) { try { - val project = Project(jsonProject) + val project = Project(jsonObject = jsonProject) newProjects.add(project) } catch (e: IllegalArgumentException) { Logger.d(e.message) From e2ea58e38e00999de7239af6c2317ae45c6f82e7 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Tue, 27 Aug 2024 09:38:51 +0200 Subject: [PATCH 02/46] WIP: Replace MaterialButton with CustomView e.g. SnabblePrimaryButton --- .../layout/snabble_fragment_onboarding.xml | 4 +-- .../layout/snabble_shop_details_fragment.xml | 2 +- .../ui/remotetheme/SnabblePrimaryButton.kt | 30 +++++++++++++++++++ .../snabble_dialog_product_confirmation.xml | 8 ++--- ...bble_dialog_qrcodeoffline_confirmation.xml | 6 ++-- .../layout/snabble_dialog_sepa_legal_info.xml | 4 +-- .../snabble_fragment_combined_scanner.xml | 2 +- .../layout/snabble_fragment_coupon_detail.xml | 6 ++-- .../layout/snabble_fragment_selfscanning.xml | 4 +-- .../layout/snabble_subject_alert_dialog.xml | 4 +-- .../layout/snabble_view_age_verification.xml | 4 +-- .../layout/snabble_view_cardinput_sepa.xml | 2 +- .../res/layout/snabble_view_checkout_bar.xml | 6 ++-- .../snabble_view_checkout_customercard.xml | 4 +-- .../snabble_view_checkout_gatekeeper.xml | 2 +- .../layout/snabble_view_checkout_offline.xml | 4 +-- .../res/layout/snabble_view_checkout_pos.xml | 4 +-- .../layout/snabble_view_payment_status.xml | 6 ++-- .../snabble_view_payment_status_item.xml | 4 +-- .../snabble_view_routing_gatekeeper.xml | 2 +- .../snabble_view_routing_supervisor.xml | 2 +- .../layout/snabble_view_search_product.xml | 2 +- .../res/layout/snabble_view_self_scanning.xml | 4 +-- .../res/layout/snabble_view_shopping_cart.xml | 4 +-- 24 files changed, 75 insertions(+), 45 deletions(-) create mode 100644 ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt diff --git a/ui-toolkit/src/main/res/layout/snabble_fragment_onboarding.xml b/ui-toolkit/src/main/res/layout/snabble_fragment_onboarding.xml index a3724c49cc..afc012e1ac 100644 --- a/ui-toolkit/src/main/res/layout/snabble_fragment_onboarding.xml +++ b/ui-toolkit/src/main/res/layout/snabble_fragment_onboarding.xml @@ -32,7 +32,7 @@ app:tabMaxWidth="16dp" app:tabIndicatorHeight="0dp" /> - - \ No newline at end of file + diff --git a/ui-toolkit/src/main/res/layout/snabble_shop_details_fragment.xml b/ui-toolkit/src/main/res/layout/snabble_shop_details_fragment.xml index 6d691320ad..505fab7e50 100644 --- a/ui-toolkit/src/main/res/layout/snabble_shop_details_fragment.xml +++ b/ui-toolkit/src/main/res/layout/snabble_shop_details_fragment.xml @@ -129,7 +129,7 @@ android:textAlignment="center" tools:text="Bornheimer Straße 162\n53119 Bonn" /> - + setBackgroundColor(appTheme.primaryColor.asColor()) + setTextColor(appTheme.secondaryColor.asColor()) + } + } + } +} + +private fun String.asColor() = Color.parseColor(this) diff --git a/ui/src/main/res/layout/snabble_dialog_product_confirmation.xml b/ui/src/main/res/layout/snabble_dialog_product_confirmation.xml index 54f774ba28..609066c141 100644 --- a/ui/src/main/res/layout/snabble_dialog_product_confirmation.xml +++ b/ui/src/main/res/layout/snabble_dialog_product_confirmation.xml @@ -64,7 +64,7 @@ android:textAppearance="?attr/textAppearanceBodySmall" tools:text="+ 0,45 € deposit" /> - - - - - - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_dialog_sepa_legal_info.xml b/ui/src/main/res/layout/snabble_dialog_sepa_legal_info.xml index 924fd6bdb2..934b5bdd78 100644 --- a/ui/src/main/res/layout/snabble_dialog_sepa_legal_info.xml +++ b/ui/src/main/res/layout/snabble_dialog_sepa_legal_info.xml @@ -44,11 +44,11 @@ - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_fragment_combined_scanner.xml b/ui/src/main/res/layout/snabble_fragment_combined_scanner.xml index aa09960866..89936b2e47 100644 --- a/ui/src/main/res/layout/snabble_fragment_combined_scanner.xml +++ b/ui/src/main/res/layout/snabble_fragment_combined_scanner.xml @@ -37,7 +37,7 @@ android:layout_marginBottom="24dp" android:text="@string/Snabble.Scanner.Camera.allowAccess"/> - - - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_fragment_selfscanning.xml b/ui/src/main/res/layout/snabble_fragment_selfscanning.xml index a88ae29471..803004f7b1 100644 --- a/ui/src/main/res/layout/snabble_fragment_selfscanning.xml +++ b/ui/src/main/res/layout/snabble_fragment_selfscanning.xml @@ -36,11 +36,11 @@ android:textAppearance="?attr/textAppearanceBodyLarge" android:text="@string/Snabble.Scanner.Camera.allowAccess"/> - - \ No newline at end of file + 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 d42bdbc833..71b3bd96b1 100644 --- a/ui/src/main/res/layout/snabble_subject_alert_dialog.xml +++ b/ui/src/main/res/layout/snabble_subject_alert_dialog.xml @@ -43,7 +43,7 @@ android:layout_width="match_parent" android:layout_height="24dp" /> - - - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_view_cardinput_sepa.xml b/ui/src/main/res/layout/snabble_view_cardinput_sepa.xml index 72817ce8dd..00f32eecf8 100644 --- a/ui/src/main/res/layout/snabble_view_cardinput_sepa.xml +++ b/ui/src/main/res/layout/snabble_view_cardinput_sepa.xml @@ -99,7 +99,7 @@ android:layout_centerHorizontal="true" android:layout_below="@+id/input_iban_layout"> - - - - - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_view_checkout_gatekeeper.xml b/ui/src/main/res/layout/snabble_view_checkout_gatekeeper.xml index 9ce2c24834..68afab6da8 100644 --- a/ui/src/main/res/layout/snabble_view_checkout_gatekeeper.xml +++ b/ui/src/main/res/layout/snabble_view_checkout_gatekeeper.xml @@ -84,7 +84,7 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"> - - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_view_checkout_pos.xml b/ui/src/main/res/layout/snabble_view_checkout_pos.xml index 96348ebd52..8af66c706f 100644 --- a/ui/src/main/res/layout/snabble_view_checkout_pos.xml +++ b/ui/src/main/res/layout/snabble_view_checkout_pos.xml @@ -64,7 +64,7 @@ android:layout_marginBottom="16dp" android:textAppearance="?attr/textAppearanceBodyMedium" /> - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_view_payment_status.xml b/ui/src/main/res/layout/snabble_view_payment_status.xml index 2b9f26e7c2..64bbdb127a 100644 --- a/ui/src/main/res/layout/snabble_view_payment_status.xml +++ b/ui/src/main/res/layout/snabble_view_payment_status.xml @@ -161,7 +161,7 @@ android:text="@string/Snabble.PaymentStatus.AddDebitCard.message" android:textAppearance="?attr/textAppearanceBodyLarge" /> - - - - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_view_routing_gatekeeper.xml b/ui/src/main/res/layout/snabble_view_routing_gatekeeper.xml index 9fc1fe2cd8..60edae56e2 100644 --- a/ui/src/main/res/layout/snabble_view_routing_gatekeeper.xml +++ b/ui/src/main/res/layout/snabble_view_routing_gatekeeper.xml @@ -86,7 +86,7 @@ android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"> - - - - - \ No newline at end of file + diff --git a/ui/src/main/res/layout/snabble_view_shopping_cart.xml b/ui/src/main/res/layout/snabble_view_shopping_cart.xml index c2011e751c..68cece5aff 100644 --- a/ui/src/main/res/layout/snabble_view_shopping_cart.xml +++ b/ui/src/main/res/layout/snabble_view_shopping_cart.xml @@ -65,7 +65,7 @@ android:textAppearance="?attr/textAppearanceBodyLarge" android:text="@string/Snabble.Shoppingcart.EmptyState.description" /> - - Date: Wed, 28 Aug 2024 07:39:07 +0200 Subject: [PATCH 03/46] WIP: make compose fun public --- .../java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 cbf1096f43..1ec6edca5a 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 @@ -27,4 +27,4 @@ class SnabblePrimaryButton @JvmOverloads constructor( } } -private fun String.asColor() = Color.parseColor(this) +fun String.asColor() = Color.parseColor(this) From 7c2097c6098a7a7257b683abaaf17a1ebc36a11e Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Wed, 28 Aug 2024 09:15:05 +0200 Subject: [PATCH 04/46] WIP: only set background color --- .../java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryButton.kt | 1 - 1 file changed, 1 deletion(-) 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 1ec6edca5a..1f797a62ae 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 @@ -21,7 +21,6 @@ class SnabblePrimaryButton @JvmOverloads constructor( Snabble.checkedInProject.observeForever { it?.appTheme?.let { appTheme -> setBackgroundColor(appTheme.primaryColor.asColor()) - setTextColor(appTheme.secondaryColor.asColor()) } } } From a0a528a3afbab31d6f2bb8e805ae0d39b31a3670 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Wed, 28 Aug 2024 09:16:20 +0200 Subject: [PATCH 05/46] WIP: fix typo --- core/src/main/java/io/snabble/sdk/Project.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/io/snabble/sdk/Project.kt b/core/src/main/java/io/snabble/sdk/Project.kt index 57857814d1..e9862a748a 100644 --- a/core/src/main/java/io/snabble/sdk/Project.kt +++ b/core/src/main/java/io/snabble/sdk/Project.kt @@ -576,7 +576,7 @@ class Project internal constructor( override fun onResponse(call: Call, response: Response) { when (response.code) { - HTTTP_STATUS_OK -> { + HTTP_STATUS_OK -> { try { appTheme = gson.fromJson(response.body?.string(), AppTheme::class.java) Logger.d("AppTheme for $id loaded: $appTheme") @@ -721,7 +721,7 @@ class Project internal constructor( } } -private const val HTTTP_STATUS_OK = 200 +private const val HTTP_STATUS_OK = 200 data class AppTheme( @SerializedName("colorPrimary") val primaryColor: String, From 895c774409eb80ba659941cd516beedbe6c1e625 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Wed, 28 Aug 2024 11:56:51 +0200 Subject: [PATCH 06/46] WIP: add dependency for live data as flow extension --- ui/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/build.gradle.kts b/ui/build.gradle.kts index dbf71b89e8..7a539d2451 100644 --- a/ui/build.gradle.kts +++ b/ui/build.gradle.kts @@ -84,6 +84,7 @@ dependencies { implementation(libs.androidx.cardview) implementation(libs.androidx.core.ktx) implementation(libs.androidx.gridlayout) + implementation(libs.androidx.lifecycleLiveData) implementation(libs.android.material) implementation(libs.androidx.recyclerview) implementation(libs.androidx.startupRuntime) @@ -102,7 +103,6 @@ dependencies { implementation(libs.rekisoftLazyWorker) implementation(libs.relex.circleindicator) implementation(libs.snabble.phoneAuth.countryCodePicker) - implementation(libs.bundles.camera) implementation(libs.bundles.navigation) From 448c0116f380751087293530fcd6442f9c2429ca Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Wed, 28 Aug 2024 12:00:16 +0200 Subject: [PATCH 07/46] WIP: remove observe forever and create extension functions for theming --- .../sdk/ui/remotetheme/RemoteThemingExtensions.kt | 15 +++++++++++++++ .../sdk/ui/remotetheme/SnabblePrimaryButton.kt | 10 ++-------- 2 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 ui/src/main/java/io/snabble/sdk/ui/remotetheme/RemoteThemingExtensions.kt diff --git a/ui/src/main/java/io/snabble/sdk/ui/remotetheme/RemoteThemingExtensions.kt b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/RemoteThemingExtensions.kt new file mode 100644 index 0000000000..fe66fc7b8c --- /dev/null +++ b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/RemoteThemingExtensions.kt @@ -0,0 +1,15 @@ +package io.snabble.sdk.ui.remotetheme + +import android.content.Context +import android.graphics.Color +import io.snabble.sdk.Project +import io.snabble.sdk.ui.R +import io.snabble.sdk.utils.getColorByAttribute + +fun Context.getPrimaryColorForProject(project: Project?) = + project?.appTheme?.primaryColor?.asColor() ?: getColorByAttribute(R.attr.colorPrimary) + +fun Context.getSecondaryColorForProject(project: Project?) = + project?.appTheme?.secondaryColor?.asColor() ?: getColorByAttribute(R.attr.colorSecondary) + +fun String.asColor() = Color.parseColor(this) 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 1f797a62ae..d19581b515 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 @@ -1,7 +1,6 @@ package io.snabble.sdk.ui.remotetheme import android.content.Context -import android.graphics.Color import android.util.AttributeSet import com.google.android.material.button.MaterialButton import io.snabble.sdk.Snabble @@ -18,12 +17,7 @@ class SnabblePrimaryButton @JvmOverloads constructor( } private fun init() { - Snabble.checkedInProject.observeForever { - it?.appTheme?.let { appTheme -> - setBackgroundColor(appTheme.primaryColor.asColor()) - } - } + val project = Snabble.checkedInProject.value + setBackgroundColor(context.getPrimaryColorForProject(project)) } } - -fun String.asColor() = Color.parseColor(this) From 61aed6d61ab7b9acffb5f8ce9678fbb22b5ac4b0 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Wed, 28 Aug 2024 17:01:46 +0200 Subject: [PATCH 08/46] WIP: adjust primary button default style and add second impl for secondary buttons --- .../ui/remotetheme/SnabblePrimaryButton.kt | 2 +- .../ui/remotetheme/SnabbleSecondaryButton.kt | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabbleSecondaryButton.kt 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 d19581b515..1327489c24 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 @@ -9,7 +9,7 @@ import io.snabble.sdk.ui.R class SnabblePrimaryButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = R.attr.buttonStyle, + defStyleAttr: Int = R.attr.materialButtonStyle, ) : MaterialButton(context, attrs, defStyleAttr) { init { diff --git a/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabbleSecondaryButton.kt b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabbleSecondaryButton.kt new file mode 100644 index 0000000000..2ddee2a535 --- /dev/null +++ b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabbleSecondaryButton.kt @@ -0,0 +1,23 @@ +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 io.snabble.sdk.ui.R + +class SnabbleSecondaryButton @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = R.attr.materialButtonStyle, +) : MaterialButton(context, attrs, defStyleAttr) { + + init { + init() + } + + private fun init() { + val project = Snabble.checkedInProject.value + setTextColor(context.getPrimaryColorForProject(project)) + } +} From d9f48b02c23cb28e17a6188825b779be8bdec393 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Thu, 29 Aug 2024 14:30:48 +0200 Subject: [PATCH 09/46] add TextView with default primary color --- .../ui/remotetheme/SnabblePrimaryTextView.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryTextView.kt diff --git a/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryTextView.kt b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryTextView.kt new file mode 100644 index 0000000000..847631e391 --- /dev/null +++ b/ui/src/main/java/io/snabble/sdk/ui/remotetheme/SnabblePrimaryTextView.kt @@ -0,0 +1,23 @@ +package io.snabble.sdk.ui.remotetheme + +import android.content.Context +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatTextView +import io.snabble.sdk.Snabble + +class SnabblePrimaryTextView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = android.R.attr.textViewStyle +) : AppCompatTextView(context, attrs, defStyleAttr) { + + + init { + init() + } + + private fun init() { + val project = Snabble.checkedInProject.value + setTextColor(context.getPrimaryColorForProject(project)) + } +} From d26964d1b53e10a051576438a865e402bcdfb329 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Fri, 30 Aug 2024 14:23:26 +0200 Subject: [PATCH 10/46] remove obsolete loading of the theme and change parsing to get directly through the metadata --- core/src/main/java/io/snabble/sdk/Project.kt | 44 ++++---------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/io/snabble/sdk/Project.kt b/core/src/main/java/io/snabble/sdk/Project.kt index e9862a748a..40e1e0a9e4 100644 --- a/core/src/main/java/io/snabble/sdk/Project.kt +++ b/core/src/main/java/io/snabble/sdk/Project.kt @@ -357,9 +357,7 @@ class Project internal constructor( private set var appTheme: AppTheme? = null - - private val scope = CoroutineScope(Job() + Dispatchers.IO) - + init { parse(jsonObject) } @@ -381,6 +379,13 @@ class Project internal constructor( links.entrySet().forEach { urls[it.key] = Snabble.absoluteUrl(it.value.asJsonObject["href"].asString) } + val customizationConfig = jsonObject["appCustomizationConfig"].asJsonObject + try { + appTheme = gson.fromJson(customizationConfig, AppTheme::class.java) + Logger.d("AppTheme for $id loaded: $appTheme") + } catch (e: JsonSyntaxException) { + Logger.e(e.message) + } this.urls = urls tokensUrl = "${urls["tokens"]}?role=retailerApp" @@ -531,10 +536,6 @@ class Project internal constructor( .addInterceptor(AcceptedLanguageInterceptor()) .build() - scope.launch { - loadAppAppearance() - } - _shoppingCart.tryEmit(ShoppingCart(this)) shoppingCartStorage = ShoppingCartStorage(this) @@ -568,35 +569,6 @@ class Project internal constructor( notifyUpdate() } - private suspend fun loadAppAppearance() = withContext(Dispatchers.IO) { - val path = urls["customizationConfig"] ?: return@withContext - val request = Request.Builder().get().url(Snabble.absoluteUrl(path)).build() - - okHttpClient.newCall(request).enqueue(object : Callback { - - override fun onResponse(call: Call, response: Response) { - when (response.code) { - HTTP_STATUS_OK -> { - try { - appTheme = gson.fromJson(response.body?.string(), AppTheme::class.java) - Logger.d("AppTheme for $id loaded: $appTheme") - } catch (e: JsonSyntaxException) { - Logger.e(e.message) - } - } - - else -> { - Logger.d("No remote theme provided") - } - } - } - - override fun onFailure(call: Call, e: IOException) { - Logger.e("Failed to load remote theme: ${e.message}") - } - }) - } - var googlePayHelper = paymentMethodDescriptors .mapNotNull { it.paymentMethod } .firstOrNull { it == PaymentMethod.GOOGLE_PAY } From c703a6f0bc834c4725670fa318c857050883d608 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Fri, 30 Aug 2024 15:13:48 +0200 Subject: [PATCH 11/46] use json element instead of the object --- core/src/main/java/io/snabble/sdk/Project.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/io/snabble/sdk/Project.kt b/core/src/main/java/io/snabble/sdk/Project.kt index 40e1e0a9e4..ac39b1c54c 100644 --- a/core/src/main/java/io/snabble/sdk/Project.kt +++ b/core/src/main/java/io/snabble/sdk/Project.kt @@ -379,7 +379,7 @@ class Project internal constructor( links.entrySet().forEach { urls[it.key] = Snabble.absoluteUrl(it.value.asJsonObject["href"].asString) } - val customizationConfig = jsonObject["appCustomizationConfig"].asJsonObject + val customizationConfig : JsonElement? = jsonObject["appCustomizationConfig"] try { appTheme = gson.fromJson(customizationConfig, AppTheme::class.java) Logger.d("AppTheme for $id loaded: $appTheme") From d0fb844fca8612ddb51ed7645bb1df4155a7afc1 Mon Sep 17 00:00:00 2001 From: Fabian Bender Date: Fri, 30 Aug 2024 15:35:04 +0200 Subject: [PATCH 12/46] switch to secondary button --- .../src/main/res/layout/snabble_shop_details_fragment.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-toolkit/src/main/res/layout/snabble_shop_details_fragment.xml b/ui-toolkit/src/main/res/layout/snabble_shop_details_fragment.xml index 505fab7e50..bcf583e36a 100644 --- a/ui-toolkit/src/main/res/layout/snabble_shop_details_fragment.xml +++ b/ui-toolkit/src/main/res/layout/snabble_shop_details_fragment.xml @@ -26,7 +26,7 @@ android:gravity="center" android:text="@string/Snabble.Shop.Details.MapDisabled.title" /> -