Updated on 2026-08-14
This commit is contained in:
parent
8002513bf8
commit
ed03d8530e
18 changed files with 542 additions and 145 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<item
|
||||
android:id="@+id/details_menu"
|
||||
android:title="@string/details_title"
|
||||
android:icon="@drawable/ic_more_vertical_24"
|
||||
android:icon="@drawable/ic_more_vertical"
|
||||
app:iconTint="@color/darkGray6"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
|
|
|
|||
|
|
@ -35,4 +35,7 @@ dependencies {
|
|||
implementation(Compose.foundation)
|
||||
implementation(Compose.material)
|
||||
implementation(Compose.uiTooling)
|
||||
|
||||
/** Other libraries */
|
||||
implementation(Library.accompanistSystemUiController)
|
||||
}
|
||||
|
|
@ -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 = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)),
|
||||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
10
core/ui/src/main/res/drawable/ic_more_vertical.xml
Normal file
10
core/ui/src/main/res/drawable/ic_more_vertical.xml
Normal 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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -34,6 +34,9 @@ dependencies {
|
|||
/** Core modules */
|
||||
implementation(project(":core:ui"))
|
||||
|
||||
/** AndroidX */
|
||||
implementation(AndroidX.appCompat)
|
||||
|
||||
/** Compose */
|
||||
implementation(Compose.foundation)
|
||||
implementation(Compose.material)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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/")
|
||||
}
|
||||
}
|
||||
|
|
@ -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 = "",
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue