From 5d7d8817295d38304941b0891209df2e1dfc7f95 Mon Sep 17 00:00:00 2001 From: johan12345 Date: Sat, 6 Nov 2021 21:29:17 +0100 Subject: [PATCH] Chargeprice: add branding --- .../evmap/api/chargeprice/ChargepriceModel.kt | 12 ++++ .../net/vonforst/evmap/ui/BindingAdapters.kt | 65 +++++++++++++++---- .../drawable/branded_tariff_background.xml | 7 ++ app/src/main/res/layout/item_chargeprice.xml | 32 +++++---- 4 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 app/src/main/res/drawable/branded_tariff_background.xml diff --git a/app/src/main/java/net/vonforst/evmap/api/chargeprice/ChargepriceModel.kt b/app/src/main/java/net/vonforst/evmap/api/chargeprice/ChargepriceModel.kt index cc30a5df..2e91ee43 100644 --- a/app/src/main/java/net/vonforst/evmap/api/chargeprice/ChargepriceModel.kt +++ b/app/src/main/java/net/vonforst/evmap/api/chargeprice/ChargepriceModel.kt @@ -205,6 +205,9 @@ class ChargePrice : Resource(), Equatable, Cloneable { @field:Json(name = "charge_point_prices") lateinit var chargepointPrices: List + @field:Json(name = "branding") + var branding: ChargepriceBranding? = null + var tariff: HasOne? = null @@ -238,6 +241,7 @@ class ChargePrice : Resource(), Equatable, Cloneable { if (startTime != other.startTime) return false if (tags != other.tags) return false if (chargepointPrices != other.chargepointPrices) return false + if (branding != other.branding) return false return true } @@ -256,6 +260,7 @@ class ChargePrice : Resource(), Equatable, Cloneable { result = 31 * result + startTime result = 31 * result + tags.hashCode() result = 31 * result + chargepointPrices.hashCode() + result = 31 * result + branding.hashCode() return result } @@ -274,6 +279,7 @@ class ChargePrice : Resource(), Equatable, Cloneable { totalMonthlyFee = this@ChargePrice.totalMonthlyFee url = this@ChargePrice.url tariff = this@ChargePrice.tariff + branding = this@ChargePrice.branding } } } @@ -328,6 +334,12 @@ data class ChargepointPrice( } } +data class ChargepriceBranding( + @Json(name = "background_color") val backgroundColor: String, + @Json(name = "text_color") val textColor: String, + @Json(name = "logo_url") val logoUrl: String +) + data class PriceDistribution(val kwh: Double?, val session: Double?, val minute: Double?) { val isOnlyKwh = kwh != null && kwh > 0 && (session == null || session == 0.0) && (minute == null || minute == 0.0) diff --git a/app/src/main/java/net/vonforst/evmap/ui/BindingAdapters.kt b/app/src/main/java/net/vonforst/evmap/ui/BindingAdapters.kt index fb4ddf66..73c1d5e7 100644 --- a/app/src/main/java/net/vonforst/evmap/ui/BindingAdapters.kt +++ b/app/src/main/java/net/vonforst/evmap/ui/BindingAdapters.kt @@ -2,6 +2,10 @@ package net.vonforst.evmap.ui import android.content.Context import android.content.res.ColorStateList +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable +import android.graphics.drawable.LayerDrawable import android.text.SpannableString import android.view.View import android.view.ViewGroup.MarginLayoutParams @@ -18,14 +22,12 @@ import androidx.databinding.InverseBindingListener import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 +import coil.load import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.slider.RangeSlider -import net.vonforst.evmap.R +import net.vonforst.evmap.* import net.vonforst.evmap.api.availability.ChargepointStatus import net.vonforst.evmap.api.iconForPlugType -import net.vonforst.evmap.kmPerMile -import net.vonforst.evmap.meterPerFt -import net.vonforst.evmap.shouldUseImperialUnits import kotlin.math.ceil import kotlin.math.floor import kotlin.math.roundToInt @@ -344,14 +346,55 @@ fun setImageTintList(view: ImageView, @ColorInt color: Int) { view.imageTintList = ColorStateList.valueOf(color) } -@BindingAdapter("myTariffsBackground") -fun myTariffsBackground(view: View, myTariff: Boolean) { - if (myTariff) { - view.background = ContextCompat.getDrawable(view.context, R.drawable.my_tariff_background) - } else { - view.context.obtainStyledAttributes(intArrayOf(R.attr.selectableItemBackground)).use { - view.background = it.getDrawable(0) +fun tariffBackground(context: Context, myTariff: Boolean, brandingColor: String?): Drawable? { + when { + myTariff -> { + return ContextCompat.getDrawable(context, R.drawable.my_tariff_background) } + brandingColor != null -> { + val drawable = ContextCompat.getDrawable(context, R.drawable.branded_tariff_background) + val color = colorToTransparent(Color.parseColor(brandingColor)) + (drawable as LayerDrawable).setDrawableByLayerId( + R.id.background, ColorDrawable( + color + ) + ) + return drawable + } + else -> { + context.obtainStyledAttributes(intArrayOf(R.attr.selectableItemBackground)).use { + return it.getDrawable(0) + } + } + } +} + +fun isDarkMode(context: Context) = context.isDarkMode() + +/** + * Converts an opaque color to a transparent color, assuming it was on a white background + * with a certain opacity targetAlpha. + */ +private fun colorToTransparent(color: Int, targetAlpha: Float = 31f / 255): Int { + if (Color.alpha(color) != 255) return color + + val red = Color.red(color) + val green = Color.green(color) + val blue = Color.blue(color) + + val newRed = ((red - (1 - targetAlpha) * 255) / targetAlpha).roundToInt() + val newGreen = ((green - (1 - targetAlpha) * 255) / targetAlpha).roundToInt() + val newBlue = ((blue - (1 - targetAlpha) * 255) / targetAlpha).roundToInt() + + return Color.argb((targetAlpha * 255).roundToInt(), newRed, newGreen, newBlue) +} + +@BindingAdapter("imageUrl") +fun loadImage(view: ImageView, url: String?) { + if (url != null) { + view.load(url) + } else { + view.setImageDrawable(null) } } diff --git a/app/src/main/res/drawable/branded_tariff_background.xml b/app/src/main/res/drawable/branded_tariff_background.xml new file mode 100644 index 00000000..367d0d4d --- /dev/null +++ b/app/src/main/res/drawable/branded_tariff_background.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_chargeprice.xml b/app/src/main/res/layout/item_chargeprice.xml index b3a67f96..f13e785b 100644 --- a/app/src/main/res/layout/item_chargeprice.xml +++ b/app/src/main/res/layout/item_chargeprice.xml @@ -37,17 +37,16 @@ android:paddingTop="8dp" android:paddingRight="16dp" android:paddingBottom="8dp" - app:myTariffsBackground="@{!myTariffsAll && myTariffs.contains(item.tariff.get().id)}"> + android:background="@{BindingAdaptersKt.tariffBackground(context,!myTariffsAll && myTariffs.contains(item.tariff.get().id), item.branding.backgroundColor)}"> @@ -71,11 +69,10 @@ android:id="@+id/rvTags" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="4dp" android:nestedScrollingEnabled="false" app:data="@{item.tags}" app:layout_constraintBottom_toTopOf="@+id/txtProviderCustomerTariff" - app:layout_constraintEnd_toStartOf="@+id/guideline5" + app:layout_constraintEnd_toStartOf="@+id/ivLogo" app:layout_constraintStart_toStartOf="@+id/txtTariff" app:layout_constraintTop_toBottomOf="@+id/txtProvider" tools:itemCount="1" @@ -85,12 +82,12 @@ android:id="@+id/txtProviderCustomerTariff" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="4dp" android:text="@string/chargeprice_provider_customer_tariff" android:textAppearance="@style/TextAppearance.MaterialComponents.Caption" app:goneUnless="@{item.providerCustomerTariff}" app:layout_constraintBottom_toTopOf="@id/txtMonthlyFee" - app:layout_constraintEnd_toStartOf="@+id/guideline5" + app:layout_constraintEnd_toStartOf="@+id/ivLogo" + app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="@+id/txtTariff" app:layout_constraintTop_toBottomOf="@+id/rvTags" /> @@ -98,12 +95,11 @@ android:id="@+id/txtMonthlyFee" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="4dp" android:text="@{item.formatMonthlyFees(context)}" android:textAppearance="@style/TextAppearance.MaterialComponents.Caption" app:goneUnless="@{item.totalMonthlyFee > 0 || item.monthlyMinSales > 0}" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/guideline5" + app:layout_constraintEnd_toStartOf="@+id/ivLogo" app:layout_constraintStart_toStartOf="@+id/txtTariff" app:layout_constraintTop_toBottomOf="@+id/txtProviderCustomerTariff" tools:text="Base fee 1 €/month" /> @@ -160,5 +156,19 @@ android:orientation="vertical" app:layout_constraintGuide_percent="0.65" /> + +