Updated on 2026-08-14

This commit is contained in:
Tangem 2024-06-17 13:30:30 +04:00
parent 3a6668eee0
commit 25f7ea1644
10 changed files with 154 additions and 88 deletions

View file

@ -27,8 +27,8 @@ import com.tangem.core.ui.R
import com.tangem.core.ui.components.SelctorDialogParamsProvider.SelectorDialogParams
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
import com.tangem.core.ui.components.fields.SimpleDialogTextField
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
@ -100,7 +100,7 @@ fun TextInputDialog(
confirmButton: DialogButton,
onDismissDialog: () -> Unit,
onValueChange: (TextFieldValue) -> Unit,
textFieldParams: AdditionalTextInputDialogParams,
textFieldParams: AdditionalTextInputDialogParams = remember { AdditionalTextInputDialogParams() },
title: String? = null,
dismissButton: DialogButton? = null,
isDismissable: Boolean = true,
@ -128,7 +128,7 @@ fun TextInputDialog(
confirmButton: DialogButton,
onDismissDialog: () -> Unit,
onValueChange: (String) -> Unit,
textFieldParams: AdditionalTextInputDialogParams,
textFieldParams: AdditionalTextInputDialogParams = remember { AdditionalTextInputDialogParams() },
title: String? = null,
dismissButton: DialogButton? = null,
isDismissable: Boolean = true,

View file

@ -0,0 +1,75 @@
package com.tangem.core.ui.components.appbar.models
import androidx.compose.foundation.layout.size
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import com.tangem.core.ui.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
private const val COLLAPSED_APP_BAR_THRESHOLD = 0.4f
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopAppBarMedium(
title: TextReference,
scrollBehavior: TopAppBarScrollBehavior,
onBackClick: () -> Unit,
modifier: Modifier = Modifier,
navigationIconResId: Int = R.drawable.ic_back_24,
colors: TopAppBarColors = TangemTopAppBarColors,
) {
MediumTopAppBar(
modifier = modifier,
scrollBehavior = scrollBehavior,
colors = colors,
title = {
val collapsedStyle = TangemTheme.typography.subtitle1
val expandedStyle = TangemTheme.typography.h1
val style by remember(scrollBehavior.state.collapsedFraction) {
derivedStateOf {
if (scrollBehavior.state.collapsedFraction >= COLLAPSED_APP_BAR_THRESHOLD) {
collapsedStyle
} else {
expandedStyle
}
}
}
Text(
text = title.resolveReference(),
style = style,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
navigationIcon = {
IconButton(
modifier = Modifier.size(TangemTheme.dimens.size32),
onClick = onBackClick,
) {
Icon(
modifier = Modifier.size(TangemTheme.dimens.size24),
painter = painterResource(id = navigationIconResId),
contentDescription = null,
)
}
},
)
}
@OptIn(ExperimentalMaterial3Api::class)
internal val TangemTopAppBarColors: TopAppBarColors
@Composable
@ReadOnlyComposable
get() = TopAppBarColors(
containerColor = TangemTheme.colors.background.secondary,
scrolledContainerColor = TangemTheme.colors.background.secondary,
navigationIconContentColor = TangemTheme.colors.icon.primary1,
titleContentColor = TangemTheme.colors.text.primary1,
actionIconContentColor = TangemTheme.colors.icon.primary1,
)

View file

@ -1,4 +1,4 @@
package com.tangem.features.details.ui
package com.tangem.core.ui.components.block
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material3.Card
@ -9,9 +9,10 @@ import androidx.compose.ui.Modifier
import com.tangem.core.ui.res.TangemTheme
@Composable
internal fun BlockCard(
fun BlockCard(
modifier: Modifier = Modifier,
enabled: Boolean = true,
colors: CardColors = TangemBlockCardColors,
onClick: () -> Unit = {},
content: @Composable ColumnScope.() -> Unit = {},
) {
@ -19,13 +20,13 @@ internal fun BlockCard(
modifier = modifier,
onClick = onClick,
shape = TangemTheme.shapes.roundedCornersXMedium,
colors = BlockColors,
colors = colors,
enabled = enabled,
content = content,
)
}
private val BlockColors: CardColors
val TangemBlockCardColors: CardColors
@Composable
@ReadOnlyComposable
get() = CardColors(

View file

@ -1,4 +1,4 @@
package com.tangem.features.details.ui
package com.tangem.core.ui.components.block
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
@ -11,12 +11,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import com.tangem.core.ui.components.block.model.BlockUM
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.details.entity.DetailsItemUM
@Composable
internal fun BlockItem(model: DetailsItemUM.Basic.Item, modifier: Modifier = Modifier) {
fun BlockItem(model: BlockUM, modifier: Modifier = Modifier) {
BlockCard(
modifier = modifier,
onClick = model.onClick,
@ -29,14 +29,22 @@ internal fun BlockItem(model: DetailsItemUM.Basic.Item, modifier: Modifier = Mod
Icon(
modifier = Modifier.size(TangemTheme.dimens.size24),
painter = painterResource(id = model.iconRes),
tint = TangemTheme.colors.icon.secondary,
tint = when (model.accentType) {
BlockUM.AccentType.NONE -> TangemTheme.colors.icon.secondary
BlockUM.AccentType.ACCENT -> TangemTheme.colors.text.accent
BlockUM.AccentType.WARNING -> TangemTheme.colors.text.warning
},
contentDescription = null,
)
Text(
text = model.title.resolveReference(),
text = model.text.resolveReference(),
style = TangemTheme.typography.subtitle1,
color = TangemTheme.colors.text.primary1,
color = when (model.accentType) {
BlockUM.AccentType.NONE -> TangemTheme.colors.text.primary1
BlockUM.AccentType.ACCENT -> TangemTheme.colors.text.accent
BlockUM.AccentType.WARNING -> TangemTheme.colors.text.warning
},
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)

View file

@ -0,0 +1,16 @@
package com.tangem.core.ui.components.block.model
import androidx.annotation.DrawableRes
import com.tangem.core.ui.extensions.TextReference
data class BlockUM(
val text: TextReference,
@DrawableRes val iconRes: Int,
val onClick: () -> Unit,
val accentType: AccentType = AccentType.NONE,
) {
enum class AccentType {
NONE, ACCENT, WARNING,
}
}

View file

@ -1,8 +1,7 @@
package com.tangem.features.details.entity
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.components.block.model.BlockUM
import kotlinx.collections.immutable.ImmutableList
@Immutable
@ -17,10 +16,7 @@ internal sealed class DetailsItemUM {
data class Item(
val id: String,
val title: TextReference,
@DrawableRes
val iconRes: Int,
val onClick: () -> Unit,
val block: BlockUM,
)
}

View file

@ -15,11 +15,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.ComposableContentComponent
import com.tangem.core.ui.components.appbar.models.TopAppBarMedium
import com.tangem.core.ui.components.block.BlockItem
import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.LocalSnackbarHostState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -29,8 +30,6 @@ import com.tangem.features.details.entity.DetailsItemUM
import com.tangem.features.details.entity.DetailsUM
import com.tangem.features.details.impl.R
private const val COLLAPSED_APP_BAR_THRESHOLD = 0.4f
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun DetailsScreen(
@ -52,7 +51,13 @@ internal fun DetailsScreen(
hostState = LocalSnackbarHostState.current,
)
},
topBar = { TopBar(state, scrollBehavior) },
topBar = {
TopAppBarMedium(
title = resourceReference(R.string.details_title),
scrollBehavior = scrollBehavior,
onBackClick = state.popBack,
)
},
) { paddingValues ->
Content(
modifier = Modifier.padding(paddingValues),
@ -62,54 +67,6 @@ internal fun DetailsScreen(
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TopBar(state: DetailsUM, scrollBehavior: TopAppBarScrollBehavior, modifier: Modifier = Modifier) {
MediumTopAppBar(
modifier = modifier,
scrollBehavior = scrollBehavior,
colors = TopAppBarColors(
containerColor = TangemTheme.colors.background.secondary,
scrolledContainerColor = TangemTheme.colors.background.secondary,
navigationIconContentColor = TangemTheme.colors.icon.primary1,
titleContentColor = TangemTheme.colors.text.primary1,
actionIconContentColor = TangemTheme.colors.icon.primary1,
),
title = {
val collapsedStyle = TangemTheme.typography.subtitle1
val expandedStyle = TangemTheme.typography.h1
val style by remember(scrollBehavior.state.collapsedFraction) {
derivedStateOf {
if (scrollBehavior.state.collapsedFraction >= COLLAPSED_APP_BAR_THRESHOLD) {
collapsedStyle
} else {
expandedStyle
}
}
}
Text(
text = stringResource(id = R.string.details_title),
style = style,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
navigationIcon = {
IconButton(
modifier = Modifier.size(TangemTheme.dimens.size32),
onClick = state.popBack,
) {
Icon(
modifier = Modifier.size(TangemTheme.dimens.size24),
painter = painterResource(id = R.drawable.ic_back_24),
contentDescription = null,
)
}
},
)
}
@Composable
private fun Content(
state: DetailsUM,
@ -168,7 +125,7 @@ private fun Block(
key(item.id) {
BlockItem(
modifier = itemModifier,
model = item,
model = item.block,
)
}
}

View file

@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import com.tangem.core.ui.components.block.BlockCard
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme

View file

@ -8,6 +8,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import com.tangem.core.ui.components.block.BlockCard
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.details.impl.R

View file

@ -6,6 +6,7 @@ import com.tangem.core.decompose.navigation.Router
import com.tangem.core.navigation.feedback.FeedbackManager
import com.tangem.core.navigation.feedback.FeedbackType
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.components.block.model.BlockUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.features.details.entity.DetailsItemUM
@ -48,9 +49,11 @@ internal class ItemsBuilder @Inject constructor(
items = persistentListOf(
DetailsItemUM.Basic.Item(
id = "buy_tangem_wallet",
title = resourceReference(R.string.details_buy_wallet),
iconRes = R.drawable.ic_tangem_24,
onClick = { urlOpener.openUrl(BUY_TANGEM_URL) },
block = BlockUM(
text = resourceReference(R.string.details_buy_wallet),
iconRes = R.drawable.ic_tangem_24,
onClick = { urlOpener.openUrl(BUY_TANGEM_URL) },
),
),
),
)
@ -60,17 +63,21 @@ internal class ItemsBuilder @Inject constructor(
items = buildList {
DetailsItemUM.Basic.Item(
id = "app_settings",
title = resourceReference(R.string.app_settings_title),
iconRes = R.drawable.ic_settings_24,
onClick = { router.push(AppRoute.AppSettings) },
block = BlockUM(
text = resourceReference(R.string.app_settings_title),
iconRes = R.drawable.ic_settings_24,
onClick = { router.push(AppRoute.AppSettings) },
),
).let(::add)
if (BuildConfig.TESTER_MENU_ENABLED) {
DetailsItemUM.Basic.Item(
id = "tester_menu",
title = stringReference(value = "Tester menu"),
iconRes = R.drawable.ic_alert_24,
onClick = { router.push(AppRoute.TesterMenu) },
block = BlockUM(
text = stringReference(value = "Tester menu"),
iconRes = R.drawable.ic_alert_24,
onClick = { router.push(AppRoute.TesterMenu) },
),
).let(::add)
}
}.toImmutableList(),
@ -81,15 +88,19 @@ internal class ItemsBuilder @Inject constructor(
items = persistentListOf(
DetailsItemUM.Basic.Item(
id = "send_feedback",
title = resourceReference(R.string.details_send_feedback),
iconRes = R.drawable.ic_comment_24,
onClick = { feedbackManager.sendEmail(FeedbackType.Feedback) },
block = BlockUM(
text = resourceReference(R.string.details_send_feedback),
iconRes = R.drawable.ic_comment_24,
onClick = { feedbackManager.sendEmail(FeedbackType.Feedback) },
),
),
DetailsItemUM.Basic.Item(
id = "disclaimer",
title = resourceReference(R.string.disclaimer_title),
iconRes = R.drawable.ic_text_24,
onClick = { router.push(AppRoute.Disclaimer(isTosAccepted = true)) },
block = BlockUM(
text = resourceReference(R.string.disclaimer_title),
iconRes = R.drawable.ic_text_24,
onClick = { router.push(AppRoute.Disclaimer(isTosAccepted = true)) },
),
),
),
)