Updated on 2026-08-14

This commit is contained in:
Tangem 2022-11-19 17:48:54 +03:00
commit 009575eaa7
18 changed files with 542 additions and 145 deletions

View file

@ -111,6 +111,7 @@ dependencies {
implementation(project(":common"))
implementation(project(":core:ui"))
implementation(project(":libs:crypto"))
implementation(project(":features:referral:presentation"))
/** AndroidX libraries */
implementation(AndroidX.coreKtx)
@ -144,7 +145,7 @@ dependencies {
/** DI */
implementation(Library.hilt)
implementation(Library.hiltKapt)
kapt(Library.hiltKapt)
/** Other libraries */
implementation(Library.materialComponent)

View file

@ -30,6 +30,7 @@ import com.tangem.tap.domain.TangemSdkManager
import com.tangem.tap.features.shop.redux.ShopAction
import com.tangem.wallet.R
import com.tangem.wallet.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -49,6 +50,7 @@ private val mainCoroutineContext: CoroutineContext
get() = Job() + Dispatchers.Main + FeatureCoroutineExceptionHandler.create("mainScope")
val mainScope = CoroutineScope(mainCoroutineContext)
@AndroidEntryPoint
class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbackHolder {
private var snackbar: Snackbar? = null

View file

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,8C13.1,8 14,7.1 14,6C14,4.9 13.1,4 12,4C10.9,4 10,4.9 10,6C10,7.1 10.9,8 12,8ZM12,10C10.9,10 10,10.9 10,12C10,13.1 10.9,14 12,14C13.1,14 14,13.1 14,12C14,10.9 13.1,10 12,10ZM12,16C10.9,16 10,16.9 10,18C10,19.1 10.9,20 12,20C13.1,20 14,19.1 14,18C14,16.9 13.1,16 12,16Z"
android:fillColor="#000"
android:fillType="evenOdd" />
</vector>

View file

@ -2,9 +2,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/details_menu"
android:title="@string/details_title"
android:icon="@drawable/ic_more_vertical_24"
app:iconTint="@color/darkGray6"
app:showAsAction="ifRoom" />
android:id="@+id/details_menu"
android:title="@string/details_title"
android:icon="@drawable/ic_more_vertical"
app:iconTint="@color/darkGray6"
app:showAsAction="ifRoom" />
</menu>

View file

@ -35,4 +35,7 @@ dependencies {
implementation(Compose.foundation)
implementation(Compose.material)
implementation(Compose.uiTooling)
/** Other libraries */
implementation(Library.accompanistSystemUiController)
}

View file

@ -0,0 +1,169 @@
package com.tangem.core.ui.components.appbar
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.components.appbar.models.AdditionalButton
import com.tangem.core.ui.res.IconColorType
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TextColorType
import com.tangem.core.ui.res.iconColor
import com.tangem.core.ui.res.textColor
/**
* App bar with title and two additional buttons
*
* @param startButton button information attached to the left edge
* @param endButton button information attached to the right edge
*
* @see <a href = "https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?node-id=50%3A403&t=tRQ4KlzkjV7TCLZl-4">
* Figma Component</a>
*/
@Composable
fun AppBarWithAdditionalButtons(
text: String,
startButton: AdditionalButton? = null,
endButton: AdditionalButton? = null,
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(dimensionResource(id = R.dimen.size56))
.padding(all = dimensionResource(id = R.dimen.spacing16)),
) {
if (startButton != null) {
IconButton(modifier = Modifier.align(Alignment.CenterStart), onClick = startButton.onIconClicked) {
Icon(
painter = painterResource(id = startButton.iconRes),
contentDescription = null,
modifier = Modifier.size(dimensionResource(id = R.dimen.size24)),
tint = MaterialTheme.colors.iconColor(type = IconColorType.PRIMARY1),
)
}
}
Text(
text = text,
modifier = Modifier.align(Alignment.Center),
color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1),
maxLines = 1,
style = MaterialTheme.typography.subtitle1,
)
if (endButton != null) {
IconButton(modifier = Modifier.align(Alignment.CenterEnd), onClick = endButton.onIconClicked) {
Icon(
painter = painterResource(id = endButton.iconRes),
contentDescription = null,
modifier = Modifier.size(dimensionResource(id = R.dimen.size24)),
tint = MaterialTheme.colors.iconColor(type = IconColorType.PRIMARY1),
)
}
}
}
}
@Preview(widthDp = 360, heightDp = 56, showBackground = true)
@Composable
fun Preview_AppBarWithAdditionalButtons_InLightTheme() {
TangemTheme(isDarkTheme = false) {
AppBarWithAdditionalButtons(
text = "Tangem",
startButton = AdditionalButton(
iconRes = R.drawable.ic_scan,
onIconClicked = {},
),
endButton = AdditionalButton(
iconRes = R.drawable.ic_more_vertical,
onIconClicked = {},
),
)
}
}
@Preview(widthDp = 360, heightDp = 56, showBackground = true)
@Composable
fun Preview_AppBarWithAdditionalButtons_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
AppBarWithAdditionalButtons(
text = "Tangem",
startButton = AdditionalButton(
iconRes = R.drawable.ic_scan,
onIconClicked = {},
),
endButton = AdditionalButton(
iconRes = R.drawable.ic_more_vertical,
onIconClicked = {},
),
)
}
}
@Preview(widthDp = 360, heightDp = 56, showBackground = true)
@Composable
fun Preview_AppBarWithOnlyStartButtons_InLightTheme() {
TangemTheme(isDarkTheme = false) {
AppBarWithAdditionalButtons(
text = "Tangem",
startButton = AdditionalButton(
iconRes = R.drawable.ic_scan,
onIconClicked = {},
),
)
}
}
@Preview(widthDp = 360, heightDp = 56, showBackground = true)
@Composable
fun Preview_AppBarWithOnlyStartButtons_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
AppBarWithAdditionalButtons(
text = "Tangem",
startButton = AdditionalButton(
iconRes = R.drawable.ic_scan,
onIconClicked = {},
),
)
}
}
@Preview(widthDp = 360, heightDp = 56, showBackground = true)
@Composable
fun Preview_AppBarWithOnlyEndButtons_InLightTheme() {
TangemTheme(isDarkTheme = false) {
AppBarWithAdditionalButtons(
text = "Tangem",
endButton = AdditionalButton(
iconRes = R.drawable.ic_more_vertical,
onIconClicked = {},
),
)
}
}
@Preview(widthDp = 360, heightDp = 56, showBackground = true)
@Composable
fun Preview_AppBarWithOnlyEndButtons_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
AppBarWithAdditionalButtons(
text = "Tangem",
endButton = AdditionalButton(
iconRes = R.drawable.ic_more_vertical,
onIconClicked = {},
),
)
}
}

View file

@ -1,6 +1,5 @@
package com.tangem.core.ui.components
package com.tangem.core.ui.components.appbar
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
@ -48,7 +47,6 @@ fun PreviewAppBarWithBackButtonInDarkTheme() {
fun AppBarWithBackButton(text: String? = null, onBackClick: () -> Unit) {
Row(
modifier = Modifier
.background(MaterialTheme.colors.primaryVariant)
.padding(all = dimensionResource(R.dimen.spacing16))
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.spacing16)),

View file

@ -0,0 +1,8 @@
package com.tangem.core.ui.components.appbar.models
import androidx.annotation.DrawableRes
data class AdditionalButton(
@DrawableRes val iconRes: Int,
val onIconClicked: () -> Unit,
)

View file

@ -0,0 +1,60 @@
package com.tangem.core.ui.components.atoms
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.res.IconColorType
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.iconColor
/**
* Bottom sheet indicator
*
* @see <a href="https://www.figma.com/file/17JyRbuUEZ42DluaFEuGQk/Atoms?node-id=135%3A25&t=3dvxYMZBox4jxJc1-4">
* Figma Component</a>
*/
@Composable
fun BottomSheetIndicator() {
Box(
modifier = Modifier
.fillMaxWidth()
.height(dimensionResource(id = R.dimen.size20)),
contentAlignment = Alignment.Center,
) {
Box(
modifier = Modifier
.width(dimensionResource(id = R.dimen.size32))
.height(dimensionResource(id = R.dimen.size4))
.background(
color = MaterialTheme.colors.iconColor(type = IconColorType.INACTIVE),
shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius2)),
),
)
}
}
@Preview(heightDp = 20, showBackground = true)
@Composable
fun Preview_BottomSheetIndicator_InLightTheme() {
TangemTheme(isDarkTheme = false) {
BottomSheetIndicator()
}
}
@Preview(heightDp = 20, showBackground = true)
@Composable
fun Preview_BottomSheetIndicator_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
BottomSheetIndicator()
}
}

View file

@ -4,6 +4,8 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import com.google.accompanist.systemuicontroller.rememberSystemUiController
internal val isSystemInDarkTheme: Boolean = false // TODO: use isSystemInDarkTheme() for automatic color detection
@ -12,6 +14,11 @@ fun TangemTheme(
isDarkTheme: Boolean = isSystemInDarkTheme,
content: @Composable () -> Unit,
) {
val systemUiController = rememberSystemUiController()
SideEffect {
systemUiController.setSystemBarsColor(color = if (isDarkTheme) Black else Light1, darkIcons = !isDarkTheme)
}
MaterialTheme(
colors = if (isDarkTheme) DarkColors else LightColors,
typography = TangemTypography,

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,8C13.1,8 14,7.1 14,6C14,4.9 13.1,4 12,4C10.9,4 10,4.9 10,6C10,7.1 10.9,8 12,8ZM12,10C10.9,10 10,10.9 10,12C10,13.1 10.9,14 12,14C13.1,14 14,13.1 14,12C14,10.9 13.1,10 12,10ZM12,16C10.9,16 10,16.9 10,18C10,19.1 10.9,20 12,20C13.1,20 14,19.1 14,18C14,16.9 13.1,16 12,16Z"
android:fillColor="#000"
android:fillType="evenOdd" />
</vector>

View file

@ -2,7 +2,7 @@
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<clip-path android:pathData="M0,0h24v24h-24z"/>
<clip-path android:pathData="M0,0h24v24h-24z" />
<path android:fillColor="#000000" android:pathData="M2,4H6V2H2C1.47,2 0.961,2.211 0.586,2.586C0.211,2.961 0,3.47 0,4L0,8H2V4ZM22,2H18V4H22V8H24V4C24,3.47 23.789,2.961 23.414,2.586C23.039,2.211 22.53,2 22,2ZM2,16H0V20C0,20.53 0.211,21.039 0.586,21.414C0.961,21.789 1.47,22 2,22H6V20H2V16ZM22,20H18V22H22C22.53,22 23.039,21.789 23.414,21.414C23.789,21.039 24,20.53 24,20V16H22V20ZM4,8V16C4,16.53 4.211,17.039 4.586,17.414C4.961,17.789 5.47,18 6,18H18C18.53,18 19.039,17.789 19.414,17.414C19.789,17.039 20,16.53 20,16V8C20,7.47 19.789,6.961 19.414,6.586C19.039,6.211 18.53,6 18,6H6C5.47,6 4.961,6.211 4.586,6.586C4.211,6.961 4,7.47 4,8ZM6,16V12H18V16H6ZM18,8V10H6V8H18Z"/>
</group>
</vector>

View file

@ -19,10 +19,14 @@
<!-- endregion Radius -->
<!-- region Size -->
<dimen name="size0">0dp</dimen>
<dimen name="size4">4dp</dimen>
<dimen name="size11">11dp</dimen>
<dimen name="size16">16dp</dimen>
<dimen name="size20">20dp</dimen>
<dimen name="size24">24dp</dimen>
<dimen name="size28">28dp</dimen>
<dimen name="size32">32dp</dimen>
<dimen name="size40">40dp</dimen>
<dimen name="size48">48dp</dimen>
<dimen name="size56">56dp</dimen>
@ -45,5 +49,6 @@
<dimen name="spacing44">44dp</dimen>
<dimen name="spacing50">50dp</dimen>
<dimen name="spacing54">54dp</dimen>
<dimen name="radius2">2dp</dimen>
<!-- endregion Spacing -->
</resources>

View file

@ -34,6 +34,9 @@ dependencies {
/** Core modules */
implementation(project(":core:ui"))
/** AndroidX */
implementation(AndroidX.appCompat)
/** Compose */
implementation(Compose.foundation)
implementation(Compose.material)

View file

@ -4,6 +4,7 @@ data class ReferralStateHolder(
val headerState: HeaderState,
val referralInfoState: ReferralInfoState,
val effects: Effects,
val agreementBottomSheetState: AgreementBottomSheetState
) {
data class HeaderState(val onBackClicked: () -> Unit)
@ -16,7 +17,6 @@ data class ReferralStateHolder(
val award: String,
val address: String,
val discount: String,
val onAgreementClicked: () -> Unit,
val onParticipateClicked: () -> Unit,
) : ReferralInfoState, ReferralInfoContentState
@ -27,11 +27,12 @@ data class ReferralStateHolder(
val code: String,
val onCopyClicked: () -> Unit,
val onShareClicked: () -> Unit,
val onAgreementClicked: () -> Unit,
) : ReferralInfoState, ReferralInfoContentState
object Loading : ReferralInfoState
}
data class Effects(val showErrorToast: Boolean)
data class AgreementBottomSheetState(val url: String)
}

View file

@ -0,0 +1,80 @@
package com.tangem.feature.referral.ui
import android.view.ViewGroup.LayoutParams
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.tangem.core.ui.components.appbar.AppBarWithAdditionalButtons
import com.tangem.core.ui.components.atoms.BottomSheetIndicator
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.referral.presentation.R
/**
* Bottom sheet content with referral program terms of use
*
* @param url link to the html page
*/
@Composable
fun AgreementBottomSheetContent(url: String) {
Column(
modifier = Modifier
.background(color = MaterialTheme.colors.secondary)
.fillMaxWidth()
.height(LocalConfiguration.current.screenHeightDp.dp - dimensionResource(id = R.dimen.spacing16)),
) {
BottomSheetIndicator()
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
AppBarWithAdditionalButtons(text = stringResource(id = R.string.details_referral_title))
AgreementHtmlView(url = url)
}
}
}
@Composable
private fun AgreementHtmlView(url: String) {
AndroidView(
modifier = Modifier.background(MaterialTheme.colors.secondary),
factory = {
WebView(it).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
webViewClient = WebViewClient()
settings.apply {
javaScriptEnabled = false
allowFileAccess = false
}
loadUrl(url)
}
},
update = { it.loadUrl(url) },
)
}
@Preview
@Composable
fun Preview_AgreementBottomSheet_InLightTheme() {
TangemTheme(isDarkTheme = false) {
AgreementBottomSheetContent(url = "https://tangem.com/en/")
}
}
@Preview
@Composable
fun Preview_AgreementBottomSheet_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
AgreementBottomSheetContent(url = "https://tangem.com/en/")
}
}

View file

@ -17,10 +17,16 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.BottomSheetScaffold
import androidx.compose.material.BottomSheetState
import androidx.compose.material.BottomSheetValue
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.rememberBottomSheetScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -32,8 +38,8 @@ import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.AppBarWithBackButton
import com.tangem.core.ui.components.VerticalSpacer
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.ButtonColorType
import com.tangem.core.ui.res.IconColorType
import com.tangem.core.ui.res.TangemTheme
@ -46,126 +52,51 @@ import com.tangem.feature.referral.models.ReferralStateHolder
import com.tangem.feature.referral.models.ReferralStateHolder.ReferralInfoState
import com.tangem.feature.referral.presentation.R
import com.valentinilk.shimmer.shimmer
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Participant_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.ParticipantContent(
award = "10 USDT",
address = "ma80...zk8q2",
discount = "10%",
onAgreementClicked = {},
onParticipateClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Participant_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.ParticipantContent(
award = "10 USDT",
address = "ma80...zk8q2",
discount = "10%",
onAgreementClicked = {},
onParticipateClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_NonParticipant_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.NonParticipantContent(
award = "10 USDT",
discount = "10%",
purchasedWalletCount = 3,
code = "x4JdK",
onCopyClicked = {},
onShareClicked = {},
onAgreementClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_NonParticipant_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.NonParticipantContent(
award = "10 USDT",
discount = "10%",
purchasedWalletCount = 3,
code = "x4JdK",
onCopyClicked = {},
onShareClicked = {},
onAgreementClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Loading_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.Loading,
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Loading_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.Loading,
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
import kotlinx.coroutines.launch
/**
* Referral program screen for participant and non-participant
*
* @param stateHolder state holder
*/
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun ReferralScreen(stateHolder: ReferralStateHolder) {
val coroutineScope = rememberCoroutineScope()
val bottomSheetScaffoldState = rememberBottomSheetScaffoldState(
bottomSheetState = BottomSheetState(BottomSheetValue.Collapsed),
)
TangemTheme {
BottomSheetScaffold(
sheetContent = { AgreementBottomSheetContent(stateHolder.agreementBottomSheetState.url) },
scaffoldState = bottomSheetScaffoldState,
sheetShape = RoundedCornerShape(
topStart = dimensionResource(id = R.dimen.radius16),
topEnd = dimensionResource(id = R.dimen.radius16),
),
sheetElevation = dimensionResource(id = R.dimen.elevation24),
sheetPeekHeight = dimensionResource(id = R.dimen.size0),
content = {
ReferralContent(
stateHolder = stateHolder,
onAgreementClicked = {
coroutineScope.launch {
if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) {
bottomSheetScaffoldState.bottomSheetState.expand()
} else {
bottomSheetScaffoldState.bottomSheetState.collapse()
}
}
},
)
},
)
}
}
@Composable
fun ReferralContent(stateHolder: ReferralStateHolder, onAgreementClicked: () -> Unit) {
Column(
modifier = Modifier
.background(color = MaterialTheme.colors.primary)
@ -175,7 +106,7 @@ fun ReferralScreen(stateHolder: ReferralStateHolder) {
) {
Header(stateHolder = stateHolder)
VerticalSpacer(spaceResId = R.dimen.spacing16)
ReferralInfo(stateHolder = stateHolder)
ReferralInfo(stateHolder = stateHolder, onAgreementClicked = onAgreementClicked)
}
}
@ -202,17 +133,17 @@ private fun ColumnScope.Header(stateHolder: ReferralStateHolder) {
}
@Composable
fun ReferralInfo(stateHolder: ReferralStateHolder) {
fun ReferralInfo(stateHolder: ReferralStateHolder, onAgreementClicked: () -> Unit) {
when (val state = stateHolder.referralInfoState) {
is ReferralInfoState.ParticipantContent -> {
Conditions(state = state)
VerticalSpacer(spaceResId = R.dimen.spacing44)
ParticipantBottomBlock(state = state)
ParticipantBottomBlock(state = state, onAgreementClicked = onAgreementClicked)
}
is ReferralInfoState.NonParticipantContent -> {
Conditions(state = state)
VerticalSpacer(spaceResId = R.dimen.spacing24)
NonParticipantBottomBlock(state = state)
NonParticipantBottomBlock(state = state, onAgreementClicked = onAgreementClicked)
}
is ReferralInfoState.Loading -> {
LoadingCondition(iconResId = R.drawable.ic_tether)
@ -373,21 +304,150 @@ private fun ShimmerInfo() {
}
@Composable
private fun ParticipantBottomBlock(state: ReferralInfoState.ParticipantContent) {
private fun ParticipantBottomBlock(state: ReferralInfoState.ParticipantContent, onAgreementClicked: () -> Unit) {
ParticipateBottomBlock(
onAgreementClicked = state.onAgreementClicked,
onAgreementClicked = onAgreementClicked,
onParticipateClicked = state.onParticipateClicked,
)
}
@Composable
private fun NonParticipantBottomBlock(state: ReferralInfoState.NonParticipantContent) {
private fun NonParticipantBottomBlock(state: ReferralInfoState.NonParticipantContent, onAgreementClicked: () -> Unit) {
NonParticipateBottomBlock(
purchasedWalletCount = state.purchasedWalletCount,
code = state.code,
onCopyClicked = state.onCopyClicked,
onShareClicked = state.onShareClicked,
onAgreementClicked = state.onAgreementClicked,
onAgreementClicked = onAgreementClicked,
)
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Participant_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.ParticipantContent(
award = "10 USDT",
address = "ma80...zk8q2",
discount = "10%",
onParticipateClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Participant_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.ParticipantContent(
award = "10 USDT",
address = "ma80...zk8q2",
discount = "10%",
onParticipateClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_NonParticipant_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.NonParticipantContent(
award = "10 USDT",
discount = "10%",
purchasedWalletCount = 3,
code = "x4JdK",
onCopyClicked = {},
onShareClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_NonParticipant_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.NonParticipantContent(
award = "10 USDT",
discount = "10%",
purchasedWalletCount = 3,
code = "x4JdK",
onCopyClicked = {},
onShareClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Loading_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.Loading,
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Loading_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.Loading,
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}

View file

@ -4,10 +4,10 @@
<string name="referral_title">Приведи друга в Tangem</string>
<string name="referral_point_currencies_title">Вы</string>
<string name="referral_point_currencies_description_prefix">Получите</string>
<string name="referral_point_currencies_description_suffix">за каждый кошелек, который купит ваш друг на ваш адрес в сети Tron %@</string>
<string name="referral_point_currencies_description_suffix">за каждый кошелек, который купит ваш друг на ваш адрес в сети Tron %s</string>
<string name="referral_point_discount_title">Ваш друг</string>
<string name="referral_point_discount_description_prefix">Получит</string>
<string name="referral_point_discount_description_value">%@ скидку</string>
<string name="referral_point_discount_description_value">%s скидку</string>
<string name="referral_point_discount_description_suffix">при покупке карточки на сайте tangem.com</string>
<string name="referral_tou_not_enroled_prefix">Нажимая на эту кнопку вы принимаете</string>
<string name="common_terms_and_conditions">условия участия</string>