Updated on 2026-08-14
This commit is contained in:
parent
56b064b1a0
commit
b47cc52e70
14 changed files with 546 additions and 9 deletions
|
|
@ -176,7 +176,7 @@ dependencies {
|
||||||
}
|
}
|
||||||
implementation(Library.accompanistAppCompatTheme)
|
implementation(Library.accompanistAppCompatTheme)
|
||||||
implementation(Library.accompanistSystemUiController)
|
implementation(Library.accompanistSystemUiController)
|
||||||
implementation(Library.skydovesVeil)
|
implementation(Library.xmlShimmer)
|
||||||
implementation(Library.viewBindingDelegate)
|
implementation(Library.viewBindingDelegate)
|
||||||
implementation(Library.armadillo)
|
implementation(Library.armadillo)
|
||||||
implementation(Library.googlePlayServicesWallet)
|
implementation(Library.googlePlayServicesWallet)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ object Library {
|
||||||
const val appsflyer = "com.appsflyer:af-android-sdk:" + Versions.appsflyer
|
const val appsflyer = "com.appsflyer:af-android-sdk:" + Versions.appsflyer
|
||||||
const val armadillo = "at.favre.lib:armadillo:" + Versions.armadillo
|
const val armadillo = "at.favre.lib:armadillo:" + Versions.armadillo
|
||||||
const val coil = "io.coil-kt:coil:" + Versions.coil
|
const val coil = "io.coil-kt:coil:" + Versions.coil
|
||||||
|
const val composeShimmer = "com.valentinilk.shimmer:compose-shimmer:" + Versions.composeShimmer
|
||||||
const val coroutine = "org.jetbrains.kotlinx:kotlinx-coroutines-core:" + Versions.coroutine
|
const val coroutine = "org.jetbrains.kotlinx:kotlinx-coroutines-core:" + Versions.coroutine
|
||||||
const val desugarJdkLibs = "com.android.tools:desugar_jdk_libs:" + Versions.desugarJdkLibs
|
const val desugarJdkLibs = "com.android.tools:desugar_jdk_libs:" + Versions.desugarJdkLibs
|
||||||
const val googlePlayCore = "com.google.android.play:core:" + Versions.googlePlayCore
|
const val googlePlayCore = "com.google.android.play:core:" + Versions.googlePlayCore
|
||||||
|
|
@ -52,7 +53,6 @@ object Library {
|
||||||
const val okHttpLogging = "com.squareup.okhttp3:logging-interceptor:" + Versions.okhttp
|
const val okHttpLogging = "com.squareup.okhttp3:logging-interceptor:" + Versions.okhttp
|
||||||
const val otaliastudiosCameraView = "com.otaliastudios:cameraview:" + Versions.otaliastudiosCameraView
|
const val otaliastudiosCameraView = "com.otaliastudios:cameraview:" + Versions.otaliastudiosCameraView
|
||||||
const val shopifyBuySdk = "com.shopify.mobilebuysdk:buy3:" + Versions.shopifyBuySdk
|
const val shopifyBuySdk = "com.shopify.mobilebuysdk:buy3:" + Versions.shopifyBuySdk
|
||||||
const val skydovesVeil = "com.github.skydoves:androidveil:" + Versions.skydovesAndroidVeil
|
|
||||||
const val spongecastleCryptoCore = "com.madgag.spongycastle:core:" + Versions.spongycastleCryptoCore
|
const val spongecastleCryptoCore = "com.madgag.spongycastle:core:" + Versions.spongycastleCryptoCore
|
||||||
const val reKotlin = "org.rekotlin:rekotlin:" + Versions.rekotlin
|
const val reKotlin = "org.rekotlin:rekotlin:" + Versions.rekotlin
|
||||||
const val retrofit = "com.squareup.retrofit2:retrofit:" + Versions.retrofit
|
const val retrofit = "com.squareup.retrofit2:retrofit:" + Versions.retrofit
|
||||||
|
|
@ -60,6 +60,7 @@ object Library {
|
||||||
const val timber = "com.jakewharton.timber:timber:" + Versions.timber
|
const val timber = "com.jakewharton.timber:timber:" + Versions.timber
|
||||||
const val viewBindingDelegate =
|
const val viewBindingDelegate =
|
||||||
"com.github.kirich1409:viewbindingpropertydelegate-noreflection:" + Versions.viewBindingDelegate
|
"com.github.kirich1409:viewbindingpropertydelegate-noreflection:" + Versions.viewBindingDelegate
|
||||||
|
const val xmlShimmer = "com.github.skydoves:androidveil:" + Versions.xmlShimmer
|
||||||
const val zendeskChat = "com.zendesk:chat:" + Versions.zendeskChat
|
const val zendeskChat = "com.zendesk:chat:" + Versions.zendeskChat
|
||||||
const val zendeskMessaging = "com.zendesk:messaging:" + Versions.zendeskMessaging
|
const val zendeskMessaging = "com.zendesk:messaging:" + Versions.zendeskMessaging
|
||||||
const val zxingQrBarcodeScanner = "me.dm7.barcodescanner:zxing:" + Versions.zxingQrBarcodeScanner
|
const val zxingQrBarcodeScanner = "me.dm7.barcodescanner:zxing:" + Versions.zxingQrBarcodeScanner
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ object Versions {
|
||||||
const val appsflyer = "6.5.1"
|
const val appsflyer = "6.5.1"
|
||||||
const val armadillo = "0.9.0"
|
const val armadillo = "0.9.0"
|
||||||
const val coil = "2.1.0"
|
const val coil = "2.1.0"
|
||||||
|
const val composeShimmer = "1.0.3"
|
||||||
const val coroutine = "1.5.2"
|
const val coroutine = "1.5.2"
|
||||||
const val desugarJdkLibs = "1.1.5"
|
const val desugarJdkLibs = "1.1.5"
|
||||||
const val firebase = "26.0.0"
|
const val firebase = "26.0.0"
|
||||||
|
|
@ -46,10 +47,10 @@ object Versions {
|
||||||
const val retrofit = "2.8.1"
|
const val retrofit = "2.8.1"
|
||||||
const val retrofitMoshiConverter = "2.6.0"
|
const val retrofitMoshiConverter = "2.6.0"
|
||||||
const val shopifyBuySdk = "12.0.0"
|
const val shopifyBuySdk = "12.0.0"
|
||||||
const val skydovesAndroidVeil = "1.1.2"
|
|
||||||
const val spongycastleCryptoCore = "1.58.0.0"
|
const val spongycastleCryptoCore = "1.58.0.0"
|
||||||
const val timber = "4.7.1"
|
const val timber = "4.7.1"
|
||||||
const val viewBindingDelegate = "1.5.6"
|
const val viewBindingDelegate = "1.5.6"
|
||||||
|
const val xmlShimmer = "1.1.2"
|
||||||
const val zendeskChat = "3.3.5"
|
const val zendeskChat = "3.3.5"
|
||||||
const val zendeskMessaging = "5.2.4"
|
const val zendeskMessaging = "5.2.4"
|
||||||
const val zxingQrBarcodeScanner = "1.9.8"
|
const val zxingQrBarcodeScanner = "1.9.8"
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
|
|
@ -48,7 +49,8 @@ fun AppBarWithBackButton(text: String? = null, onBackClick: () -> Unit) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(MaterialTheme.colors.primaryVariant)
|
.background(MaterialTheme.colors.primaryVariant)
|
||||||
.padding(all = dimensionResource(R.dimen.spacing16)),
|
.padding(all = dimensionResource(R.dimen.spacing16))
|
||||||
|
.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.spacing16)),
|
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.spacing16)),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.tangem.core.ui.components
|
||||||
|
|
||||||
|
import androidx.annotation.DimenRes
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.dimensionResource
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun VerticalSpacer(@DimenRes spaceResId: Int) {
|
||||||
|
Spacer(modifier = Modifier.height(dimensionResource(id = spaceResId)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HorizontalSpacer(@DimenRes spaceResId: Int) {
|
||||||
|
Spacer(modifier = Modifier.width(dimensionResource(id = spaceResId)))
|
||||||
|
}
|
||||||
19
core/ui/src/main/java/com/tangem/core/ui/res/IconColor.kt
Normal file
19
core/ui/src/main/java/com/tangem/core/ui/res/IconColor.kt
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.tangem.core.ui.res
|
||||||
|
|
||||||
|
import androidx.compose.material.Colors
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
enum class IconColorType(val lightColor: Color, val darkColor: Color) {
|
||||||
|
PRIMARY1(lightColor = Black, darkColor = White),
|
||||||
|
PRIMARY2(lightColor = White, darkColor = Dark6),
|
||||||
|
SECONDARY(lightColor = Dark2, darkColor = Dark1),
|
||||||
|
INFORMATIVE(lightColor = Light5, darkColor = Dark2),
|
||||||
|
INACTIVE(lightColor = Light4, darkColor = Dark4),
|
||||||
|
ACCENT(lightColor = Meadow, darkColor = Meadow),
|
||||||
|
WARNING(lightColor = Amaranth, darkColor = Amaranth),
|
||||||
|
ATTENTION(lightColor = Tangerine, darkColor = Tangerine)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Colors.iconColor(type: IconColorType): Color = if (isSystemInDarkTheme) type.darkColor else type.lightColor
|
||||||
9
core/ui/src/main/res/drawable/ic_discount.xml
Normal file
9
core/ui/src/main/res/drawable/ic_discount.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="28dp"
|
||||||
|
android:height="28dp"
|
||||||
|
android:viewportWidth="28"
|
||||||
|
android:viewportHeight="28">
|
||||||
|
<path
|
||||||
|
android:pathData="M22.04,10.71V6H17.34L14,2.69L10.71,6H6V10.71L2.69,14L6,17.34V22.04H10.71L14,25.35L17.34,22.04H22.04V17.34L25.35,14L22.04,10.71ZM10.83,9.05C11.81,9.05 12.6,9.84 12.6,10.83C12.6,11.299 12.413,11.75 12.082,12.082C11.75,12.413 11.299,12.6 10.83,12.6C9.84,12.6 9.05,11.81 9.05,10.83C9.05,9.84 9.84,9.05 10.83,9.05ZM17.22,19C16.24,19 15.45,18.2 15.45,17.22C15.45,16.751 15.637,16.3 15.968,15.968C16.3,15.637 16.751,15.45 17.22,15.45C18.2,15.45 19,16.24 19,17.22C19,17.692 18.813,18.145 18.479,18.479C18.145,18.813 17.692,19 17.22,19ZM10.5,19.03L9,17.53L17.53,9L19.03,10.5L10.5,19.03Z"
|
||||||
|
android:fillColor="#000000" />
|
||||||
|
</vector>
|
||||||
17
core/ui/src/main/res/drawable/ic_tether.xml
Normal file
17
core/ui/src/main/res/drawable/ic_tether.xml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="28dp"
|
||||||
|
android:height="28dp"
|
||||||
|
android:viewportWidth="28"
|
||||||
|
android:viewportHeight="28">
|
||||||
|
<group>
|
||||||
|
<clip-path android:pathData="M0,0h28v28h-28z" />
|
||||||
|
<path
|
||||||
|
android:pathData="M8.821,17.869C9.035,16.016 9.741,14.312 10.803,12.892C10.407,13.076 9.929,13.195 9.38,13.241V14H8.552V13.247C6.83,13.134 5.744,12.22 5.738,10.863H7.015C7.077,11.556 7.657,12.04 8.552,12.142V9.483L8.015,9.346C6.67,9.017 5.935,8.234 5.935,7.093C5.935,5.749 6.929,4.852 8.552,4.709V3.902H9.38V4.709C10.941,4.84 11.966,5.766 12.003,7.063H10.744C10.719,6.424 10.176,5.922 9.38,5.826V8.342L9.941,8.467C11.454,8.82 12.163,9.561 12.163,10.768C12.163,11.028 12.13,11.27 12.065,11.493C13.628,10.047 15.64,9.079 17.869,8.822C17.808,3.939 13.831,0 8.935,0C4,0 0,4 0,8.935C0,13.831 3.939,17.808 8.821,17.869ZM17.776,10.222C13.873,10.786 10.786,13.873 10.222,17.776L17.776,10.222ZM8.552,8.174C7.688,8.007 7.225,7.589 7.225,6.991C7.225,6.352 7.781,5.862 8.552,5.82V8.174ZM9.38,12.154V9.632C10.404,9.83 10.88,10.236 10.88,10.905C10.88,11.646 10.33,12.1 9.38,12.154Z"
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:fillType="evenOdd" />
|
||||||
|
<path
|
||||||
|
android:pathData="M10.13,19.066C10.13,14.132 14.13,10.131 19.064,10.131C23.998,10.131 27.999,14.132 27.999,19.066C27.999,24 23.998,28.001 19.064,28.001C14.13,28.001 10.13,24 10.13,19.066ZM19.527,17.526L20.48,14.823L19.066,14.323L17.782,17.962L15.337,18.573L15.701,20.028L17.183,19.658L16.23,22.36C16.149,22.589 16.184,22.844 16.325,23.043C16.465,23.241 16.694,23.36 16.937,23.36H22.61V21.86H17.997L18.928,19.222L21.374,18.61L21.01,17.155L19.527,17.526Z"
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:fillType="evenOdd" />
|
||||||
|
</group>
|
||||||
|
</vector>
|
||||||
|
|
@ -13,19 +13,37 @@
|
||||||
<!-- endregion Elevation -->
|
<!-- endregion Elevation -->
|
||||||
|
|
||||||
<!-- region Radius -->
|
<!-- region Radius -->
|
||||||
|
<dimen name="radius6">6dp</dimen>
|
||||||
<dimen name="radius12">12dp</dimen>
|
<dimen name="radius12">12dp</dimen>
|
||||||
|
<dimen name="radius16">16dp</dimen>
|
||||||
<!-- endregion Radius -->
|
<!-- endregion Radius -->
|
||||||
|
|
||||||
<!-- region Size -->
|
<!-- region Size -->
|
||||||
|
<dimen name="size11">11dp</dimen>
|
||||||
|
<dimen name="size16">16dp</dimen>
|
||||||
<dimen name="size24">24dp</dimen>
|
<dimen name="size24">24dp</dimen>
|
||||||
|
<dimen name="size28">28dp</dimen>
|
||||||
|
<dimen name="size40">40dp</dimen>
|
||||||
<dimen name="size48">48dp</dimen>
|
<dimen name="size48">48dp</dimen>
|
||||||
|
<dimen name="size56">56dp</dimen>
|
||||||
|
<dimen name="size84">84dp</dimen>
|
||||||
|
<dimen name="size86">86dp</dimen>
|
||||||
|
<dimen name="size102">102dp</dimen>
|
||||||
|
<dimen name="size164">164dp</dimen>
|
||||||
<dimen name="size200">200dp</dimen>
|
<dimen name="size200">200dp</dimen>
|
||||||
<!-- endregion Size -->
|
<!-- endregion Size -->
|
||||||
|
|
||||||
<!-- region Spacing -->
|
<!-- region Spacing -->
|
||||||
|
<dimen name="spacing2">2dp</dimen>
|
||||||
|
<dimen name="spacing4">4dp</dimen>
|
||||||
<dimen name="spacing8">8dp</dimen>
|
<dimen name="spacing8">8dp</dimen>
|
||||||
|
<dimen name="spacing10">10dp</dimen>
|
||||||
<dimen name="spacing12">12dp</dimen>
|
<dimen name="spacing12">12dp</dimen>
|
||||||
<dimen name="spacing16">16dp</dimen>
|
<dimen name="spacing16">16dp</dimen>
|
||||||
<dimen name="spacing24">24dp</dimen>
|
<dimen name="spacing24">24dp</dimen>
|
||||||
|
<dimen name="spacing32">32dp</dimen>
|
||||||
|
<dimen name="spacing44">44dp</dimen>
|
||||||
|
<dimen name="spacing50">50dp</dimen>
|
||||||
|
<dimen name="spacing54">54dp</dimen>
|
||||||
<!-- endregion Spacing -->
|
<!-- endregion Spacing -->
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.library")
|
id("com.android.library")
|
||||||
kotlin("android")
|
kotlin("android")
|
||||||
kotlin("kapt")
|
|
||||||
id("com.google.dagger.hilt.android")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
@ -22,11 +20,25 @@ android {
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
isCoreLibraryDesugaringEnabled = false
|
isCoreLibraryDesugaringEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
compose = true
|
||||||
|
}
|
||||||
|
|
||||||
|
composeOptions {
|
||||||
|
kotlinCompilerExtensionVersion = Versions.compose
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
/** Core modules */
|
||||||
|
implementation(project(":core:ui"))
|
||||||
|
|
||||||
/** DI */
|
/** Compose */
|
||||||
implementation(Library.hilt)
|
implementation(Compose.foundation)
|
||||||
kapt(Library.hiltKapt)
|
implementation(Compose.material)
|
||||||
|
implementation(Compose.uiTooling)
|
||||||
|
|
||||||
|
/** Other libraries */
|
||||||
|
implementation(Library.composeShimmer)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.tangem.feature.referral.models
|
||||||
|
|
||||||
|
data class ReferralStateHolder(
|
||||||
|
val headerState: HeaderState,
|
||||||
|
val referralInfoState: ReferralInfoState,
|
||||||
|
val effects: Effects,
|
||||||
|
) {
|
||||||
|
|
||||||
|
data class HeaderState(val onBackClicked: () -> Unit)
|
||||||
|
|
||||||
|
sealed interface ReferralInfoContentState
|
||||||
|
|
||||||
|
sealed interface ReferralInfoState {
|
||||||
|
|
||||||
|
data class ParticipantContent(
|
||||||
|
val award: String,
|
||||||
|
val address: String,
|
||||||
|
val discount: String,
|
||||||
|
val onAgreementClicked: () -> Unit,
|
||||||
|
val onParticipateClicked: () -> Unit,
|
||||||
|
) : ReferralInfoState, ReferralInfoContentState
|
||||||
|
|
||||||
|
data class NonParticipantContent(
|
||||||
|
val award: String,
|
||||||
|
val discount: String,
|
||||||
|
val purchasedWalletCount: Int,
|
||||||
|
val code: String,
|
||||||
|
val onCopyClicked: () -> Unit,
|
||||||
|
val onShareClicked: () -> Unit,
|
||||||
|
val onAgreementClicked: () -> Unit,
|
||||||
|
) : ReferralInfoState, ReferralInfoContentState
|
||||||
|
|
||||||
|
object Loading : ReferralInfoState
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Effects(val showErrorToast: Boolean)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,362 @@
|
||||||
|
package com.tangem.feature.referral.ui
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
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.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
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.draw.clip
|
||||||
|
import androidx.compose.ui.res.dimensionResource
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
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.res.ButtonColorType
|
||||||
|
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.White
|
||||||
|
import com.tangem.core.ui.res.buttonColor
|
||||||
|
import com.tangem.core.ui.res.iconColor
|
||||||
|
import com.tangem.core.ui.res.textColor
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Referral program screen for participant and non-participant
|
||||||
|
*
|
||||||
|
* @param stateHolder state holder
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun ReferralScreen(stateHolder: ReferralStateHolder) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(color = MaterialTheme.colors.primary)
|
||||||
|
.fillMaxSize(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
Header(stateHolder = stateHolder)
|
||||||
|
VerticalSpacer(spaceResId = R.dimen.spacing16)
|
||||||
|
ReferralInfo(stateHolder = stateHolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ColumnScope.Header(stateHolder: ReferralStateHolder) {
|
||||||
|
AppBar(stateHolder = stateHolder)
|
||||||
|
Image(
|
||||||
|
painter = painterResource(R.drawable.ill_businessman_3d),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = dimensionResource(id = R.dimen.spacing32))
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(dimensionResource(R.dimen.size200)),
|
||||||
|
)
|
||||||
|
VerticalSpacer(spaceResId = R.dimen.spacing24)
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.referral_title),
|
||||||
|
modifier = Modifier.padding(horizontal = dimensionResource(R.dimen.spacing50)),
|
||||||
|
color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 2,
|
||||||
|
style = MaterialTheme.typography.h2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ReferralInfo(stateHolder: ReferralStateHolder) {
|
||||||
|
when (val state = stateHolder.referralInfoState) {
|
||||||
|
is ReferralInfoState.ParticipantContent,
|
||||||
|
is ReferralInfoState.NonParticipantContent -> {
|
||||||
|
Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing32))) {
|
||||||
|
ConditionForYou(state = state as ReferralStateHolder.ReferralInfoContentState)
|
||||||
|
ConditionForYourFriend(state = state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is ReferralInfoState.Loading -> {
|
||||||
|
Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing32))) {
|
||||||
|
LoadingCondition(iconResId = R.drawable.ic_tether)
|
||||||
|
LoadingCondition(iconResId = R.drawable.ic_discount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun AppBar(stateHolder: ReferralStateHolder) {
|
||||||
|
AppBarWithBackButton(
|
||||||
|
text = stringResource(R.string.details_referral_title),
|
||||||
|
onBackClick = stateHolder.headerState.onBackClicked,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ConditionForYou(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||||
|
Condition(iconResId = R.drawable.ic_tether) {
|
||||||
|
when (state) {
|
||||||
|
is ReferralInfoState.ParticipantContent -> InfoForYou(award = state.award, address = state.address)
|
||||||
|
is ReferralInfoState.NonParticipantContent -> InfoForYou(award = state.award)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ConditionForYourFriend(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||||
|
Condition(iconResId = R.drawable.ic_discount) {
|
||||||
|
when (state) {
|
||||||
|
is ReferralInfoState.ParticipantContent -> InfoForYourFriend(discount = state.discount)
|
||||||
|
is ReferralInfoState.NonParticipantContent -> InfoForYourFriend(discount = state.discount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun LoadingCondition(@DrawableRes iconResId: Int) {
|
||||||
|
Condition(iconResId = iconResId) {
|
||||||
|
ShimmerCondition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Condition(@DrawableRes iconResId: Int, infoBlock: @Composable () -> Unit) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing16)),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing12)),
|
||||||
|
verticalAlignment = Alignment.Top,
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(
|
||||||
|
color = MaterialTheme.colors.buttonColor(type = ButtonColorType.SECONDARY),
|
||||||
|
shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius16)),
|
||||||
|
)
|
||||||
|
.size(dimensionResource(id = R.dimen.size56)),
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = iconResId),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(dimensionResource(id = R.dimen.size28)),
|
||||||
|
tint = MaterialTheme.colors.iconColor(type = IconColorType.PRIMARY1),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
infoBlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun InfoForYou(award: String, address: String? = null) {
|
||||||
|
ConditionInfo(title = stringResource(id = R.string.referral_point_currencies_title)) {
|
||||||
|
Text(
|
||||||
|
text = buildAnnotatedString {
|
||||||
|
append(stringResource(id = R.string.referral_point_currencies_description_prefix))
|
||||||
|
withStyle(SpanStyle(color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1))) {
|
||||||
|
append(" $award ")
|
||||||
|
}
|
||||||
|
append(
|
||||||
|
String.format(
|
||||||
|
stringResource(id = R.string.referral_point_currencies_description_suffix),
|
||||||
|
if (!address.isNullOrBlank()) address else "",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY),
|
||||||
|
style = MaterialTheme.typography.body2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun InfoForYourFriend(discount: String) {
|
||||||
|
ConditionInfo(title = stringResource(id = R.string.referral_point_discount_title)) {
|
||||||
|
Text(
|
||||||
|
text = buildString {
|
||||||
|
append(stringResource(id = R.string.referral_point_discount_description_prefix))
|
||||||
|
append(
|
||||||
|
String.format(
|
||||||
|
stringResource(id = R.string.referral_point_discount_description_value),
|
||||||
|
" $discount",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
append(" ")
|
||||||
|
append(stringResource(id = R.string.referral_point_discount_description_suffix))
|
||||||
|
},
|
||||||
|
color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY),
|
||||||
|
style = MaterialTheme.typography.body2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ConditionInfo(title: String, subtitleContent: @Composable () -> Unit) {
|
||||||
|
Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing2))) {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1),
|
||||||
|
style = MaterialTheme.typography.subtitle1,
|
||||||
|
)
|
||||||
|
subtitleContent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ShimmerCondition() {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = dimensionResource(id = R.dimen.spacing4))
|
||||||
|
.shimmer(),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing10)),
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(id = R.dimen.radius6)))
|
||||||
|
.width(dimensionResource(id = R.dimen.size102))
|
||||||
|
.height(dimensionResource(id = R.dimen.size16))
|
||||||
|
.background(White),
|
||||||
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(id = R.dimen.radius6)))
|
||||||
|
.width(dimensionResource(id = R.dimen.size40))
|
||||||
|
.height(dimensionResource(id = R.dimen.size11))
|
||||||
|
.background(White),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="details_referral_title">Реферальная программа</string>
|
||||||
|
<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_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_suffix">при покупке карточки на сайте tangem.com</string>
|
||||||
|
<string name="referral_tou_not_enroled_prefix">Нажимая на эту кнопку вы принимаете</string>
|
||||||
|
<string name="common_terms_and_conditions">условия участия</string>
|
||||||
|
<string name="referral_tou_suffix">в реферальной программе</string>
|
||||||
|
<string name="referral_button_participate">Участвовать</string>
|
||||||
|
<string name="referral_tou_enroled_prefix">Вы приняли</string>
|
||||||
|
<string name="referral_promo_code_title">Ваш персональный код</string>
|
||||||
|
<string name="referral_wallets_purchased_count">%d кошельков</string>
|
||||||
|
<string name="referral_friends_bought_title">Ваши друзья купили</string>
|
||||||
|
</resources>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="details_referral_title">Referral program</string>
|
||||||
|
<string name="referral_title">Refer your friends to Tangem</string>
|
||||||
|
<string name="referral_point_currencies_title">You</string>
|
||||||
|
<string name="referral_point_currencies_description_prefix">Will get</string>
|
||||||
|
<string name="referral_point_currencies_description_suffix">for each wallet bought by your friend on your Tron network address %s</string>
|
||||||
|
<string name="referral_point_discount_title">Your friend</string>
|
||||||
|
<string name="referral_point_discount_description_prefix">Will get a</string>
|
||||||
|
<string name="referral_point_discount_description_value">%s discount</string>
|
||||||
|
<string name="referral_point_discount_description_suffix">when buying a card on tangem.com</string>
|
||||||
|
<string name="referral_tou_not_enroled_prefix">By tapping this button you accept</string>
|
||||||
|
<string name="common_terms_and_conditions">terms and conditions</string>
|
||||||
|
<string name="referral_tou_suffix">of the referral program</string>
|
||||||
|
<string name="referral_button_participate">Participate</string>
|
||||||
|
<string name="referral_tou_enroled_prefix">You\'ve accepted</string>
|
||||||
|
<string name="referral_promo_code_title">Your personal code</string>
|
||||||
|
<string name="referral_wallets_purchased_count">%d wallets</string>
|
||||||
|
<string name="referral_friends_bought_title">Your friends bought</string>
|
||||||
|
</resources>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue