Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-18 18:47:15 +03:00
parent 38e3891680
commit c81ce487a2
30 changed files with 403 additions and 20 deletions

View file

@ -0,0 +1,24 @@
package com.tangem.features.send.impl.di
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
import com.tangem.features.send.api.featuretoggles.SendFeatureToggles
import com.tangem.features.send.impl.featuretoggles.DefaultSendFeatureToggles
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
/**
* DI module provides implementation of [SendFeatureToggles]
*/
@Module
@InstallIn(SingletonComponent::class)
internal object SendFeatureTogglesModule {
@Provides
@Singleton
fun provideSendFeatureToggles(featureTogglesManager: FeatureTogglesManager): SendFeatureToggles {
return DefaultSendFeatureToggles(featureTogglesManager = featureTogglesManager)
}
}

View file

@ -0,0 +1,23 @@
package com.tangem.features.send.impl.di
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.send.impl.navigation.DefaultSendRouter
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityScoped
/**
* DI module provides implementation of [SendRouter]
*/
@Module
@InstallIn(ActivityComponent::class)
internal object SendRouterModule {
@Provides
@ActivityScoped
fun provideSendRouter(): SendRouter {
return DefaultSendRouter()
}
}

View file

@ -0,0 +1,16 @@
package com.tangem.features.send.impl.featuretoggles
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
import com.tangem.features.send.api.featuretoggles.SendFeatureToggles
/**
* Default implementation of Send feature toggles
*
* @property featureTogglesManager manager for getting information about the availability of feature toggles
*/
internal class DefaultSendFeatureToggles(
private val featureTogglesManager: FeatureTogglesManager,
) : SendFeatureToggles {
override val isRedesignedSendEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = "REDESIGNED_SEND_SCREEN_ENABLED")
}

View file

@ -0,0 +1,9 @@
package com.tangem.features.send.impl.navigation
import androidx.fragment.app.Fragment
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.send.impl.presentation.SendFragment
internal class DefaultSendRouter : SendRouter {
override fun getEntryFragment(): Fragment = SendFragment.create()
}

View file

@ -0,0 +1,41 @@
package com.tangem.features.send.impl.presentation
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.tangem.core.ui.components.SystemBarsEffect
import com.tangem.core.ui.screen.ComposeBottomSheetFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.features.send.impl.presentation.send.ui.SendScreen
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
/**
* Send fragment
*/
@AndroidEntryPoint
internal class SendFragment : ComposeBottomSheetFragment() {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
override val expandedHeightFraction: Float = 1f
@Composable
override fun ScreenContent(modifier: Modifier) {
SystemBarsEffect {
setSystemBarsColor(color = Color.Transparent)
}
BackHandler {
dismiss()
}
SendScreen()
}
companion object {
/** Create send fragment instance */
fun create(): SendFragment = SendFragment()
}
}

View file

@ -0,0 +1,7 @@
package com.tangem.features.send.impl.presentation.send.ui
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
data class SendBottomSheetConfig(
val currentState: SendStates,
) : TangemBottomSheetConfigContent

View file

@ -0,0 +1,96 @@
package com.tangem.features.send.impl.presentation.send.ui
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import com.tangem.core.ui.R
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.PrimaryButtonIconEnd
import com.tangem.core.ui.res.TangemTheme
@Composable
internal fun SendNavigationButtons(currentState: SendStates) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = TangemTheme.dimens.spacing12),
) {
SendSecondaryNavigationButton(currentState)
SendPrimaryNavigationButton(
currentState,
modifier = Modifier
.weight(1f)
.padding(horizontal = TangemTheme.dimens.spacing16),
)
}
}
@Composable
private fun SendSecondaryNavigationButton(currentState: SendStates) {
AnimatedVisibility(
visible = currentState == SendStates.Recipient || currentState == SendStates.Fee,
) {
Icon(
modifier = Modifier
.padding(start = TangemTheme.dimens.spacing16)
.clip(RoundedCornerShape(TangemTheme.dimens.radius16))
.background(TangemTheme.colors.button.secondary)
.clickable {
// todo add prev click
}
.padding(TangemTheme.dimens.spacing12),
painter = painterResource(R.drawable.ic_back_24),
contentDescription = null,
)
}
}
@Composable
private fun SendPrimaryNavigationButton(currentState: SendStates, modifier: Modifier = Modifier) {
val buttonTextId = when (currentState) {
SendStates.Amount,
SendStates.Recipient,
SendStates.Fee,
-> R.string.common_next
SendStates.Filled -> R.string.common_send
SendStates.Done -> R.string.common_close
}
AnimatedContent(
targetState = buttonTextId,
label = "Update send screen state",
modifier = modifier,
) { textId ->
when (currentState) {
SendStates.Amount,
SendStates.Recipient,
SendStates.Fee,
SendStates.Done,
-> PrimaryButton(
text = stringResource(textId),
onClick = {
// todo add next click
},
)
SendStates.Filled -> {
PrimaryButtonIconEnd(
text = stringResource(textId),
iconResId = R.drawable.ic_tangem_24,
onClick = {
// todo add next click
},
)
}
}
}
}

View file

@ -0,0 +1,52 @@
package com.tangem.features.send.impl.presentation.send.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetDraggableHeader
import com.tangem.core.ui.res.TangemTheme
@Composable
fun SendScreen() {
// todo will be removed
val config = remember { SendBottomSheetConfig(SendStates.Amount) }
Column(
modifier = Modifier
.imePadding()
.background(
color = TangemTheme.colors.background.tertiary,
shape = RoundedCornerShape(
topStart = TangemTheme.dimens.radius24,
topEnd = TangemTheme.dimens.radius24,
),
),
horizontalAlignment = Alignment.CenterHorizontally,
) {
TangemBottomSheetDraggableHeader(
color = TangemTheme.colors.background.tertiary,
)
Box(
modifier = Modifier
.weight(1f)
.scrollable(state = rememberScrollState(), orientation = Orientation.Vertical),
) {
SendScreenContent()
}
SendNavigationButtons(config.currentState)
}
}
@Composable
fun SendScreenContent() {
// todo work in progress
}

View file

@ -0,0 +1,34 @@
package com.tangem.features.send.impl.presentation.send.ui
/**
* Screen states of Send
*/
enum class SendStates {
Amount,
Recipient,
Fee,
Filled,
Done,
;
companion object {
/** Get next [SendStates] */
fun SendStates.next(): SendStates {
return if (this.ordinal < SendStates.values().last().ordinal) {
SendStates.values()[this.ordinal + 1]
} else {
this
}
}
/** Get previous [SendStates] */
fun SendStates.previous(): SendStates {
return if (this.ordinal > 0) {
SendStates.values()[this.ordinal - 1]
} else {
this
}
}
}
}