Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-30 12:06:31 +04:00
parent 2105360004
commit d76fcd143c
24 changed files with 645 additions and 5 deletions

View file

@ -67,6 +67,10 @@ class DefaultTangemPayDetailsContainerComponent @AssistedInject constructor(
TangemPayDetailsInnerRoute.ChangePINSuccess -> TangemPayChangePinSuccessComponent(
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
)
TangemPayDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent(
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
params = params,
)
}
private fun onChildBack() {

View file

@ -0,0 +1,38 @@
package com.tangem.features.tangempay.components
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.child
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.tangempay.components.cardDetails.DefaultTangemPayCardDetailsBlockComponent
import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent
import com.tangem.features.tangempay.model.TangemPayAddToWalletModel
import com.tangem.features.tangempay.ui.TangemPayAddToWalletScreen
internal class TangemPayAddToWalletComponent(
private val appComponentContext: AppComponentContext,
private val params: TangemPayDetailsContainerComponent.Params,
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val model: TangemPayAddToWalletModel = getOrCreateModel()
private val cardDetailsBlockComponent = DefaultTangemPayCardDetailsBlockComponent(
appComponentContext = child("cardDetailsBlockComponent"),
params = TangemPayCardDetailsBlockComponent.Params(params = params),
)
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
BackHandler(onBack = router::pop)
TangemPayAddToWalletScreen(
state = state,
cardDetailsBlockComponent = cardDetailsBlockComponent,
)
}
}

View file

@ -2,6 +2,7 @@ package com.tangem.features.tangempay.di
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.tangempay.model.TangemPayAddToWalletModel
import com.tangem.features.tangempay.model.TangemPayCardDetailsBlockModel
import com.tangem.features.tangempay.model.TangemPayChangePinModel
import com.tangem.features.tangempay.model.TangemPayDetailsModel
@ -41,4 +42,9 @@ internal interface TangemPayModelModule {
@IntoMap
@ClassKey(TangemPayCardDetailsBlockModel::class)
fun bindTangemPayCardDetailsBlockModel(model: TangemPayCardDetailsBlockModel): Model
@Binds
@IntoMap
@ClassKey(TangemPayAddToWalletModel::class)
fun bindTangemPayAddToWalletModel(model: TangemPayAddToWalletModel): Model
}

View file

@ -0,0 +1,16 @@
package com.tangem.features.tangempay.entity
import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
internal data class TangemPayAddToWalletUM(
val steps: ImmutableList<TangemPayAddToWalletStepItemUM>,
val showAddToWalletButton: Boolean,
val onBackClick: () -> Unit,
val onClickOpenWallet: () -> Unit,
)
internal data class TangemPayAddToWalletStepItemUM(
val count: Int,
val text: TextReference,
)

View file

@ -45,6 +45,7 @@ internal class TangemPayDetailsStateFactory(
),
),
),
addToWalletBlockState = null,
isBalanceHidden = false,
)
}

View file

@ -9,6 +9,7 @@ internal data class TangemPayDetailsUM(
val topBarConfig: TangemPayDetailsTopBarConfig,
val pullToRefreshConfig: PullToRefreshConfig,
val balanceBlockState: TangemPayDetailsBalanceBlockState,
val addToWalletBlockState: AddToWalletBlockState?,
val isBalanceHidden: Boolean,
)
@ -41,4 +42,9 @@ internal sealed class TangemPayDetailsBalanceBlockState {
data class Error(
override val actionButtons: ImmutableList<ActionButtonConfig>,
) : TangemPayDetailsBalanceBlockState()
}
}
internal data class AddToWalletBlockState(
val onClick: () -> Unit,
val onClickClose: () -> Unit,
)

View file

@ -0,0 +1,59 @@
package com.tangem.features.tangempay.model
import androidx.compose.runtime.Stable
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM
import com.tangem.features.tangempay.entity.TangemPayAddToWalletUM
import com.tangem.features.tangempay.utils.GoogleWalletUtil
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
@Stable
@ModelScoped
internal class TangemPayAddToWalletModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val router: Router,
private val googleWalletUtil: GoogleWalletUtil,
) : Model() {
val uiState: StateFlow<TangemPayAddToWalletUM>
field = MutableStateFlow(getInitialState())
@Suppress("MagicNumber")
private fun getInitialState(): TangemPayAddToWalletUM {
return TangemPayAddToWalletUM(
steps = persistentListOf(
TangemPayAddToWalletStepItemUM(
count = 1,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_1),
),
TangemPayAddToWalletStepItemUM(
count = 2,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_2),
),
TangemPayAddToWalletStepItemUM(
count = 3,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_3),
),
TangemPayAddToWalletStepItemUM(
count = 4,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_4),
),
TangemPayAddToWalletStepItemUM(
count = 5,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_5),
),
),
showAddToWalletButton = googleWalletUtil.isWalletAvailable(),
onBackClick = router::pop,
onClickOpenWallet = googleWalletUtil::openWallet,
)
}
}

View file

@ -20,6 +20,7 @@ import com.tangem.features.tangempay.entity.TangemPayDetailsStateFactory
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
import com.tangem.features.tangempay.model.listener.CardDetailsEvent
import com.tangem.features.tangempay.model.listener.CardDetailsEventListener
import com.tangem.features.tangempay.model.transformers.DetailsAddToWalletBannerTransformer
import com.tangem.features.tangempay.model.transformers.DetailsBalanceTransformer
import com.tangem.features.tangempay.model.transformers.TangemPayDetailsRefreshTransformer
import com.tangem.features.tangempay.navigation.TangemPayDetailsInnerRoute
@ -63,10 +64,12 @@ internal class TangemPayDetailsModel @Inject constructor(
private val refreshStateJobHolder = JobHolder()
private val fetchBalanceJobHolder = JobHolder()
private val addToWalletBannerJobHolder = JobHolder()
val bottomSheetNavigation: SlotNavigation<TangemPayDetailsNavigation> = SlotNavigation()
init {
fetchAddToWalletBanner()
fetchBalance()
}
@ -105,6 +108,19 @@ internal class TangemPayDetailsModel @Inject constructor(
}.saveIn(fetchBalanceJobHolder)
}
private fun fetchAddToWalletBanner() {
modelScope.launch {
val isDone = cardDetailsRepository.isAddToWalletDone().getOrNull() ?: false
uiState.update(
transformer = DetailsAddToWalletBannerTransformer(
onClickBanner = ::onClickAddToWalletBlock,
onClickCloseBanner = ::onClickCloseAddToWalletBlock,
isDone = isDone,
),
)
}.saveIn(addToWalletBannerJobHolder)
}
private fun onRefreshSwipe(refreshState: ShowRefreshState) {
modelScope.launch {
cardDetailsEventListener.send(CardDetailsEvent.Hide)
@ -114,6 +130,23 @@ internal class TangemPayDetailsModel @Inject constructor(
}.saveIn(refreshStateJobHolder)
}
private fun onClickAddToWalletBlock() {
router.push(TangemPayDetailsInnerRoute.AddToWallet)
}
private fun onClickCloseAddToWalletBlock() {
modelScope.launch {
cardDetailsRepository.setAddToWalletAsDone()
uiState.update(
transformer = DetailsAddToWalletBannerTransformer(
onClickBanner = ::onClickAddToWalletBlock,
onClickCloseBanner = ::onClickCloseAddToWalletBlock,
isDone = true,
),
)
}.saveIn(addToWalletBannerJobHolder)
}
override fun onTransactionClick(item: TangemPayTxHistoryItem) {
bottomSheetNavigation.activate(TangemPayDetailsNavigation.TransactionDetails(item))
}

View file

@ -0,0 +1,22 @@
package com.tangem.features.tangempay.model.transformers
import com.tangem.features.tangempay.entity.AddToWalletBlockState
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
import com.tangem.utils.transformer.Transformer
internal class DetailsAddToWalletBannerTransformer(
private val onClickBanner: () -> Unit,
private val onClickCloseBanner: () -> Unit,
private val isDone: Boolean,
) : Transformer<TangemPayDetailsUM> {
override fun transform(prevState: TangemPayDetailsUM): TangemPayDetailsUM {
return prevState.copy(
addToWalletBlockState = if (isDone) {
null
} else {
AddToWalletBlockState(onClick = onClickBanner, onClickClose = onClickCloseBanner)
},
)
}
}

View file

@ -13,4 +13,7 @@ internal sealed class TangemPayDetailsInnerRoute : Route {
@Serializable
data object ChangePINSuccess : TangemPayDetailsInnerRoute()
@Serializable
data object AddToWallet : TangemPayDetailsInnerRoute()
}

View file

@ -0,0 +1,107 @@
package com.tangem.features.tangempay.ui
import android.content.res.Configuration
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.AddToWalletBlockState
private const val GRADIENT_START_COLOR = 0xFF252934
private const val GRADIENT_END_COLOR = 0xFF12141E
private const val GRADIENT_OFFSET_X = 0f
private const val GRADIENT_OFFSET_Y = 80F
private const val GRADIENT_RADIUS = 200F
@Composable
internal fun TangemPayAddToWalletBlock(state: AddToWalletBlockState, modifier: Modifier = Modifier) {
Box(
modifier = modifier
.fillMaxWidth()
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(
brush = Brush.radialGradient(
colors = listOf(Color(GRADIENT_START_COLOR), Color(GRADIENT_END_COLOR)),
center = Offset(GRADIENT_OFFSET_X, GRADIENT_OFFSET_Y),
radius = GRADIENT_RADIUS,
),
)
.clickable(onClick = state.onClick),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(IntrinsicSize.Min)
.padding(horizontal = 16.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Image(
painter = painterResource(R.drawable.img_google_wallet_48),
contentDescription = null,
modifier = Modifier.size(36.dp).clip(CircleShape),
)
Spacer(Modifier.width(12.dp))
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.Center,
) {
Text(
text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_notification_title),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.constantWhite,
)
Spacer(Modifier.height(6.dp))
Text(
text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_notification_subtitle),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
}
Box(
modifier = Modifier.fillMaxHeight(),
contentAlignment = Alignment.TopEnd,
) {
Image(
modifier = Modifier
.clip(TangemTheme.shapes.roundedCornersXMedium)
.clickable(onClick = state.onClickClose)
.padding(4.dp)
.size(12.dp),
painter = painterResource(id = R.drawable.ic_close_24),
colorFilter = ColorFilter.tint(TangemTheme.colors.icon.inactive),
contentDescription = null,
)
}
}
}
}
@Preview(showBackground = true)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PreviewTangemPayAddToWalletBlock() {
TangemThemePreview {
TangemPayAddToWalletBlock(AddToWalletBlockState({}, {}))
}
}

View file

@ -0,0 +1,192 @@
package com.tangem.features.tangempay.ui
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.tangempay.components.cardDetails.PreviewTangemPayCardDetailsBlockComponent
import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM
import com.tangem.features.tangempay.entity.TangemPayAddToWalletUM
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
import kotlinx.collections.immutable.persistentListOf
@Composable
internal fun TangemPayAddToWalletScreen(
state: TangemPayAddToWalletUM,
cardDetailsBlockComponent: TangemPayCardDetailsBlockComponent,
modifier: Modifier = Modifier,
) {
val listState = rememberLazyListState()
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
val cardDetailsState by cardDetailsBlockComponent.state.collectAsStateWithLifecycle()
Column(
modifier = modifier
.fillMaxSize()
.navigationBarsPadding(),
) {
AppBarWithBackButton(
modifier = Modifier.statusBarsPadding(),
iconRes = R.drawable.ic_close_24,
onBackClick = state.onBackClick,
)
LazyColumn(
modifier = Modifier
.fillMaxSize()
.weight(1f),
state = listState,
contentPadding = PaddingValues(bottom = TangemTheme.dimens.spacing16 + bottomBarHeight),
) {
item(key = TangemPayCardDetailsUM::class.java) {
TangemPayCardDetailsBlockItem(component = cardDetailsBlockComponent, state = cardDetailsState)
}
item(key = TangemPayAddToWalletUM::class.java) {
Text(
modifier = Modifier
.padding(horizontal = 16.dp, vertical = 24.dp)
.fillMaxWidth(),
text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
)
}
itemsIndexed(
items = state.steps,
key = { _, step -> "${TangemPayAddToWalletStepItemUM::class.java}${step.count}" },
) { idx, step ->
StepItem(
modifier = Modifier.padding(bottom = if (idx < state.steps.lastIndex) 16.dp else 0.dp),
stepNumber = step.count,
title = step.text,
)
}
}
SecondaryButton(
modifier = Modifier
.imePadding()
.padding(start = 16.dp, end = 16.dp, bottom = 8.dp)
.fillMaxWidth(),
text = resourceReference(R.string.common_got_it).resolveReference(),
onClick = state.onBackClick,
)
if (state.showAddToWalletButton) {
PrimaryButton(
modifier = Modifier
.imePadding()
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.fillMaxWidth(),
text = resourceReference(R.string.tangempay_card_details_open_wallet_button).resolveReference(),
onClick = state.onClickOpenWallet,
)
}
}
}
@Composable
private fun StepItem(stepNumber: Int, title: TextReference, modifier: Modifier = Modifier) {
Row(
modifier = modifier
.background(color = Color.Transparent, shape = TangemTheme.shapes.roundedCorners8)
.padding(horizontal = 24.dp),
verticalAlignment = Alignment.Top,
) {
Box(
modifier = Modifier
.size(24.dp)
.background(color = TangemColorPalette.Azure, shape = CircleShape),
contentAlignment = Alignment.Center,
) {
Text(
text = stepNumber.toString(),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.primary2,
)
}
Spacer(modifier = Modifier.width(12.dp))
Text(
text = title.resolveReference(),
style = TangemTheme.typography.subtitle1,
color = TangemTheme.colors.text.primary1,
)
}
}
@Preview(showBackground = true)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PreviewTangemPayAddToWalletScreen() {
TangemThemePreview {
TangemPayAddToWalletScreen(
state = TangemPayAddToWalletUM(
steps = persistentListOf(
TangemPayAddToWalletStepItemUM(
count = 1,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_1),
),
TangemPayAddToWalletStepItemUM(
count = 2,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_2),
),
TangemPayAddToWalletStepItemUM(
count = 3,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_3),
),
TangemPayAddToWalletStepItemUM(
count = 4,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_4),
),
TangemPayAddToWalletStepItemUM(
count = 5,
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_5),
),
),
showAddToWalletButton = true,
onBackClick = {},
onClickOpenWallet = {},
),
cardDetailsBlockComponent = PreviewTangemPayCardDetailsBlockComponent(
TangemPayCardDetailsUM(
number = "•••• •••• •••• 1245",
expiry = "••/••",
cvv = "•••",
onCopy = {},
onClick = {},
buttonText = TextReference.Res(R.string.tangempay_card_details_hide_text),
),
),
)
}
}

View file

@ -0,0 +1,15 @@
package com.tangem.features.tangempay.ui
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
@Composable
internal fun TangemPayCardDetailsBlockItem(
component: TangemPayCardDetailsBlockComponent,
state: TangemPayCardDetailsUM,
modifier: Modifier = Modifier,
) {
component.CardDetailsBlockContent(state = state, modifier = modifier)
}

View file

@ -90,10 +90,21 @@ internal fun TangemPayDetailsScreen(
)
},
)
with(cardDetailsBlockComponent) {
item(TangemPayCardDetailsUM::class.java) {
CardDetailsBlockContent(state = cardDetailsState)
}
if (state.addToWalletBlockState != null) {
item(
key = AddToWalletBlockState::class.java,
content = {
TangemPayAddToWalletBlock(
state = state.addToWalletBlockState,
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing12)
.padding(horizontal = TangemTheme.dimens.spacing16),
)
},
)
}
item(TangemPayCardDetailsUM::class.java) {
TangemPayCardDetailsBlockItem(component = cardDetailsBlockComponent, state = cardDetailsState)
}
with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryState) }
}
@ -300,12 +311,14 @@ private class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<Ta
fiatBalance = "$1234.56",
isBalanceFlickering = false,
),
addToWalletBlockState = AddToWalletBlockState({}, {}),
isBalanceHidden = false,
),
TangemPayDetailsUM(
topBarConfig = TangemPayDetailsTopBarConfig(onBackClick = {}, items = null),
pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}),
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(actionButtons = persistentListOf()),
addToWalletBlockState = AddToWalletBlockState({}, {}),
isBalanceHidden = false,
),
),

View file

@ -0,0 +1,40 @@
package com.tangem.features.tangempay.utils
import android.content.Context
import android.content.Intent
import dagger.hilt.android.qualifiers.ApplicationContext
import timber.log.Timber
import javax.inject.Inject
private const val TAG = "GoogleWalletUtil"
private const val WALLET_PACKAGE_NAME = "com.google.android.apps.walletnfcrel"
internal class GoogleWalletUtil @Inject constructor(
@ApplicationContext private val context: Context,
) {
private var walletIntent: Intent? = null
fun isWalletAvailable(): Boolean = getWalletIntent() != null
fun openWallet() {
val intent = getWalletIntent()
if (intent != null) {
context.startActivity(intent)
}
}
private fun getWalletIntent(): Intent? {
return if (walletIntent != null) {
walletIntent
} else {
try {
context.packageManager.getLaunchIntentForPackage(WALLET_PACKAGE_NAME)
?.apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
.also { walletIntent = it }
} catch (exception: Exception) {
Timber.tag(TAG).e(exception)
null
}
}
}
}

View file

@ -0,0 +1,25 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:pathData="M24,0L24,0A24,24 0,0 1,48 24L48,24A24,24 0,0 1,24 48L24,48A24,24 0,0 1,0 24L0,24A24,24 0,0 1,24 0z"
android:fillColor="#393C45"/>
<path
android:pathData="M34.092,21.69V18.629C34.092,16.861 32.652,15.42 30.884,15.42H17.116C15.348,15.436 13.907,16.877 13.907,18.629V21.69C13.907,22.001 14.153,22.247 14.464,22.247H33.536C33.847,22.247 34.092,22.001 34.092,21.69Z"
android:fillColor="#34A853"
android:fillType="evenOdd"/>
<path
android:pathData="M34.092,24.375V21.33C34.092,19.562 32.652,18.121 30.884,18.121H17.116C15.348,18.121 13.907,19.562 13.907,21.33V24.391C13.907,24.702 14.153,24.948 14.464,24.948H33.536C33.847,24.931 34.092,24.686 34.092,24.375Z"
android:fillColor="#FBBC04"
android:fillType="evenOdd"/>
<path
android:pathData="M34.092,27.077V24.015C34.092,22.247 32.652,20.807 30.884,20.807H17.116C15.348,20.807 13.907,22.247 13.907,24.015V27.077C13.907,27.388 14.153,27.633 14.464,27.633H33.536C33.847,27.617 34.092,27.371 34.092,27.077Z"
android:fillColor="#EA4335"
android:fillType="evenOdd"/>
<path
android:pathData="M26.742,25.603L13.907,22.623V29.368C13.907,31.136 15.348,32.576 17.116,32.576H30.884C32.652,32.576 34.092,31.136 34.092,29.368V22.492L31.031,24.719C29.787,25.619 28.232,25.946 26.742,25.603Z"
android:fillColor="#4285F4"
android:fillType="evenOdd"/>
</vector>