// Copyright © 2022 Olo Inc. All rights reserved. // This software is made available under the Olo Pay SDK License (See LICENSE.md file) package com.olopaysdkreactnative.digitalwalletbutton import android.annotation.SuppressLint import android.util.AttributeSet import android.util.TypedValue import androidx.constraintlayout.widget.ConstraintLayout import com.facebook.react.bridge.ReadableMap import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.UIManagerHelper import com.olo.olopay.googlepay.GooglePayButton import com.olo.olopay.googlepay.GooglePayButtonTheme import com.olo.olopay.googlepay.GooglePayButtonType import com.olopaysdkreactnative.R import com.olopaysdkreactnative.data.DataKeys import com.olopaysdkreactnative.digitalwalletbutton.events.DigitalWalletButtonClickedEvent import com.olopaysdkreactnative.extensions.getNullableDouble import com.olopaysdkreactnative.extensions.getNullableString @SuppressLint("ViewConstructor") class DigitalWalletButton @JvmOverloads constructor( context: ThemedReactContext, attrs: AttributeSet? = null ): ConstraintLayout(context, attrs) { private val _button: GooglePayButton private var _googlePayButtonTheme: GooglePayButtonTheme? = null private var _googlePayButtonType: GooglePayButtonType? = null private var _googlePayButtonCornerRadius: Int? = null private val reactContext: ThemedReactContext get() = context as ThemedReactContext private val surfaceId get() = UIManagerHelper.getSurfaceId(reactContext) init { inflate(context, R.layout.rnsdk_googlepay_button, this) _button = findViewById(R.id.rn_google_pay_button) _button.setOnClickListener { DigitalWalletButtonClickedEvent(surfaceId, id).emit(reactContext) } } override fun setEnabled(enabled: Boolean) { _button.isEnabled = enabled } override fun requestLayout() { super.requestLayout() post { measure( MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) ) layout(left, top, right, bottom) } } fun updateConfig(buttonConfig: ReadableMap?) { buttonConfig?.also { config -> val themeStr = config.getNullableString(DataKeys.ThemeKey) ?: DEFAULT_BUTTON_THEME val typeStr = config.getNullableString(DataKeys.TypeKey) ?: DEFAULT_BUTTON_TYPE val cornerRadiusPx = config.getNullableDouble(DataKeys.CornerRadiusKey)?.let { TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, it.toFloat(), reactContext.resources.displayMetrics) } ?: GooglePayButton.defaultCornerRadiusDp.dpToPx() updateButton( GooglePayButtonTheme.convertFrom(themeStr), GooglePayButtonType.convertFrom(typeStr), cornerRadiusPx.toInt() ) return } // Set defaults updateButton( GooglePayButtonTheme.convertFrom(DEFAULT_BUTTON_THEME), GooglePayButtonType.convertFrom(DEFAULT_BUTTON_TYPE), GooglePayButton.defaultCornerRadiusDp.dpToPx().toInt() ) } private fun updateButton( theme: GooglePayButtonTheme, type: GooglePayButtonType, cornerRadius: Int ) { if (_googlePayButtonTheme == theme && _googlePayButtonType == type && _googlePayButtonCornerRadius == cornerRadius ) { //Don't update the button if nothing changed, because it's expensive to do so. However, // we do want to always force a layout pass in case the size changed requestLayout() return } _googlePayButtonTheme = theme _googlePayButtonType = type _googlePayButtonCornerRadius = cornerRadius _button.updateButton(theme, type, cornerRadius) requestLayout() } companion object { const val DEFAULT_BUTTON_THEME = "dark" const val DEFAULT_BUTTON_TYPE = "checkout" const val DEFAULT_CORNER_RADIUS_DP: Float = 8.0f } }