Updated on 2026-08-14
This commit is contained in:
commit
009575eaa7
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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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