diff --git a/app/src/main/assets/tangem-app-config b/app/src/main/assets/tangem-app-config index 0cf3af21e6..e80938f7d9 160000 --- a/app/src/main/assets/tangem-app-config +++ b/app/src/main/assets/tangem-app-config @@ -1 +1 @@ -Subproject commit 0cf3af21e6f441e6323a1ba127ee7518168797df +Subproject commit e80938f7d9ba378a91ac544a9170597e64afa696 diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Store.kt b/app/src/main/java/com/tangem/tap/common/extensions/Store.kt index 50087bbf93..83aa152f76 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Store.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Store.kt @@ -26,6 +26,10 @@ fun Store<*>.dispatchOpenUrl(url: String) { store.dispatch(NavigationAction.OpenUrl(url)) } +fun Store<*>.dispatchShare(url: String) { + store.dispatch(NavigationAction.Share(url)) +} + fun Store<*>.dispatchNotification(resId: Int) { scope.launch(Dispatchers.Main) { store.dispatch(GlobalAction.ShowNotification(resId)) diff --git a/app/src/main/java/com/tangem/tap/common/redux/StateDialog.kt b/app/src/main/java/com/tangem/tap/common/redux/StateDialog.kt index 4334d55f59..0db3aa9b0a 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/StateDialog.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/StateDialog.kt @@ -13,6 +13,6 @@ sealed class AppDialog : StateDialog { data class AddressInfoDialog( val addressData: AddressData, val onCopyAddress: VoidCallback, - val onExploreAddress: VoidCallback + val onShareAddress: VoidCallback ) : AppDialog() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt index d2147ad3c6..214a034270 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt @@ -15,6 +15,8 @@ sealed class NavigationAction : Action { data class OpenUrl(val url: String) : NavigationAction() + data class Share(val data: String) : NavigationAction() + data class ActivityCreated(val activity: WeakReference) : NavigationAction() object ActivityDestroyed : NavigationAction() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationMiddleware.kt index 31fe730615..e8e0168455 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationMiddleware.kt @@ -3,6 +3,7 @@ package com.tangem.tap.common.redux.navigation import com.tangem.tap.common.CustomTabsManager import com.tangem.tap.common.extensions.openFragment import com.tangem.tap.common.extensions.popBackTo +import com.tangem.tap.common.extensions.shareText import com.tangem.tap.common.redux.AppState import org.rekotlin.Middleware @@ -31,6 +32,11 @@ val navigationMiddleware: Middleware = { dispatch, state -> CustomTabsManager().openUrl(action.url, it) } } + is NavigationAction.Share -> { + navState?.activity?.get()?.let { + it.shareText(action.data) + } + } } } next(action) diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/MoonpayStatus.kt b/app/src/main/java/com/tangem/tap/domain/extensions/MoonpayStatus.kt new file mode 100644 index 0000000000..a07f7698c3 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/extensions/MoonpayStatus.kt @@ -0,0 +1,19 @@ +package com.tangem.tap.domain.extensions + +import com.tangem.blockchain.common.Blockchain +import com.tangem.tap.network.moonpay.MoonpayStatus + +/** +[REDACTED_AUTHOR] + */ +fun MoonpayStatus.buyIsAllowed(blockchain: Blockchain): Boolean { + if (blockchain == Blockchain.Unknown || blockchain == Blockchain.BSC) return false + + return isBuyAllowed && availableToBuy.contains(blockchain.currency) +} + +fun MoonpayStatus.sellIsAllowed(blockchain: Blockchain): Boolean { + if (blockchain == Blockchain.Unknown || blockchain == Blockchain.BSC) return false + + return isSellAllowed && availableToSell.contains(blockchain.currency) +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index 22bbd11511..0f9b8982dc 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -100,7 +100,7 @@ class DetailsMiddleware { store.dispatch(NavigationAction.PopBackTo()) } is DetailsAction.EraseWallet.Confirm -> { - val card = store.state.detailsState.card ?: return + val card = store.state.detailsState.scanResponse?.card ?: return scope.launch { val result = tangemSdkManager.eraseWallet(card) withContext(Dispatchers.Main) { @@ -113,7 +113,7 @@ class DetailsMiddleware { FirebaseAnalyticsHandler.logCardSdkError( error, FirebaseAnalyticsHandler.ActionToLog.PurgeWallet, - card = store.state.detailsState.card + card = store.state.detailsState.scanResponse?.card ) } } @@ -170,7 +170,7 @@ class DetailsMiddleware { } } is DetailsAction.ManageSecurity.SaveChanges -> { - val cardId = store.state.detailsState.card?.cardId + val cardId = store.state.detailsState.scanResponse?.card?.cardId val selectedOption = store.state.detailsState.securityScreenState?.selectedOption scope.launch { val result = when (selectedOption) { @@ -199,7 +199,7 @@ class DetailsMiddleware { FirebaseAnalyticsHandler.AnalyticsParam.NEW_SECURITY_OPTION to (selectedOption?.name ?: "") ), - card = store.state.detailsState.card + card = store.state.detailsState.scanResponse?.card ) } store.dispatch(DetailsAction.ManageSecurity.SaveChanges.Failure) diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index d2622417f7..ca2b6fb4bb 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -41,7 +41,7 @@ private fun internalReduce(action: Action, state: AppState): DetailsState { private fun handlePrepareScreen(action: DetailsAction.PrepareScreen, state: DetailsState): DetailsState { return DetailsState( - card = action.scanResponse.card, + scanResponse = action.scanResponse, wallets = action.wallets, cardInfo = action.scanResponse.card.toCardInfo(), appCurrencyState = AppCurrencyState(action.fiatCurrencyName), @@ -52,8 +52,10 @@ private fun handlePrepareScreen(action: DetailsAction.PrepareScreen, state: Deta private fun handleEraseWallet(action: DetailsAction.EraseWallet, state: DetailsState): DetailsState { return when (action) { DetailsAction.EraseWallet.Check -> { - val notAllowedByAnyWallet = state.card?.wallets?.any { it.settings.isPermanent } ?: false - val notAllowedByCard = notAllowedByAnyWallet || state.card?.isWalletDataSupported == true + val card = state.scanResponse?.card + val notAllowedByAnyWallet = card?.wallets?.any { it.settings.isPermanent } ?: false + val notAllowedByCard = notAllowedByAnyWallet || + (card?.isWalletDataSupported == true && !state.scanResponse.isTangemNote()) val notEmpty = state.wallets.any { it.hasPendingTransactions() || it.amounts.toSendableAmounts().isNotEmpty() } @@ -121,7 +123,9 @@ private fun handleSecurityAction( state.copy(securityScreenState = SecurityScreenState(currentOption = securityOption)) } is DetailsAction.ManageSecurity.OpenSecurity -> { - if (state.card?.isStart2Coin == true) { + if (state.scanResponse?.card?.isStart2Coin == true || + state.scanResponse?.isTangemNote() == true + ) { return state.copy(securityScreenState = state.securityScreenState?.copy( allowedOptions = EnumSet.of(SecurityOption.LongTap), selectedOption = state.securityScreenState.currentOption @@ -129,7 +133,7 @@ private fun handleSecurityAction( } val allowedSecurityOptions = prepareAllowedSecurityOptions( - state.card, state.securityScreenState?.currentOption + state.scanResponse?.card, state.securityScreenState?.currentOption ) state.copy(securityScreenState = state.securityScreenState?.copy( allowedOptions = allowedSecurityOptions, @@ -154,7 +158,7 @@ private fun handleSecurityAction( state.copy( securityScreenState = state.securityScreenState?.copy( currentOption = state.securityScreenState.selectedOption, - allowedOptions = state.card?.let { + allowedOptions = state.scanResponse?.card?.let { prepareAllowedSecurityOptions( it, state.securityScreenState.selectedOption ) @@ -189,7 +193,7 @@ private fun prepareAllowedSecurityOptions( } -private fun Card.toCardInfo(): CardInfo? { +private fun Card.toCardInfo(): CardInfo { val cardId = this.cardId.chunked(4).joinToString(separator = " ") val issuer = this.issuer.name val signedHashes = this.signedHashesCount() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt index 40f409c680..cad9493b63 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt @@ -2,10 +2,10 @@ package com.tangem.tap.features.details.redux import android.net.Uri import com.tangem.blockchain.common.Wallet -import com.tangem.common.card.Card import com.tangem.tap.common.entities.Button import com.tangem.tap.common.entities.TapCurrency.Companion.DEFAULT_FIAT_CURRENCY import com.tangem.tap.common.redux.global.FiatCurrencyName +import com.tangem.tap.domain.tasks.product.ScanResponse import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.network.coinmarketcap.FiatCurrency import com.tangem.tap.store @@ -14,7 +14,7 @@ import java.util.* import kotlin.properties.ReadOnlyProperty data class DetailsState( - val card: Card? = null, + val scanResponse: ScanResponse? = null, val wallets: List = emptyList(), val cardInfo: CardInfo? = null, val appCurrencyState: AppCurrencyState = AppCurrencyState(), diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt index ac9be2e1a0..6f7eb15b43 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt @@ -67,7 +67,7 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber { thisRef, property -> - store.state.globalState.moonpayStatus?.canBuy(walletBalance) ?: false + store.state.globalState.moonpayStatus?.buyIsAllowed(walletBalance.currency.blockchain) ?: false } } -fun MoonpayStatus.canBuy(walletBalance: OnboardingWalletBalance): Boolean { - if (walletBalance.currency.blockchain == Blockchain.Unknown) return false - - return isBuyAllowed && availableToBuy.contains(walletBalance.currency.currencySymbol) -} - enum class OnboardingNoteStep { None, CreateWallet, TopUpWallet, Done } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt index 761fee04ea..6986100a02 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt @@ -243,7 +243,7 @@ private fun handle(action: Action, dispatch: DispatchFunction) { val appDialog = AppDialog.AddressInfoDialog( addressData, onCopyAddress = { store.dispatchToastNotification(addressWasCopied) }, - onExploreAddress = { store.dispatchOpenUrl(addressData.exploreUrl) } + onShareAddress = { store.dispatchShare(addressData.shareUrl) } ) store.dispatchDialogShow(appDialog) } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt index 6f7d27ec14..a041508dc0 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt @@ -2,10 +2,10 @@ package com.tangem.tap.features.onboarding.products.twins.redux import com.tangem.blockchain.common.WalletManager import com.tangem.tap.domain.TapError +import com.tangem.tap.domain.extensions.buyIsAllowed import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.domain.twins.TwinCardsManager import com.tangem.tap.features.onboarding.OnboardingWalletBalance -import com.tangem.tap.features.onboarding.products.note.redux.canBuy import com.tangem.tap.store import org.rekotlin.StateType import kotlin.properties.ReadOnlyProperty @@ -57,7 +57,7 @@ data class TwinCardsState( get() = currentStep == TwinCardsStep.CreateSecondWallet || currentStep == TwinCardsStep.CreateThirdWallet val isBuyAllowed: Boolean by ReadOnlyProperty { thisRef, property -> - store.state.globalState.moonpayStatus?.canBuy(walletBalance) ?: false + store.state.globalState.moonpayStatus?.buyIsAllowed(walletBalance.currency.blockchain) ?: false } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 042192ae8f..0c0892b176 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -10,6 +10,8 @@ import com.tangem.tap.common.redux.StateDialog import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.tap.common.toggleWidget.WidgetState import com.tangem.tap.domain.configurable.warningMessage.WarningMessage +import com.tangem.tap.domain.extensions.buyIsAllowed +import com.tangem.tap.domain.extensions.sellIsAllowed import com.tangem.tap.domain.extensions.toSendableAmounts import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.features.wallet.models.PendingTransaction @@ -17,6 +19,7 @@ import com.tangem.tap.features.wallet.models.toPendingTransactions import com.tangem.tap.features.wallet.models.toPendingTransactionsForToken import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData +import com.tangem.tap.network.moonpay.MoonpayStatus import com.tangem.tap.store import org.rekotlin.StateType import java.math.BigDecimal @@ -144,9 +147,9 @@ data class WalletState( fun replaceSomeWallets(newWallets: List): List { val remainingWallets: MutableList = newWallets.toMutableList() - val updatedWallets = wallets.map { wallet -> + val updatedWallets = wallets.map { wallet -> val newWallet = newWallets - .firstOrNull { wallet.currencyData.currency == it.currencyData.currency } + .firstOrNull { wallet.currencyData.currency == it.currencyData.currency } if (newWallet == null) { wallet } else { @@ -217,7 +220,16 @@ data class Artwork( data class TradeCryptoState( val sellingAllowed: Boolean = false, val buyingAllowed: Boolean = false, -) +) { + companion object { + fun from(moonpayStatus: MoonpayStatus?, walletData: WalletData): TradeCryptoState { + val status = moonpayStatus ?: return walletData.tradeCryptoState + val blockchain = walletData.currency?.blockchain ?: return walletData.tradeCryptoState + + return TradeCryptoState(status.sellIsAllowed(blockchain), status.buyIsAllowed(blockchain)) + } + } +} data class WalletData( val pendingTransactions: List = emptyList(), diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 376a38136b..f4188096f4 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -21,6 +21,8 @@ import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.send.redux.PrepareSendScreen import com.tangem.tap.features.wallet.redux.* import com.tangem.tap.network.NetworkStateChanged +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll import kotlinx.coroutines.launch import org.rekotlin.Action import org.rekotlin.DispatchFunction @@ -51,9 +53,9 @@ class WalletMiddleware { is WalletAction.LoadWallet -> { scope.launch { if (action.blockchain == null) { - walletState.walletManagers.map { walletManager -> - globalState.tapWalletManager.loadWalletData(walletManager) - } + walletState.walletManagers.map { walletManager -> + async { globalState.tapWalletManager.loadWalletData(walletManager) } + }.awaitAll() } else { val walletManager = walletState.getWalletManager(action.blockchain) walletManager?.let { globalState.tapWalletManager.loadWalletData(it) } @@ -108,7 +110,7 @@ class WalletMiddleware { FirebaseAnalyticsHandler.logCardSdkError( error, FirebaseAnalyticsHandler.ActionToLog.CreateWallet, - card = store.state.detailsState.card + card = store.state.detailsState.scanResponse?.card ) } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index bff0032c0f..ff5f728052 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -95,14 +95,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState { currencySymbol = wallet.currencyData.currencySymbol, ), mainButton = WalletMainButton.SendButton(false), - tradeCryptoState = TradeCryptoState( - sellingAllowed = action.moonpayStatus?.availableToSell?.contains( - wallet.currencyData.currencySymbol - ) ?: wallet.tradeCryptoState.sellingAllowed, - buyingAllowed = action.moonpayStatus?.availableToBuy?.contains( - wallet.currencyData.currencySymbol - ) ?: wallet.tradeCryptoState.buyingAllowed - ) + tradeCryptoState = TradeCryptoState.from(action.moonpayStatus, wallet) ) } newState = newState.copy( @@ -123,14 +116,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState { currencySymbol = wallet.currencyData.currencySymbol, ), mainButton = WalletMainButton.SendButton(false), - tradeCryptoState = TradeCryptoState( - sellingAllowed = action.moonpayStatus?.availableToSell?.contains( - wallet.currencyData.currencySymbol - ) ?: wallet.tradeCryptoState.sellingAllowed, - buyingAllowed = action.moonpayStatus?.availableToBuy?.contains( - wallet.currencyData.currencySymbol - ) ?: wallet.tradeCryptoState.buyingAllowed - ) + tradeCryptoState = TradeCryptoState.from(action.moonpayStatus, wallet) ) } val wallets = newState.replaceSomeWallets(newWallets) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/MultipleAddressUiHelper.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/MultipleAddressUiHelper.kt index 66425c74a7..ecbad2650a 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/MultipleAddressUiHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/MultipleAddressUiHelper.kt @@ -23,14 +23,14 @@ class MultipleAddressUiHelper { return when (id) { R.id.chip_default -> { when (blockchain) { - Blockchain.Bitcoin, Blockchain.BitcoinTestnet -> BitcoinAddressType.Segwit + Blockchain.Bitcoin, Blockchain.BitcoinTestnet, Blockchain.Litecoin -> BitcoinAddressType.Segwit Blockchain.CardanoShelley -> CardanoAddressType.Shelley else -> null } } R.id.chip_legacy -> { when (blockchain) { - Blockchain.Bitcoin, Blockchain.BitcoinTestnet -> BitcoinAddressType.Legacy + Blockchain.Bitcoin, Blockchain.BitcoinTestnet, Blockchain.Litecoin -> BitcoinAddressType.Legacy Blockchain.CardanoShelley -> CardanoAddressType.Byron else -> null } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index 874c3abfec..08e1b03466 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -164,11 +164,11 @@ class SingleWalletView : WalletView { allowedToBuy && !allowedToSell -> R.drawable.ic_arrow_up_short_btn !allowedToBuy && allowedToSell -> R.drawable.ic_arrow_down_short_button allowedToBuy && allowedToSell -> R.drawable.ic_arrows_up_down_short_btn - else -> R.string.wallet_button_trade + else -> null } with(fragment) { btn_trade.text = getText(text) - btn_trade.setCompoundDrawablesWithIntrinsicBounds(0, icon, 0, 0) + btn_trade.setCompoundDrawablesWithIntrinsicBounds(0, icon ?: 0, 0, 0) btn_trade.setOnClickListener { if (action != null) store.dispatch(action) } } } diff --git a/app/src/main/res/color/menu_item_color.xml b/app/src/main/res/color/menu_item_color.xml index f8d7307051..2b59ebcebe 100644 --- a/app/src/main/res/color/menu_item_color.xml +++ b/app/src/main/res/color/menu_item_color.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_onboarding_address_info.xml b/app/src/main/res/layout/dialog_onboarding_address_info.xml index a3c34a8f06..5259725069 100644 --- a/app/src/main/res/layout/dialog_onboarding_address_info.xml +++ b/app/src/main/res/layout/dialog_onboarding_address_info.xml @@ -53,7 +53,7 @@ android:backgroundTint="@color/lightGray0" android:paddingStart="16dp" android:paddingEnd="16dp" - app:layout_constraintEnd_toStartOf="@+id/btn_fl_explore" + app:layout_constraintEnd_toStartOf="@+id/btn_fl_share" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline3"> @@ -90,7 +90,7 @@