Updated on 2026-08-14
This commit is contained in:
parent
6d69a5706a
commit
9c1931f7d7
81 changed files with 686 additions and 981 deletions
|
|
@ -14,10 +14,10 @@ import androidx.compose.ui.unit.sp
|
|||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
fun TextAutoSize(
|
||||
modifier: Modifier = Modifier,
|
||||
text: String,
|
||||
textStyle: TextStyle = LocalTextStyle.current,
|
||||
fontSizeRange: FontSizeRange,
|
||||
modifier: Modifier = Modifier,
|
||||
textStyle: TextStyle = LocalTextStyle.current,
|
||||
) {
|
||||
val fontSizeValue = remember { mutableStateOf(fontSizeRange.max.value) }
|
||||
val readyToDraw = remember { mutableStateOf(false) }
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ fun BlockchainSpinner(
|
|||
textFieldConverter: (Blockchain) -> String,
|
||||
dropdownItemView: @Composable ((Blockchain) -> Unit)? = null,
|
||||
closePopupTrigger: ClosePopupTrigger = ClosePopupTrigger(),
|
||||
onItemSelected: (Blockchain) -> Unit,
|
||||
onItemSelect: (Blockchain) -> Unit,
|
||||
) {
|
||||
OutlinedSpinner(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
|
@ -27,7 +27,7 @@ fun BlockchainSpinner(
|
|||
textFieldConverter = textFieldConverter,
|
||||
dropdownItemView = dropdownItemView,
|
||||
isEnabled = isEnabled,
|
||||
onItemSelected = onItemSelected,
|
||||
onItemSelected = onItemSelect,
|
||||
closePopupTrigger = closePopupTrigger,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,137 +1,8 @@
|
|||
package com.tangem.tap.common.compose
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.ripple.LocalRippleTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.components.SpacerH8
|
||||
import com.tangem.tap.common.compose.extensions.stringResourceDefault
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
fun RectangleButton(
|
||||
modifier: Modifier = Modifier,
|
||||
text: String = "",
|
||||
textId: Int? = null,
|
||||
isEnabled: Boolean = true,
|
||||
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
|
||||
leadingView: @Composable RowScope.() -> Unit = {},
|
||||
middleView: @Composable RowScope.() -> Unit = { TextInButton(text = text, textId = textId) },
|
||||
trailingView: @Composable RowScope.() -> Unit = {},
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Button(
|
||||
modifier = modifier,
|
||||
contentPadding = contentPadding,
|
||||
enabled = isEnabled,
|
||||
onClick = onClick,
|
||||
) {
|
||||
leadingView()
|
||||
middleView()
|
||||
trailingView()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TextInButton(
|
||||
modifier: Modifier = Modifier,
|
||||
text: String = "",
|
||||
textId: Int? = null,
|
||||
) {
|
||||
Text(
|
||||
modifier = modifier,
|
||||
text = stringResourceDefault(textId, text),
|
||||
maxLines = 1,
|
||||
style = TextStyle(
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 20.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PasteButton(
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
dpSize: DpSize = DpSize(40.dp, 40.dp),
|
||||
onClick: () -> Unit,
|
||||
tint: Color? = null,
|
||||
content: @Composable (() -> Unit)? = null
|
||||
) {
|
||||
IconButton(
|
||||
modifier = modifier.size(dpSize),
|
||||
enabled = enabled,
|
||||
onClick = onClick,
|
||||
) {
|
||||
when (content) {
|
||||
null -> {
|
||||
val tintColor = tint
|
||||
?: colorResource(id = if (enabled) R.color.button_positive else R.color.button_positive_disabled)
|
||||
Icon(
|
||||
painterResource(id = R.drawable.ic_paste),
|
||||
contentDescription = "Paste",
|
||||
tint = tintColor,
|
||||
)
|
||||
}
|
||||
else -> content()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ClearButton(
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
dpSize: DpSize = DpSize(40.dp, 40.dp),
|
||||
onClick: () -> Unit,
|
||||
tint: Color? = null,
|
||||
content: @Composable (() -> Unit)? = null
|
||||
) {
|
||||
IconButton(
|
||||
modifier = modifier.size(dpSize),
|
||||
enabled = enabled,
|
||||
onClick = onClick,
|
||||
) {
|
||||
when (content) {
|
||||
null -> {
|
||||
val tintColor = tint
|
||||
?: colorResource(id = if (enabled) R.color.button_positive else R.color.button_positive_disabled)
|
||||
Icon(
|
||||
painterResource(id = R.drawable.ic_clear),
|
||||
contentDescription = "Clear",
|
||||
tint = tintColor,
|
||||
)
|
||||
}
|
||||
else -> content()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for disable ripple if button is enable = false
|
||||
|
|
@ -143,34 +14,4 @@ fun ToggledRippleTheme(
|
|||
) {
|
||||
val theme = LocalRippleTheme provides if (isEnabled) LocalRippleTheme.current else NoRippleTheme()
|
||||
CompositionLocalProvider(theme) { content() }
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun ButtonTest() {
|
||||
Scaffold {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
PreviewItem("Button") {
|
||||
RectangleButton(text = "Some button") {}
|
||||
}
|
||||
PreviewItem("PasteButton") {
|
||||
PasteButton(onClick = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PreviewItem(
|
||||
name: String,
|
||||
content: @Composable RowScope.() -> Unit,
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = name,
|
||||
)
|
||||
content()
|
||||
}
|
||||
SpacerH8()
|
||||
}
|
||||
|
|
@ -11,19 +11,19 @@ import com.tangem.domain.common.util.ValueDebouncer
|
|||
@Composable
|
||||
fun <T> valueDebouncerAsState(
|
||||
initialValue: T,
|
||||
onValueChange: (T) -> Unit,
|
||||
debounce: Long = 600,
|
||||
onEmitValueReceived: (T) -> Unit = {},
|
||||
onValueChanged: (T) -> Unit,
|
||||
onEmitValueReceive: (T) -> Unit = {},
|
||||
): ValueDebouncer<T> {
|
||||
return remember {
|
||||
ValueDebouncer<T>(
|
||||
ValueDebouncer(
|
||||
initialValue = initialValue,
|
||||
debounceDuration = debounce,
|
||||
onEmitValueReceived = { emitValue ->
|
||||
emitValue?.let { onEmitValueReceived(it) }
|
||||
emitValue?.let { onEmitValueReceive(it) }
|
||||
},
|
||||
onValueChanged = { changedValue ->
|
||||
changedValue?.let { onValueChanged(it) }
|
||||
changedValue?.let { onValueChange(it) }
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -32,16 +32,16 @@ fun <T> valueDebouncerAsState(
|
|||
@Composable
|
||||
fun <T> valueDebouncerNullableAsState(
|
||||
initialValue: T?,
|
||||
onValueChange: (T?) -> Unit,
|
||||
debounce: Long = 400,
|
||||
onEmitValueReceived: (T?) -> Unit = {},
|
||||
onValueChanged: (T?) -> Unit,
|
||||
onEmitValueReceive: (T?) -> Unit = {},
|
||||
): ValueDebouncer<T?> {
|
||||
return remember {
|
||||
ValueDebouncer(
|
||||
initialValue = initialValue,
|
||||
debounceDuration = debounce,
|
||||
onEmitValueReceived = onEmitValueReceived,
|
||||
onValueChanged = onValueChanged,
|
||||
onEmitValueReceived = onEmitValueReceive,
|
||||
onValueChanged = onValueChange,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.Box
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.LocalTextStyle
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -19,23 +18,20 @@ import androidx.compose.ui.unit.dp
|
|||
fun ErrorView(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = LocalTextStyle.current
|
||||
style: TextStyle = LocalTextStyle.current,
|
||||
) {
|
||||
Text(
|
||||
text,
|
||||
color = MaterialTheme.colors.error,
|
||||
modifier = modifier,
|
||||
style = style
|
||||
style = style,
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun ErrorViewTest() {
|
||||
Scaffold(
|
||||
) {
|
||||
Box(Modifier.padding(16.dp)) {
|
||||
ErrorView(text = "Some error description")
|
||||
}
|
||||
private fun ErrorViewTest() {
|
||||
Box(Modifier.padding(16.dp)) {
|
||||
ErrorView(text = "Some error description")
|
||||
}
|
||||
}
|
||||
|
|
@ -21,11 +21,11 @@ import com.tangem.tap.common.extensions.ValueCallback
|
|||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun <T> OutlinedSpinner(
|
||||
modifier: Modifier = Modifier,
|
||||
label: String,
|
||||
itemList: List<T>,
|
||||
selectedItem: Field.Data<T>,
|
||||
onItemSelected: ValueCallback<T>,
|
||||
modifier: Modifier = Modifier,
|
||||
textFieldConverter: (T) -> String = { it.toString() },
|
||||
dropdownItemView: @Composable ((T) -> Unit)? = null,
|
||||
isEnabled: Boolean = true,
|
||||
|
|
@ -96,13 +96,11 @@ class ClosePopupTrigger {
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun TestSpinnerPreview() {
|
||||
Scaffold {
|
||||
OutlinedSpinner(
|
||||
label = "Blockchain name",
|
||||
itemList = listOf(Blockchain.values()),
|
||||
selectedItem = Field.Data(Blockchain.Avalanche, false),
|
||||
onItemSelected = {},
|
||||
)
|
||||
}
|
||||
private fun TestSpinnerPreview() {
|
||||
OutlinedSpinner(
|
||||
label = "Blockchain name",
|
||||
itemList = listOf(Blockchain.values()),
|
||||
selectedItem = Field.Data(Blockchain.Avalanche, false),
|
||||
onItemSelected = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.LinearProgressIndicator
|
||||
import androidx.compose.material.OutlinedTextField
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextFieldColors
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -41,7 +40,6 @@ import com.tangem.tap.domain.moduleMessage.ModuleMessageConverter
|
|||
*/
|
||||
@Composable
|
||||
fun OutlinedTextFieldWidget(
|
||||
modifier: Modifier = Modifier,
|
||||
fieldData: Field.Data<String>,
|
||||
labelId: Int? = null,
|
||||
label: String = "",
|
||||
|
|
@ -56,15 +54,12 @@ fun OutlinedTextFieldWidget(
|
|||
debounceTextChanges: Long = 400,
|
||||
visualTransformation: VisualTransformation = VisualTransformation.None,
|
||||
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
|
||||
onTextChanged: (String) -> Unit,
|
||||
onTextChange: (String) -> Unit,
|
||||
) {
|
||||
if (!isVisible) return
|
||||
|
||||
Column(
|
||||
modifier = modifier.animateContentSize(),
|
||||
) {
|
||||
Column(modifier = Modifier.animateContentSize()) {
|
||||
OutlinedProgressTextField(
|
||||
modifier = modifier,
|
||||
fieldData = fieldData,
|
||||
label = stringResourceDefault(labelId, label),
|
||||
placeholder = stringResourceDefault(placeholderId, placeholder),
|
||||
|
|
@ -75,16 +70,15 @@ fun OutlinedTextFieldWidget(
|
|||
debounce = debounceTextChanges,
|
||||
visualTransformation = visualTransformation,
|
||||
keyboardOptions = keyboardOptions,
|
||||
onTextChanged = onTextChanged,
|
||||
onTextChange = onTextChange,
|
||||
)
|
||||
errorConverter?.let { AnimatedErrorView(error, it) }
|
||||
errorConverter?.let { AnimatedErrorView(errorConverter = it, error = error) }
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod", "NestedBlockDepth", "MagicNumber", "MaxLineLength")
|
||||
@Composable
|
||||
private fun OutlinedProgressTextField(
|
||||
modifier: Modifier = Modifier,
|
||||
fieldData: Field.Data<String>,
|
||||
label: String = "",
|
||||
placeholder: String = "",
|
||||
|
|
@ -97,7 +91,7 @@ private fun OutlinedProgressTextField(
|
|||
colors: TextFieldColors = TangemTextFieldsDefault.defaultTextFieldColors,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
trailingIcon: @Composable (() -> Unit)? = null,
|
||||
onTextChanged: (String) -> Unit,
|
||||
onTextChange: (String) -> Unit,
|
||||
) {
|
||||
val logger = remember {
|
||||
CompositionLogger(label, "OutlinedProgressTextField", listOf("Символ токена"))
|
||||
|
|
@ -108,14 +102,14 @@ private fun OutlinedProgressTextField(
|
|||
val textDebouncer = valueDebouncerAsState(
|
||||
initialValue = fieldData.value,
|
||||
debounce = debounce,
|
||||
onEmitValueReceived = {
|
||||
onEmitValueReceive = {
|
||||
logger.log("DEBOUNCER: onEmitValueReceived: [$it]")
|
||||
logger.log("DEBOUNCER: start RECOMPOSE by new value for textValueState.value = [$it]")
|
||||
textValueState.value = it
|
||||
},
|
||||
onValueChanged = {
|
||||
onValueChange = {
|
||||
logger.log("DEBOUNCER: onValueChanged: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dispatch.toStore([$it])")
|
||||
onTextChanged(it)
|
||||
onTextChange(it)
|
||||
},
|
||||
)
|
||||
|
||||
|
|
@ -194,7 +188,7 @@ private fun OutlinedProgressTextField(
|
|||
interactionSource = interactionSource,
|
||||
)
|
||||
AnimatedVisibility(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(start = 6.dp, top = 0.dp, end = 6.dp, bottom = 6.dp),
|
||||
|
|
@ -209,8 +203,8 @@ private fun OutlinedProgressTextField(
|
|||
|
||||
@Composable
|
||||
private fun AnimatedErrorView(
|
||||
error: ModuleError? = null,
|
||||
errorConverter: ModuleMessageConverter,
|
||||
error: ModuleError? = null,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = error != null,
|
||||
|
|
@ -228,7 +222,7 @@ private fun AnimatedErrorView(
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun OutlinedTextFieldWithErrorTest() {
|
||||
private fun OutlinedTextFieldWithErrorTest() {
|
||||
val context = LocalContext.current
|
||||
val converter = remember { ModuleMessageConverter(context) }
|
||||
|
||||
|
|
@ -241,41 +235,35 @@ fun OutlinedTextFieldWithErrorTest() {
|
|||
val modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
Scaffold {
|
||||
Column {
|
||||
OutlinedTextFieldWidget(
|
||||
modifier = modifier,
|
||||
fieldData = Field.Data("", false),
|
||||
label = "First label",
|
||||
placeholder = "1 placeholder",
|
||||
error = null,
|
||||
errorConverter = converter,
|
||||
) {}
|
||||
OutlinedTextFieldWidget(
|
||||
modifier = modifier,
|
||||
fieldData = Field.Data("First", false),
|
||||
label = "First label",
|
||||
placeholder = "1 placeholder",
|
||||
error = null,
|
||||
errorConverter = converter,
|
||||
) {}
|
||||
OutlinedTextFieldWidget(
|
||||
modifier = modifier,
|
||||
fieldData = Field.Data("First", false),
|
||||
label = "First label",
|
||||
placeholder = "1 placeholder",
|
||||
isLoading = true,
|
||||
error = null,
|
||||
errorConverter = converter,
|
||||
) {}
|
||||
OutlinedTextFieldWidget(
|
||||
modifier = modifier,
|
||||
fieldData = Field.Data("First", false),
|
||||
label = "First label",
|
||||
placeholder = "1 placeholder",
|
||||
error = SimpleError(),
|
||||
errorConverter = converter,
|
||||
) {}
|
||||
}
|
||||
Column {
|
||||
OutlinedTextFieldWidget(
|
||||
fieldData = Field.Data("", false),
|
||||
label = "First label",
|
||||
placeholder = "1 placeholder",
|
||||
error = null,
|
||||
errorConverter = converter,
|
||||
) {}
|
||||
OutlinedTextFieldWidget(
|
||||
fieldData = Field.Data("First", false),
|
||||
label = "First label",
|
||||
placeholder = "1 placeholder",
|
||||
error = null,
|
||||
errorConverter = converter,
|
||||
) {}
|
||||
OutlinedTextFieldWidget(
|
||||
fieldData = Field.Data("First", false),
|
||||
label = "First label",
|
||||
placeholder = "1 placeholder",
|
||||
isLoading = true,
|
||||
error = null,
|
||||
errorConverter = converter,
|
||||
) {}
|
||||
OutlinedTextFieldWidget(
|
||||
fieldData = Field.Data("First", false),
|
||||
label = "First label",
|
||||
placeholder = "1 placeholder",
|
||||
error = SimpleError(),
|
||||
errorConverter = converter,
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ import androidx.core.text.isDigitsOnly
|
|||
@Composable
|
||||
fun PinCodeWidget(
|
||||
config: PinViewConfig = tangemPinConfig,
|
||||
onPinChanged: (String, Boolean) -> Unit = { pin, isLastSymbolEntered -> },
|
||||
onPinChange: (String, Boolean) -> Unit = { pin, isLastSymbolEntered -> },
|
||||
) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
|
|
@ -65,7 +65,7 @@ fun PinCodeWidget(
|
|||
|
||||
if (value.text.length <= config.pinsCount) {
|
||||
rTextFieldValue.value = value
|
||||
onPinChanged(value.text, isLastSymbolEntered())
|
||||
onPinChange(value.text, isLastSymbolEntered())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ private val tangemPinConfig = PinViewConfig(
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PinCodeWidgetPreview() {
|
||||
private fun PinCodeWidgetPreview() {
|
||||
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
|
||||
PinCodeWidget(tangemPinConfig)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ import com.tangem.wallet.R
|
|||
*/
|
||||
@Composable
|
||||
fun AddCustomTokenWarning(
|
||||
modifier: Modifier = Modifier,
|
||||
warning: ModuleMessage,
|
||||
converter: ModuleMessageConverter
|
||||
converter: ModuleMessageConverter,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ import com.tangem.tap.common.extensions.getFromClipboard
|
|||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Suppress("ComposableFunctionName")
|
||||
@Composable
|
||||
fun copyToClipboard(value: Any, label: String = "") {
|
||||
LocalContext.current.copyToClipboard(value, label)
|
||||
}
|
||||
|
||||
@Suppress("ComposableFunctionName")
|
||||
@Composable
|
||||
fun getFromClipboard(default: CharSequence? = null): CharSequence? {
|
||||
return LocalContext.current.getFromClipboard(default)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
package com.tangem.tap.common.compose.extensions
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import com.tangem.tap.common.extensions.hideKeyboard
|
||||
|
||||
@Composable
|
||||
fun LazyListState.OnBottomReached(loadMoreThreshold: Int, loadMore: () -> Unit) {
|
||||
fun LazyListState.OnBottomReached(loadMoreThreshold: Int, onLoadMore: () -> Unit) {
|
||||
require(loadMoreThreshold >= 0)
|
||||
val shouldLoadMore by remember {
|
||||
derivedStateOf {
|
||||
|
|
@ -17,7 +21,7 @@ fun LazyListState.OnBottomReached(loadMoreThreshold: Int, loadMore: () -> Unit)
|
|||
}
|
||||
|
||||
LaunchedEffect(shouldLoadMore) {
|
||||
if (shouldLoadMore) loadMore()
|
||||
if (shouldLoadMore) onLoadMore()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class AppSettingsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
TangemTheme {
|
||||
AppSettingsScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = {
|
||||
onBackClick = {
|
||||
store.dispatch(DetailsAction.ResetCardSettingsData)
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
},
|
||||
|
|
|
|||
|
|
@ -31,25 +31,16 @@ import com.tangem.tap.features.details.ui.common.TangemSwitch
|
|||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
fun AppSettingsScreen(
|
||||
state: AppSettingsScreenState,
|
||||
onBackPressed: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun AppSettingsScreen(state: AppSettingsScreenState, onBackClick: () -> Unit) {
|
||||
SettingsScreensScaffold(
|
||||
content = {
|
||||
AppSettings(state = state, modifier = modifier)
|
||||
},
|
||||
content = { AppSettings(state = state) },
|
||||
titleRes = R.string.app_settings_title,
|
||||
onBackClick = onBackPressed,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AppSettings(
|
||||
state: AppSettingsScreenState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
private fun AppSettings(state: AppSettingsScreenState) {
|
||||
var dialogType by remember { mutableStateOf<PrivacySetting?>(null) }
|
||||
val onDialogStateChange: (PrivacySetting?) -> Unit = { dialogType = it }
|
||||
|
||||
|
|
@ -57,21 +48,13 @@ private fun AppSettings(
|
|||
SettingsAlertDialog(
|
||||
element = it,
|
||||
onDialogStateChange = onDialogStateChange,
|
||||
onSettingToggled = state.onSettingToggled,
|
||||
onSettingToggle = { state.onSettingToggled(it, false) },
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxSize()) {
|
||||
if (state.showEnrollBiometricsCard) {
|
||||
EnrollBiometricsCard(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing8)
|
||||
.fillMaxWidth(),
|
||||
onClick = state.onEnrollBiometrics,
|
||||
)
|
||||
EnrollBiometricsCard(onClick = state.onEnrollBiometrics)
|
||||
SpacerH24()
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +75,6 @@ private fun AppSettings(
|
|||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun AppSettingsElement(
|
||||
modifier: Modifier = Modifier,
|
||||
state: AppSettingsScreenState,
|
||||
setting: PrivacySetting,
|
||||
onDialogStateChange: (PrivacySetting?) -> Unit,
|
||||
|
|
@ -123,7 +105,7 @@ private fun AppSettingsElement(
|
|||
)
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = TangemTheme.dimens.spacing20),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
|
|
@ -195,7 +177,7 @@ private fun AppSettingsScreenSample(
|
|||
onSettingToggled = { _, _ -> },
|
||||
onEnrollBiometrics = {},
|
||||
),
|
||||
onBackPressed = { },
|
||||
onBackClick = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -220,10 +202,7 @@ private fun AppSettingsScreenPreview_Dark() {
|
|||
private fun AppSettingsScreen_EnrollBiometrics_Sample(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.primary),
|
||||
) {
|
||||
Column(modifier = modifier.background(TangemTheme.colors.background.primary)) {
|
||||
AppSettingsScreen(
|
||||
state = AppSettingsScreenState(
|
||||
settings = mapOf(
|
||||
|
|
@ -235,7 +214,7 @@ private fun AppSettingsScreen_EnrollBiometrics_Sample(
|
|||
onSettingToggled = { _, _ -> },
|
||||
onEnrollBiometrics = {},
|
||||
),
|
||||
onBackPressed = { },
|
||||
onBackClick = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
|
|
@ -23,12 +24,11 @@ import com.tangem.wallet.R
|
|||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
internal fun EnrollBiometricsCard(
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
internal fun EnrollBiometricsCard(onClick: () -> Unit) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing8)
|
||||
.fillMaxWidth(),
|
||||
color = TangemTheme.colors.background.primary,
|
||||
shape = TangemTheme.shapes.roundedCornersLarge,
|
||||
onClick = onClick,
|
||||
|
|
@ -67,8 +67,7 @@ private fun EnrollBiometricsCardSample(
|
|||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.secondary),
|
||||
modifier = modifier.background(TangemTheme.colors.background.secondary),
|
||||
) {
|
||||
EnrollBiometricsCard(onClick = {})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ import com.tangem.wallet.R
|
|||
internal fun SettingsAlertDialog(
|
||||
element: PrivacySetting,
|
||||
onDialogStateChange: (PrivacySetting?) -> Unit,
|
||||
onSettingToggled: (PrivacySetting, Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onSettingToggle: () -> Unit
|
||||
) {
|
||||
val text = when (element) {
|
||||
PrivacySetting.SaveWallets -> R.string.app_settings_off_saved_wallet_alert_message
|
||||
|
|
@ -43,7 +42,7 @@ internal fun SettingsAlertDialog(
|
|||
text = stringResource(id = R.string.common_delete),
|
||||
onClick = {
|
||||
onDialogStateChange(null)
|
||||
onSettingToggled(element, false)
|
||||
onSettingToggle()
|
||||
},
|
||||
)
|
||||
},
|
||||
|
|
@ -62,7 +61,6 @@ internal fun SettingsAlertDialog(
|
|||
)
|
||||
},
|
||||
shape = TangemTheme.shapes.roundedCornersLarge,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +76,7 @@ private fun SettingsAlertDialogSample(
|
|||
SettingsAlertDialog(
|
||||
element = PrivacySetting.SaveAccessCode,
|
||||
onDialogStateChange = {},
|
||||
onSettingToggled = { _, _ -> },
|
||||
onSettingToggle = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class CardSettingsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
TangemTheme {
|
||||
CardSettingsScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = {
|
||||
onBackClick = {
|
||||
store.dispatch(DetailsAction.ResetCardSettingsData)
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,44 +30,36 @@ import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
|||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
fun CardSettingsScreen(
|
||||
state: CardSettingsScreenState,
|
||||
onBackPressed: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun CardSettingsScreen(state: CardSettingsScreenState, onBackClick: () -> Unit) {
|
||||
val needReadCard = state.cardDetails == null
|
||||
|
||||
SettingsScreensScaffold(
|
||||
content = {
|
||||
if (needReadCard) {
|
||||
CardSettingsReadCard(state.onScanCardClick, modifier = modifier)
|
||||
CardSettingsReadCard(state.onScanCardClick)
|
||||
} else {
|
||||
CardSettings(state = state, modifier = modifier)
|
||||
CardSettings(state = state)
|
||||
}
|
||||
},
|
||||
titleRes = R.string.card_settings_title,
|
||||
backgroundColor = TangemTheme.colors.background.secondary,
|
||||
onBackClick = onBackPressed,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
fun CardSettingsReadCard(
|
||||
onScanCardClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun CardSettingsReadCard(onScanCardClick: () -> Unit) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 40.dp),
|
||||
) {
|
||||
Image(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 80.dp, end = 80.dp, top = 70.dp)
|
||||
.rotate(-15f),
|
||||
|
|
@ -76,7 +68,7 @@ fun CardSettingsReadCard(
|
|||
contentScale = ContentScale.FillWidth,
|
||||
)
|
||||
Image(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 60.dp, end = 60.dp)
|
||||
.rotate(-1f),
|
||||
|
|
@ -87,7 +79,7 @@ fun CardSettingsReadCard(
|
|||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Column(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 32.dp),
|
||||
) {
|
||||
|
|
@ -96,20 +88,19 @@ fun CardSettingsReadCard(
|
|||
color = colorResource(id = R.color.text_primary_1),
|
||||
style = TangemTypography.headline3,
|
||||
)
|
||||
Spacer(modifier = modifier.size(20.dp))
|
||||
Spacer(modifier = Modifier.size(20.dp))
|
||||
Text(
|
||||
text = stringResource(id = R.string.scan_card_settings_message),
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
style = TangemTypography.body1,
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.weight(weight = 1f, fill = false),
|
||||
)
|
||||
Spacer(modifier = modifier.size(29.dp))
|
||||
Spacer(modifier = Modifier.size(29.dp))
|
||||
DetailsMainButton(
|
||||
title = stringResource(id = R.string.scan_card_settings_button),
|
||||
onClick = onScanCardClick,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -117,15 +108,11 @@ fun CardSettingsReadCard(
|
|||
|
||||
@Suppress("ComplexMethod")
|
||||
@Composable
|
||||
fun CardSettings(
|
||||
state: CardSettingsScreenState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun CardSettings(state: CardSettingsScreenState) {
|
||||
if (state.cardDetails == null) return
|
||||
|
||||
LazyColumn(
|
||||
modifier = modifier
|
||||
.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
items(state.cardDetails) {
|
||||
val paddingBottom = when (it) {
|
||||
|
|
@ -144,7 +131,7 @@ fun CardSettings(
|
|||
is CardInfo.ResetToFactorySettings -> 16.dp
|
||||
}
|
||||
Column(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
enabled = it.clickable,
|
||||
|
|
@ -167,7 +154,7 @@ fun CardSettings(
|
|||
color = titleColor,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
Spacer(modifier = modifier.size(4.dp))
|
||||
Spacer(modifier = Modifier.size(4.dp))
|
||||
Text(
|
||||
text = it.subtitle.resolveReference(),
|
||||
color = subtitleColor,
|
||||
|
|
@ -180,6 +167,6 @@ fun CardSettings(
|
|||
|
||||
@Composable
|
||||
@Preview
|
||||
fun CardSettingsPreview() {
|
||||
private fun CardSettingsPreview() {
|
||||
CardSettingsScreen(state = CardSettingsScreenState(onScanCardClick = {}) {}, {})
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.Column
|
|||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
|
|
@ -90,12 +90,10 @@ fun ScreenTitle(
|
|||
|
||||
@Composable
|
||||
fun EmptyTopBarWithNavigation(
|
||||
modifier: Modifier = Modifier,
|
||||
onBackClick: () -> Unit,
|
||||
backgroundColor: Color = TangemTheme.colors.background.primary,
|
||||
) {
|
||||
TopAppBar(
|
||||
modifier = modifier,
|
||||
title = { },
|
||||
navigationIcon =
|
||||
{
|
||||
|
|
@ -114,16 +112,16 @@ fun EmptyTopBarWithNavigation(
|
|||
|
||||
@Composable
|
||||
fun DetailsMainButton(
|
||||
modifier: Modifier = Modifier,
|
||||
title: String,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
onClick: (() -> Unit),
|
||||
) {
|
||||
Button(
|
||||
onClick = onClick,
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.height(48.dp),
|
||||
.heightIn(48.dp),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
enabled = enabled,
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
|
|
@ -134,7 +132,9 @@ fun DetailsMainButton(
|
|||
),
|
||||
) {
|
||||
Text(text = title)
|
||||
Spacer(modifier = modifier.size(8.dp))
|
||||
Spacer(modifier = Modifier
|
||||
.padding(start = 20.dp, end = 20.dp)
|
||||
.size(8.dp))
|
||||
Icon(painter = painterResource(id = R.drawable.ic_tangem_24), contentDescription = "")
|
||||
}
|
||||
}
|
||||
|
|
@ -33,13 +33,12 @@ import com.tangem.wallet.R
|
|||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
fun TangemSwitch(
|
||||
modifier: Modifier = Modifier,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
checkedColor: Color = colorResource(id = R.color.control_checked),
|
||||
uncheckedColor: Color = colorResource(id = R.color.icon_informative),
|
||||
size: Dp = 48.dp,
|
||||
checked: Boolean = false,
|
||||
enabled: Boolean = true,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
) {
|
||||
val transition = updateTransition(checked, label = "SwitchState")
|
||||
val color by transition.animateColor(
|
||||
|
|
@ -53,7 +52,7 @@ fun TangemSwitch(
|
|||
val interactionSource = remember { MutableInteractionSource() }
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
interactionSource = interactionSource,
|
||||
indication = null,
|
||||
|
|
@ -70,7 +69,7 @@ fun TangemSwitch(
|
|||
),
|
||||
) {
|
||||
BoxWithConstraints(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.width(size)
|
||||
.height(size / 2)
|
||||
.indication(interactionSource, null)
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.analytics.events.Settings
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
|
|
@ -43,7 +43,7 @@ class DetailsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
TangemTheme {
|
||||
DetailsScreen(
|
||||
state = detailsScreenState.value,
|
||||
onBackPressed = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
onBackClick = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,66 +33,52 @@ import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
|||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
fun DetailsScreen(
|
||||
state: DetailsScreenState,
|
||||
onBackPressed: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun DetailsScreen(state: DetailsScreenState, onBackClick: () -> Unit) {
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(color = TangemColorPalette.Light1)
|
||||
}
|
||||
|
||||
SettingsScreensScaffold(
|
||||
content = { Content(state = state, modifier = modifier) },
|
||||
onBackClick = onBackPressed,
|
||||
content = { Content(state = state) },
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Content(
|
||||
state: DetailsScreenState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun Content(state: DetailsScreenState) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
ScreenTitle(titleRes = R.string.details_title, modifier.padding(bottom = 52.dp))
|
||||
state.elements.map {
|
||||
if (it == SettingsElement.WalletConnect) {
|
||||
WalletConnectDetailsItem(
|
||||
onItemsClick = state.onItemsClick,
|
||||
modifier = modifier,
|
||||
)
|
||||
ScreenTitle(titleRes = R.string.details_title, Modifier.padding(bottom = 52.dp))
|
||||
state.elements.map { element ->
|
||||
if (element == SettingsElement.WalletConnect) {
|
||||
WalletConnectDetailsItem(onItemsClick = state.onItemsClick)
|
||||
} else {
|
||||
DetailsItem(
|
||||
item = it,
|
||||
item = element,
|
||||
appCurrency = state.appCurrency,
|
||||
onItemsClick = state.onItemsClick,
|
||||
modifier = modifier,
|
||||
onItemsClick = { state.onItemsClick(element) },
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = modifier.weight(1f))
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
TangemSocialAccounts(state.tangemLinks, state.onSocialNetworkClick)
|
||||
Spacer(modifier = Modifier.size(12.dp))
|
||||
Text(
|
||||
text = "${stringResource(id = state.appNameRes)} ${state.tangemVersion}",
|
||||
style = TangemTypography.caption,
|
||||
color = colorResource(id = R.color.text_tertiary),
|
||||
modifier = modifier.padding(start = 16.dp, end = 16.dp, bottom = 40.dp),
|
||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 40.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun WalletConnectDetailsItem(
|
||||
onItemsClick: (SettingsElement) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun WalletConnectDetailsItem(onItemsClick: (SettingsElement) -> Unit) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.defaultMinSize(minHeight = 84.dp)
|
||||
.fillMaxWidth()
|
||||
.clickable { onItemsClick(SettingsElement.WalletConnect) },
|
||||
|
|
@ -102,23 +88,23 @@ fun WalletConnectDetailsItem(
|
|||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_walletconnect),
|
||||
contentDescription = stringResource(id = R.string.wallet_connect_title),
|
||||
modifier = modifier.padding(start = 20.dp, end = 20.dp),
|
||||
modifier = Modifier.padding(start = 20.dp, end = 20.dp),
|
||||
tint = colorResource(id = R.color.all_colors_azure),
|
||||
)
|
||||
Column(
|
||||
modifier = modifier.defaultMinSize(minHeight = 56.dp),
|
||||
modifier = Modifier.defaultMinSize(minHeight = 56.dp),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.wallet_connect_title),
|
||||
modifier = modifier.padding(end = 20.dp, bottom = 4.dp),
|
||||
modifier = Modifier.padding(end = 20.dp, bottom = 4.dp),
|
||||
style = TangemTypography.headline3,
|
||||
color = colorResource(id = R.color.text_primary_1),
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.wallet_connect_subtitle),
|
||||
modifier = modifier.padding(end = 20.dp, bottom = 4.dp),
|
||||
modifier = Modifier.padding(end = 20.dp, bottom = 4.dp),
|
||||
style = TangemTypography.body1,
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
)
|
||||
|
|
@ -127,37 +113,31 @@ fun WalletConnectDetailsItem(
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun DetailsItem(
|
||||
item: SettingsElement,
|
||||
appCurrency: String,
|
||||
onItemsClick: (SettingsElement) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun DetailsItem(item: SettingsElement, appCurrency: String, onItemsClick: () -> Unit) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.height(56.dp)
|
||||
.fillMaxWidth()
|
||||
.clickable { onItemsClick(item) },
|
||||
.clickable(onClick = onItemsClick),
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = item.iconRes),
|
||||
contentDescription = stringResource(id = item.titleRes),
|
||||
modifier = modifier.padding(start = 20.dp, end = 20.dp),
|
||||
modifier = Modifier.padding(start = 20.dp, end = 20.dp),
|
||||
tint = colorResource(id = R.color.icon_secondary),
|
||||
)
|
||||
Column(modifier = modifier.padding(end = 20.dp)) {
|
||||
Column(modifier = Modifier.padding(end = 20.dp)) {
|
||||
Text(
|
||||
text = stringResource(id = item.titleRes),
|
||||
modifier = modifier,
|
||||
modifier = Modifier,
|
||||
style = TangemTypography.subtitle1,
|
||||
color = colorResource(id = R.color.text_primary_1),
|
||||
)
|
||||
if (item == SettingsElement.AppCurrency) {
|
||||
Text(
|
||||
text = appCurrency,
|
||||
modifier = modifier,
|
||||
style = TangemTypography.body2,
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
)
|
||||
|
|
@ -170,16 +150,13 @@ fun DetailsItem(
|
|||
fun TangemSocialAccounts(
|
||||
links: List<SocialNetworkLink>,
|
||||
onSocialNetworkClick: (SocialNetworkLink) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
LazyRow(
|
||||
modifier = modifier.padding(start = 8.dp, end = 8.dp),
|
||||
) {
|
||||
LazyRow(modifier = Modifier.padding(start = 8.dp, end = 8.dp)) {
|
||||
items(links) {
|
||||
Icon(
|
||||
painter = painterResource(id = it.network.iconRes),
|
||||
contentDescription = "",
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.clickable { onSocialNetworkClick(it) },
|
||||
tint = colorResource(id = R.color.icon_informative),
|
||||
|
|
@ -190,7 +167,7 @@ fun TangemSocialAccounts(
|
|||
|
||||
@Composable
|
||||
@Preview
|
||||
fun Preview() {
|
||||
private fun Preview() {
|
||||
DetailsScreen(
|
||||
state = DetailsScreenState(
|
||||
elements = SettingsElement.values().toList(),
|
||||
|
|
@ -199,6 +176,6 @@ fun Preview() {
|
|||
appCurrency = "Dollar",
|
||||
onItemsClick = {}, onSocialNetworkClick = {},
|
||||
),
|
||||
onBackPressed = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ class ResetCardFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
TangemTheme {
|
||||
ResetCardScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
onBackClick = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@ import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
|||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
fun ResetCardScreen(state: ResetCardScreenState, onBackPressed: () -> Unit) {
|
||||
fun ResetCardScreen(state: ResetCardScreenState, onBackClick: () -> Unit) {
|
||||
SettingsScreensScaffold(
|
||||
content = { ResetCardView(state = state) },
|
||||
onBackClick = onBackPressed,
|
||||
onBackClick = onBackClick,
|
||||
backgroundColor = Color.Transparent,
|
||||
)
|
||||
}
|
||||
|
|
@ -148,7 +148,7 @@ private fun ResetCardScreenSample(
|
|||
onAcceptWarningToggleClick = {},
|
||||
onResetButtonClick = {},
|
||||
),
|
||||
onBackPressed = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class SecurityModeFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
TangemTheme {
|
||||
SecurityModeScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
onBackClick = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,36 +28,28 @@ import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
|||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
fun SecurityModeScreen(
|
||||
state: SecurityModeScreenState,
|
||||
onBackPressed: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun SecurityModeScreen(state: SecurityModeScreenState, onBackClick: () -> Unit) {
|
||||
SettingsScreensScaffold(
|
||||
content = { SecurityModeOptions(state = state, modifier = modifier) },
|
||||
content = { SecurityModeOptions(state = state) },
|
||||
// titleRes = R.string.card_settings_security_mode,
|
||||
onBackClick = onBackPressed,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SecurityModeOptions(
|
||||
state: SecurityModeScreenState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
||||
fun SecurityModeOptions(state: SecurityModeScreenState) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(bottom = 28.dp),
|
||||
verticalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
ScreenTitle(titleRes = R.string.card_settings_security_mode, modifier.padding(bottom = 36.dp))
|
||||
ScreenTitle(titleRes = R.string.card_settings_security_mode, Modifier.padding(bottom = 36.dp))
|
||||
|
||||
|
||||
state.availableOptions.map {
|
||||
SecurityOption(option = it, state = state, modifier = modifier)
|
||||
SecurityOption(option = it, state = state)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
|
@ -66,17 +58,13 @@ fun SecurityModeOptions(
|
|||
title = stringResource(id = R.string.common_save_changes),
|
||||
enabled = state.isSaveChangesEnabled,
|
||||
onClick = state.onSaveChangesClicked,
|
||||
modifier = modifier
|
||||
.padding(start = 20.dp, end = 20.dp),
|
||||
modifier = Modifier.padding(start = 20.dp, end = 20.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SecurityOption(
|
||||
option: SecurityOption, state: SecurityModeScreenState,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
fun SecurityOption(option: SecurityOption, state: SecurityModeScreenState) {
|
||||
val selected = option == state.selectedSecurityMode
|
||||
|
||||
val title = option.toTitleRes()
|
||||
|
|
@ -88,7 +76,7 @@ fun SecurityOption(
|
|||
}
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.selectable(
|
||||
selected = selected, onClick = { state.onNewModeSelected(option) },
|
||||
|
|
@ -98,7 +86,7 @@ fun SecurityOption(
|
|||
|
||||
RadioButton(
|
||||
selected = selected, onClick = null,
|
||||
modifier = modifier.padding(end = 20.dp),
|
||||
modifier = Modifier.padding(end = 20.dp),
|
||||
colors = RadioButtonDefaults.colors(
|
||||
unselectedColor = colorResource(id = R.color.icon_secondary),
|
||||
selectedColor = colorResource(id = R.color.icon_accent),
|
||||
|
|
@ -111,7 +99,7 @@ fun SecurityOption(
|
|||
style = TangemTypography.subtitle1,
|
||||
color = colorResource(id = R.color.text_primary_1),
|
||||
)
|
||||
Spacer(modifier = modifier.size(4.dp))
|
||||
Spacer(modifier = Modifier.size(4.dp))
|
||||
Text(
|
||||
text = stringResource(id = subtitle),
|
||||
style = TangemTypography.body2,
|
||||
|
|
@ -123,7 +111,7 @@ fun SecurityOption(
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun SecurityModeScreenPreview() {
|
||||
private fun SecurityModeScreenPreview() {
|
||||
SecurityModeScreen(
|
||||
state = SecurityModeScreenState(
|
||||
availableOptions = SecurityOption.values().toList(),
|
||||
|
|
@ -132,6 +120,6 @@ fun SecurityModeScreenPreview() {
|
|||
onNewModeSelected = {},
|
||||
onSaveChangesClicked = {},
|
||||
),
|
||||
onBackPressed = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ class WalletConnectFragment : Fragment(), StoreSubscriber<WalletConnectState> {
|
|||
TangemTheme {
|
||||
WalletConnectScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = {
|
||||
onBackClick = {
|
||||
if (screenState.value.isLoading) {
|
||||
store.dispatch(
|
||||
WalletConnectAction.FailureEstablishingSession(
|
||||
|
|
|
|||
|
|
@ -38,19 +38,15 @@ import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
|||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
fun WalletConnectScreen(
|
||||
state: WalletConnectScreenState,
|
||||
onBackPressed: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun WalletConnectScreen(state: WalletConnectScreenState, onBackClick: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
|
||||
SettingsScreensScaffold(
|
||||
content = {
|
||||
if (state.sessions.isEmpty()) {
|
||||
EmptyScreen(state, modifier)
|
||||
EmptyScreen(state)
|
||||
} else {
|
||||
WalletConnectSessions(state, modifier)
|
||||
WalletConnectSessions(state)
|
||||
}
|
||||
},
|
||||
fab = {
|
||||
|
|
@ -64,7 +60,7 @@ fun WalletConnectScreen(
|
|||
}
|
||||
},
|
||||
titleRes = R.string.wallet_connect_title,
|
||||
onBackClick = onBackPressed,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -88,15 +84,15 @@ private fun AddSessionFab(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun EmptyScreen(state: WalletConnectScreenState, modifier: Modifier = Modifier) {
|
||||
private fun EmptyScreen(state: WalletConnectScreenState) {
|
||||
if (state.isLoading) {
|
||||
LinearProgressIndicator(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = colorResource(id = R.color.icon_accent),
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(bottom = 64.dp),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
|
|
@ -107,10 +103,9 @@ private fun EmptyScreen(state: WalletConnectScreenState, modifier: Modifier = Mo
|
|||
contentDescription = "",
|
||||
colorFilter = ColorFilter.tint(colorResource(id = R.color.icon_inactive)),
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = modifier
|
||||
.width(width = 100.dp),
|
||||
modifier = Modifier.width(width = 100.dp),
|
||||
)
|
||||
Spacer(modifier = modifier.size(24.dp))
|
||||
Spacer(modifier = Modifier.size(24.dp))
|
||||
Text(
|
||||
text = stringResource(id = R.string.wallet_connect_subtitle),
|
||||
style = TangemTypography.body2,
|
||||
|
|
@ -120,28 +115,25 @@ private fun EmptyScreen(state: WalletConnectScreenState, modifier: Modifier = Mo
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun WalletConnectSessions(
|
||||
state: WalletConnectScreenState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
private fun WalletConnectSessions(state: WalletConnectScreenState) {
|
||||
if (state.isLoading) {
|
||||
LinearProgressIndicator(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(2.dp),
|
||||
color = colorResource(id = R.color.icon_accent),
|
||||
)
|
||||
} else {
|
||||
Spacer(modifier = modifier.height(2.dp))
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
items(state.sessions) { session ->
|
||||
Row(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 20.dp, vertical = 16.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
|
|
@ -151,7 +143,7 @@ private fun WalletConnectSessions(
|
|||
text = session.description,
|
||||
style = TangemTypography.subtitle1,
|
||||
color = colorResource(id = R.color.text_primary_1),
|
||||
modifier = modifier.weight(1f),
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
IconButton(
|
||||
onClick = {
|
||||
|
|
@ -172,7 +164,7 @@ private fun WalletConnectSessions(
|
|||
|
||||
@Composable
|
||||
@Preview
|
||||
fun WalletConnectScreenPreview() {
|
||||
private fun WalletConnectScreenPreview() {
|
||||
WalletConnectScreen(
|
||||
state = WalletConnectScreenState(
|
||||
sessions = listOf(
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ class HomeFragment : Fragment(), StoreSubscriber<HomeState> {
|
|||
homeState.value = state
|
||||
}
|
||||
|
||||
@Suppress("TopLevelComposableFunctions")
|
||||
@Composable
|
||||
private fun ScreenContent() {
|
||||
StoriesScreen(
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
|||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.statusBars
|
||||
|
|
@ -59,7 +60,7 @@ private const val STEPS = 6
|
|||
@Suppress("LongMethod", "ComplexMethod")
|
||||
@Composable
|
||||
fun StoriesScreen(
|
||||
homeState: MutableState<HomeState> = mutableStateOf(HomeState()),
|
||||
homeState: MutableState<HomeState>,
|
||||
onScanButtonClick: () -> Unit,
|
||||
onShopButtonClick: () -> Unit,
|
||||
onSearchTokensClick: () -> Unit,
|
||||
|
|
@ -157,7 +158,7 @@ fun StoriesScreen(
|
|||
currentStep = currentStep.value,
|
||||
stepDuration = currentStep.duration(),
|
||||
paused = isPaused,
|
||||
onStepFinished = goToNextScreen,
|
||||
onStepFinish = goToNextScreen,
|
||||
)
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.ic_tangem_logo),
|
||||
|
|
@ -191,7 +192,7 @@ fun StoriesScreen(
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.height(48.dp),
|
||||
.heightIn(48.dp),
|
||||
colors = ButtonDefaults.textButtonColors(
|
||||
backgroundColor = Color.White,
|
||||
contentColor = Color(0xFF080C10),
|
||||
|
|
@ -230,6 +231,11 @@ private fun MutableState<Int>.duration(): Int = when (this.value) {
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun StoriesScreenPreview() {
|
||||
StoriesScreen(onScanButtonClick = {}, onShopButtonClick = {}, onSearchTokensClick = {})
|
||||
private fun StoriesScreenPreview() {
|
||||
StoriesScreen(
|
||||
onScanButtonClick = {},
|
||||
onShopButtonClick = {},
|
||||
onSearchTokensClick = {},
|
||||
homeState = remember { mutableStateOf(HomeState()) },
|
||||
)
|
||||
}
|
||||
|
|
@ -216,9 +216,9 @@ private fun StoriesSubtitleText(subtitleText: AnnotatedString) {
|
|||
|
||||
@Composable
|
||||
private fun StoriesImage(
|
||||
modifier: Modifier = Modifier,
|
||||
@DrawableRes drawableResId: Int,
|
||||
isDarkBackground: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = drawableResId),
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@ import com.tangem.wallet.R
|
|||
@Suppress("LongMethod", "ComplexMethod", "MagicNumber")
|
||||
@Composable
|
||||
fun FirstStoriesContent(
|
||||
isPaused: Boolean, duration: Int = 8_000,
|
||||
hideContent: (Boolean) -> Unit,
|
||||
isPaused: Boolean,
|
||||
duration: Int,
|
||||
onHideContent: (Boolean) -> Unit,
|
||||
) {
|
||||
val screenState = remember { mutableStateOf(StartingScreenState.INIT) }
|
||||
val progress = remember { Animatable(0f) }
|
||||
|
|
@ -70,8 +71,8 @@ fun FirstStoriesContent(
|
|||
in 1.2f..2f -> screenState.value = StartingScreenState.MEET_TANGEM
|
||||
}
|
||||
|
||||
if (screenState.value == StartingScreenState.INIT) hideContent(true)
|
||||
if (screenState.value == StartingScreenState.BUY) hideContent(false)
|
||||
if (screenState.value == StartingScreenState.INIT) onHideContent(true)
|
||||
if (screenState.value == StartingScreenState.BUY) onHideContent(false)
|
||||
|
||||
val style = TextStyle(
|
||||
fontSize = 60.sp,
|
||||
|
|
@ -166,6 +167,6 @@ private fun MutableState<StartingScreenState>.isMeetTangemDisplaying(): Boolean
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun FirstStoriesPreview() {
|
||||
private fun FirstStoriesPreview() {
|
||||
FirstStoriesContent(false, 8000) {}
|
||||
}
|
||||
|
|
@ -49,6 +49,7 @@ private data class CardValues(
|
|||
|
||||
private object FloatingCard {
|
||||
|
||||
@Suppress("TopLevelComposableFunctions")
|
||||
@Composable
|
||||
fun Item(
|
||||
isPaused: Boolean,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ package com.tangem.tap.features.home.compose.views
|
|||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
|
|
@ -22,11 +24,11 @@ import com.tangem.wallet.R
|
|||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
fun HomeButtons(
|
||||
modifier: Modifier = Modifier,
|
||||
isDarkBackground: Boolean,
|
||||
btnScanStateInProgress: Boolean,
|
||||
onScanButtonClick: () -> Unit,
|
||||
onShopButtonClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val darkColorBackground = Color(0xFF26292E)
|
||||
val darkColorButton = Color(0xFF080C10)
|
||||
|
|
@ -36,9 +38,6 @@ fun HomeButtons(
|
|||
modifier = modifier,
|
||||
) {
|
||||
ProgressButton(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.height(48.dp),
|
||||
inProgress = btnScanStateInProgress,
|
||||
backgroundColor = if (isDarkBackground) darkColorBackground else Color.White,
|
||||
contentColor = if (isDarkBackground) Color.White else darkColorButton,
|
||||
|
|
@ -64,7 +63,7 @@ fun HomeButtons(
|
|||
Button(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.height(48.dp),
|
||||
.heightIn(48.dp),
|
||||
onClick = onShopButtonClick,
|
||||
enabled = !btnScanStateInProgress,
|
||||
colors = ButtonDefaults.textButtonColors(
|
||||
|
|
@ -85,8 +84,7 @@ fun HomeButtons(
|
|||
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
fun ProgressButton(
|
||||
modifier: Modifier,
|
||||
fun RowScope.ProgressButton(
|
||||
backgroundColor: Color,
|
||||
contentColor: Color,
|
||||
onClick: () -> Unit,
|
||||
|
|
@ -95,7 +93,9 @@ fun ProgressButton(
|
|||
content: @Composable () -> Unit,
|
||||
) {
|
||||
Button(
|
||||
modifier = modifier,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.height(48.dp),
|
||||
onClick = onClick,
|
||||
colors = ButtonDefaults.textButtonColors(
|
||||
backgroundColor = backgroundColor,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ fun StoriesProgressBar(
|
|||
currentStep: Int,
|
||||
paused: Boolean = false,
|
||||
stepDuration: Int = 8_000,
|
||||
onStepFinished: () -> Unit = {},
|
||||
onStepFinish: () -> Unit = {},
|
||||
) {
|
||||
val progress = remember(currentStep) { Animatable(0f) }
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ fun StoriesProgressBar(
|
|||
)
|
||||
)
|
||||
progress.snapTo(0f)
|
||||
onStepFinished()
|
||||
onStepFinish()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -81,6 +81,6 @@ fun StoriesProgressBar(
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun StoriesProgressBarPreview() {
|
||||
private fun StoriesProgressBarPreview() {
|
||||
StoriesProgressBar(steps = 3, currentStep = 2, paused = false) { }
|
||||
}
|
||||
|
|
@ -40,8 +40,8 @@ internal class SaveWalletBottomSheetFragment : ComposeBottomSheetFragment<SaveWa
|
|||
|
||||
@Composable
|
||||
override fun ScreenContent(
|
||||
modifier: Modifier,
|
||||
state: SaveWalletScreenState,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference())
|
||||
|
|
@ -73,12 +73,10 @@ internal class SaveWalletBottomSheetFragment : ComposeBottomSheetFragment<SaveWa
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("TopLevelComposableFunctions")
|
||||
@Composable
|
||||
private fun EnrollBiometricsDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
dialog: EnrollBiometricsDialog?,
|
||||
) {
|
||||
private fun EnrollBiometricsDialog(dialog: EnrollBiometricsDialog?) {
|
||||
if (dialog == null) return
|
||||
EnrollBiometricsDialogContent(modifier, dialog)
|
||||
EnrollBiometricsDialogContent(dialog)
|
||||
}
|
||||
}
|
||||
|
|
@ -21,13 +21,10 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.tap.features.saveWallet.ui.models.EnrollBiometricsDialog
|
||||
|
||||
@Composable
|
||||
fun EnrollBiometricsDialogContent(
|
||||
modifier: Modifier = Modifier,
|
||||
dialog: EnrollBiometricsDialog,
|
||||
) {
|
||||
fun EnrollBiometricsDialogContent(dialog: EnrollBiometricsDialog) {
|
||||
Dialog(onDismissRequest = dialog.onCancel) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.background(
|
||||
shape = TangemTheme.shapes.roundedCornersLarge,
|
||||
color = TangemTheme.colors.background.plain,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
|
|
@ -33,19 +32,12 @@ import com.tangem.wallet.R
|
|||
|
||||
@Composable
|
||||
internal fun SaveWalletScreenContent(
|
||||
modifier: Modifier = Modifier,
|
||||
showProgress: Boolean,
|
||||
onSaveWalletClick: () -> Unit,
|
||||
onCloseClick: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Header(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onCloseClick = onCloseClick,
|
||||
)
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Header(onCloseClick = onCloseClick)
|
||||
SpacerHHalf()
|
||||
Title(
|
||||
modifier = Modifier
|
||||
|
|
@ -62,9 +54,6 @@ internal fun SaveWalletScreenContent(
|
|||
)
|
||||
SpacerHHalf()
|
||||
Footer(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.fillMaxWidth(),
|
||||
showProgress = showProgress,
|
||||
onSaveWalletClick = onSaveWalletClick,
|
||||
)
|
||||
|
|
@ -73,12 +62,9 @@ internal fun SaveWalletScreenContent(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun Header(
|
||||
modifier: Modifier = Modifier,
|
||||
onCloseClick: () -> Unit,
|
||||
) {
|
||||
private fun Header(onCloseClick: () -> Unit, ) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
Hand()
|
||||
|
|
@ -150,12 +136,13 @@ private fun Description(
|
|||
|
||||
@Composable
|
||||
private fun Footer(
|
||||
modifier: Modifier = Modifier,
|
||||
showProgress: Boolean,
|
||||
onSaveWalletClick: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
|
|
@ -177,13 +164,11 @@ private fun Footer(
|
|||
|
||||
@Composable
|
||||
private fun DescriptionItem(
|
||||
modifier: Modifier = Modifier,
|
||||
iconPainter: Painter,
|
||||
title: String,
|
||||
description: String,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.Top,
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
) {
|
||||
|
|
@ -220,13 +205,6 @@ private fun SaveWalletScreenContentSample(
|
|||
.background(TangemTheme.colors.background.primary),
|
||||
) {
|
||||
SaveWalletScreenContent(
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.spacing32)
|
||||
.fillMaxSize()
|
||||
.background(
|
||||
color = TangemTheme.colors.background.plain,
|
||||
shape = TangemTheme.shapes.bottomSheet,
|
||||
),
|
||||
showProgress = false,
|
||||
onSaveWalletClick = { /* no-op */ },
|
||||
onCloseClick = { /* no-op */ },
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import com.tangem.domain.redux.domainStore
|
|||
*/
|
||||
@Composable
|
||||
fun ContractAddressTests(
|
||||
onItemClick: VoidCallback
|
||||
onItemClick: VoidCallback,
|
||||
) {
|
||||
val casesInfo = listOf(
|
||||
"USDC on ETH" to "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
|
||||
|
|
@ -38,7 +38,7 @@ fun ContractAddressTests(
|
|||
|
||||
@Composable
|
||||
fun SolanaAddressTests(
|
||||
onItemClick: VoidCallback
|
||||
onItemClick: VoidCallback,
|
||||
) {
|
||||
val casesInfo = listOf(
|
||||
"USDT (full)" to "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
|
||||
|
|
@ -54,70 +54,84 @@ private fun CasesListContent(
|
|||
casesList: List<Pair<String, String>>,
|
||||
onItemClick: VoidCallback,
|
||||
) {
|
||||
LazyColumn(content = {
|
||||
item {
|
||||
Row() {
|
||||
ResetContractAddressButton(onItemClick)
|
||||
Text("", modifier = Modifier.weight(1f))
|
||||
ResetAllFieldsButton(onItemClick)
|
||||
LazyColumn(
|
||||
content = {
|
||||
item {
|
||||
Row {
|
||||
ResetContractAddressButton(onItemClick)
|
||||
Text("", modifier = Modifier.weight(1f))
|
||||
ResetAllFieldsButton(onItemClick)
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
items(casesList.size) {
|
||||
val (info, address) = casesList[it]
|
||||
ContractAddressButton(info, address, onItemClick)
|
||||
}
|
||||
})
|
||||
items(casesList.size) {
|
||||
val (info, address) = casesList[it]
|
||||
ContractAddressButton(info, address, onItemClick)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ResetAllFieldsButton(
|
||||
onItemClick: VoidCallback
|
||||
) {
|
||||
ActionButton(name = "Reset") {
|
||||
onItemClick()
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenContractAddressChanged(Field.Data("", false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenNetworkChanged(Field.Data(Blockchain.Unknown, false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenNameChanged(Field.Data("", false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenSymbolChanged(Field.Data("", false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenDecimalsChanged(Field.Data("", false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenDerivationPathChanged(Field.Data(Blockchain.Unknown, false)))
|
||||
}
|
||||
fun ResetAllFieldsButton(onItemClick: VoidCallback) {
|
||||
ActionButton(
|
||||
name = "Reset",
|
||||
onClick = {
|
||||
onItemClick()
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenContractAddressChanged(Field.Data("", false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenNetworkChanged(Field.Data(Blockchain.Unknown, false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenNameChanged(Field.Data("", false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenSymbolChanged(Field.Data("", false)))
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenDecimalsChanged(Field.Data("", false)))
|
||||
domainStore.dispatch(
|
||||
AddCustomTokenAction.OnTokenDerivationPathChanged(
|
||||
Field.Data(
|
||||
Blockchain.Unknown,
|
||||
false,
|
||||
),
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ResetContractAddressButton(
|
||||
onItemClick: VoidCallback
|
||||
onItemClick: VoidCallback,
|
||||
) {
|
||||
ActionButton(name = "Set empty address") {
|
||||
onItemClick()
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenContractAddressChanged(Field.Data("", false)))
|
||||
}
|
||||
ActionButton(
|
||||
name = "Set empty address",
|
||||
onClick = {
|
||||
onItemClick()
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenContractAddressChanged(Field.Data("", false)))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContractAddressButton(
|
||||
name: String,
|
||||
address: String,
|
||||
onItemClick: VoidCallback
|
||||
onItemClick: VoidCallback,
|
||||
) {
|
||||
ActionButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
name = name,
|
||||
) {
|
||||
onItemClick()
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenContractAddressChanged(Field.Data(address, false)))
|
||||
}
|
||||
onClick = {
|
||||
onItemClick()
|
||||
domainStore.dispatch(AddCustomTokenAction.OnTokenContractAddressChanged(Field.Data(address, false)))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ActionButton(
|
||||
modifier: Modifier = Modifier,
|
||||
name: String,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Button(
|
||||
modifier = modifier.padding(horizontal = 8.dp),
|
||||
onClick = onClick
|
||||
onClick = onClick,
|
||||
) { Text(name, fontSize = 12.sp) }
|
||||
}
|
||||
|
|
@ -19,30 +19,19 @@ import com.tangem.wallet.R
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
fun TestCasesList(
|
||||
onItemClick: (TestCase) -> Unit
|
||||
) {
|
||||
fun TestCasesList(onItemClick: (TestCase) -> Unit) {
|
||||
if (!BuildConfig.TEST_ACTION_ENABLED) return
|
||||
|
||||
Surface(
|
||||
color = colorResource(id = R.color.lightGray5)
|
||||
) {
|
||||
Column(
|
||||
Modifier.padding(horizontal = 16.dp)
|
||||
) {
|
||||
listOf(
|
||||
TestCase.ContractAddress,
|
||||
TestCase.SolanaTokens,
|
||||
).map { TestCaseListItem(it, onItemClick) }
|
||||
Surface(color = colorResource(id = R.color.lightGray5)) {
|
||||
Column(Modifier.padding(horizontal = 16.dp)) {
|
||||
listOf(TestCase.ContractAddress, TestCase.SolanaTokens)
|
||||
.map { case -> TestCaseListItem(testCase = case, onItemClick = { onItemClick(case) }) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TestCaseListItem(
|
||||
testCase: TestCase,
|
||||
onItemClick: (TestCase) -> Unit,
|
||||
) {
|
||||
fun TestCaseListItem(testCase: TestCase, onItemClick: () -> Unit) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
|
|
@ -51,7 +40,7 @@ fun TestCaseListItem(
|
|||
text = testCase.description,
|
||||
)
|
||||
Button(
|
||||
onClick = { onItemClick(testCase) }
|
||||
onClick = onItemClick,
|
||||
) { Text("Start") }
|
||||
}
|
||||
}
|
||||
|
|
@ -59,5 +48,6 @@ fun TestCaseListItem(
|
|||
enum class TestCase(val description: String, val content: @Composable (VoidCallback) -> Unit) {
|
||||
ContractAddress("Test contract address field", { ContractAddressTests(it) }),
|
||||
Auto("Test contract address field", { ContractAddressTests(it) }),
|
||||
SolanaTokens("Test Solana contract addresses", { SolanaAddressTests(it) }), ;
|
||||
SolanaTokens("Test Solana contract addresses", { SolanaAddressTests(it) }),
|
||||
;
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ class AddTokensFragment : BaseFragment(R.layout.fragment_add_tokens), StoreSubsc
|
|||
CurrenciesScreen(
|
||||
tokensState = tokensState,
|
||||
onSaveChanges = onSaveChanges,
|
||||
onNetworkItemClicked = onNetworkItemClicked,
|
||||
onNetworkItemClick = onNetworkItemClicked,
|
||||
onLoadMore = onLoadMore,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ import com.tangem.wallet.R
|
|||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
fun CurrenciesScreen(
|
||||
tokensState: MutableState<TokensState> = mutableStateOf(store.state.tokensState),
|
||||
tokensState: MutableState<TokensState>,
|
||||
onSaveChanges: (List<TokenWithBlockchain>, List<Blockchain>) -> Unit,
|
||||
onNetworkItemClicked: (ContractAddress) -> Unit,
|
||||
onNetworkItemClick: (ContractAddress) -> Unit,
|
||||
onLoadMore: () -> Unit,
|
||||
) {
|
||||
val tokensAddedOnMainScreen = remember { tokensState.value.addedTokens }
|
||||
|
|
@ -123,10 +123,10 @@ fun CurrenciesScreen(
|
|||
addedTokens = addedTokensState.value,
|
||||
addedBlockchains = addedBlockchainsState.value,
|
||||
allowToAdd = tokensState.value.allowToAdd,
|
||||
onAddCurrencyToggled = { currency, token ->
|
||||
onAddCurrencyToggle = { currency, token ->
|
||||
onAddCurrencyToggleClick(currency, token)
|
||||
},
|
||||
onNetworkItemClicked = onNetworkItemClicked,
|
||||
onNetworkItemClick = onNetworkItemClick,
|
||||
onLoadMore = onLoadMore,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ fun ListOfCurrencies(
|
|||
addedTokens: List<TokenWithBlockchain>,
|
||||
addedBlockchains: List<Blockchain>,
|
||||
allowToAdd: Boolean,
|
||||
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit,
|
||||
onNetworkItemClicked: (ContractAddress) -> Unit,
|
||||
onAddCurrencyToggle: (Currency, TokenWithBlockchain?) -> Unit,
|
||||
onNetworkItemClick: (ContractAddress) -> Unit,
|
||||
onLoadMore: () -> Unit,
|
||||
) {
|
||||
|
||||
|
|
@ -56,16 +56,16 @@ fun ListOfCurrencies(
|
|||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
item { header() }
|
||||
itemsIndexed(currencies) { index, currency ->
|
||||
itemsIndexed(currencies) { _, currency ->
|
||||
CurrencyItem(
|
||||
currency = currency,
|
||||
addedTokens = addedTokens,
|
||||
addedBlockchains = addedBlockchains,
|
||||
allowToAdd = allowToAdd,
|
||||
isExpanded = expandedCurrencies.value.contains(currency.id),
|
||||
onCurrencyClick = onCurrencyClick,
|
||||
onAddCurrencyToggled = onAddCurrencyToggled,
|
||||
onNetworkItemClicked = onNetworkItemClicked,
|
||||
onCurrencyClick = { onCurrencyClick(currency.id) },
|
||||
onAddCurrencyToggle = onAddCurrencyToggle,
|
||||
onNetworkItemClick = onNetworkItemClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ fun CurrencyExpandedContent(
|
|||
addedBlockchains: List<Blockchain>,
|
||||
allowToAdd: Boolean,
|
||||
isExpanded: Boolean,
|
||||
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit,
|
||||
onNetworkItemClicked: (ContractAddress) -> Unit,
|
||||
onAddCurrencyToggle: (Currency, TokenWithBlockchain?) -> Unit,
|
||||
onNetworkItemClick: (ContractAddress) -> Unit,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = isExpanded,
|
||||
|
|
@ -51,8 +51,8 @@ fun CurrencyExpandedContent(
|
|||
added = added,
|
||||
index = index,
|
||||
size = blockchains.size,
|
||||
onAddCurrencyToggled = onAddCurrencyToggled,
|
||||
onNetworkItemClicked = onNetworkItemClicked,
|
||||
onAddCurrencyToggle = onAddCurrencyToggle,
|
||||
onNetworkItemClick = onNetworkItemClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ fun CurrencyItem(
|
|||
addedBlockchains: List<Blockchain>,
|
||||
allowToAdd: Boolean,
|
||||
isExpanded: Boolean,
|
||||
onCurrencyClick: (String) -> Unit,
|
||||
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit,
|
||||
onNetworkItemClicked: (ContractAddress) -> Unit,
|
||||
onCurrencyClick: () -> Unit,
|
||||
onAddCurrencyToggle: (Currency, TokenWithBlockchain?) -> Unit,
|
||||
onNetworkItemClick: (ContractAddress) -> Unit,
|
||||
) {
|
||||
Column {
|
||||
CurrencyItemHeader(
|
||||
|
|
@ -33,8 +33,8 @@ fun CurrencyItem(
|
|||
addedBlockchains = addedBlockchains,
|
||||
allowToAdd = allowToAdd,
|
||||
isExpanded = isExpanded,
|
||||
onAddCurrencyToggled = onAddCurrencyToggled,
|
||||
onNetworkItemClicked = onNetworkItemClicked,
|
||||
onAddCurrencyToggle = onAddCurrencyToggle,
|
||||
onNetworkItemClick = onNetworkItemClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -68,11 +68,8 @@ private fun LastArrowView(rowHeight: Dp) {
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
fun ArrowViewPreview() {
|
||||
Box(
|
||||
Modifier
|
||||
.background(color = Color.White),
|
||||
) {
|
||||
private fun ArrowViewPreview() {
|
||||
Box(Modifier.background(color = Color.White)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ fun CurrencyItemHeader(
|
|||
addedTokens: List<TokenWithBlockchain>,
|
||||
addedBlockchains: List<Blockchain>,
|
||||
isExpanded: Boolean,
|
||||
onCurrencyClick: (String) -> Unit,
|
||||
onCurrencyClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
|
|
@ -56,7 +56,7 @@ fun CurrencyItemHeader(
|
|||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = { onCurrencyClick(currency.id) },
|
||||
onClick = onCurrencyClick,
|
||||
),
|
||||
) {
|
||||
Box(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.compose.foundation.layout.Row
|
|||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
|
|
@ -52,19 +52,19 @@ fun NetworkItem(
|
|||
added: Boolean,
|
||||
index: Int,
|
||||
size: Int,
|
||||
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit,
|
||||
onNetworkItemClicked: (ContractAddress) -> Unit,
|
||||
onAddCurrencyToggle: (Currency, TokenWithBlockchain?) -> Unit,
|
||||
onNetworkItemClick: (ContractAddress) -> Unit,
|
||||
) {
|
||||
val rowHeight = 53.dp
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(rowHeight)
|
||||
.heightIn(rowHeight)
|
||||
.combinedClickable(
|
||||
enabled = allowToAdd,
|
||||
onLongClick = {
|
||||
contract.address?.let { onNetworkItemClicked(it) }
|
||||
contract.address?.let { onNetworkItemClick(it) }
|
||||
},
|
||||
onClick = {},
|
||||
indication = null,
|
||||
|
|
@ -150,7 +150,7 @@ fun NetworkItem(
|
|||
.fillMaxHeight()
|
||||
.padding(start = 16.dp, end = 16.dp),
|
||||
checked = added,
|
||||
onCheckedChange = { onAddCurrencyToggled(currencyToSave, tokenWithBlockchain) },
|
||||
onCheckedChange = { onAddCurrencyToggle(currencyToSave, tokenWithBlockchain) },
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = Color(0xFF1ACE80),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.ui.fragments.ComposeBottomSheetFragment
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.MyWallets
|
||||
import com.tangem.tap.features.details.ui.cardsettings.resolveReference
|
||||
import com.tangem.tap.features.walletSelector.ui.components.RenameWalletDialogContent
|
||||
|
|
@ -45,7 +45,7 @@ internal class WalletSelectorBottomSheetFragment : ComposeBottomSheetFragment<Wa
|
|||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
override fun ScreenContent(modifier: Modifier, state: WalletSelectorScreenState) {
|
||||
override fun ScreenContent(state: WalletSelectorScreenState, modifier: Modifier) {
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference())
|
||||
val renameWalletDialog by rememberUpdatedState(newValue = state.renameWalletDialog)
|
||||
|
|
@ -81,9 +81,10 @@ internal class WalletSelectorBottomSheetFragment : ComposeBottomSheetFragment<Wa
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("TopLevelComposableFunctions")
|
||||
@Composable
|
||||
private fun RenameWalletDialog(modifier: Modifier = Modifier, dialog: RenameWalletDialog?) {
|
||||
private fun RenameWalletDialog(dialog: RenameWalletDialog?) {
|
||||
if (dialog == null) return
|
||||
RenameWalletDialogContent(modifier, dialog)
|
||||
RenameWalletDialogContent(dialog)
|
||||
}
|
||||
}
|
||||
|
|
@ -27,13 +27,10 @@ import com.tangem.tap.features.walletSelector.ui.model.RenameWalletDialog
|
|||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
internal fun RenameWalletDialogContent(
|
||||
modifier: Modifier = Modifier,
|
||||
dialog: RenameWalletDialog,
|
||||
) {
|
||||
internal fun RenameWalletDialogContent(dialog: RenameWalletDialog) {
|
||||
Dialog(onDismissRequest = dialog.onCancel) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.background(
|
||||
shape = TangemTheme.shapes.roundedCornersLarge,
|
||||
color = TangemTheme.colors.background.plain,
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ internal fun WalletSelectorScreenContent(
|
|||
wallet = wallet,
|
||||
isSelected = remember(state.selectedUserWalletId) { wallet.id == state.selectedUserWalletId },
|
||||
isChecked = remember(state.editingUserWalletsIds) { wallet.id in state.editingUserWalletsIds },
|
||||
onWalletClick = onWalletClick,
|
||||
onWalletLongClick = onWalletLongClick,
|
||||
onWalletClick = { onWalletClick(wallet.id) },
|
||||
onWalletLongClick = { onWalletLongClick(wallet.id) },
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -90,20 +90,13 @@ internal fun WalletSelectorScreenContent(
|
|||
wallet = wallet,
|
||||
isSelected = remember(state.selectedUserWalletId) { wallet.id == state.selectedUserWalletId },
|
||||
isChecked = remember(state.editingUserWalletsIds) { wallet.id in state.editingUserWalletsIds },
|
||||
onWalletClick = onWalletClick,
|
||||
onWalletLongClick = onWalletLongClick,
|
||||
onWalletClick = { onWalletClick(wallet.id) },
|
||||
onWalletLongClick = { onWalletLongClick(wallet.id) },
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
Footer(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
top = dimensionResource(id = R.dimen.spacing24),
|
||||
bottom = dimensionResource(id = R.dimen.spacing16),
|
||||
)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.fillMaxWidth(),
|
||||
isLocked = state.isLocked,
|
||||
showUnlockProgress = state.showUnlockProgress,
|
||||
showAddCardProgress = state.showAddCardProgress,
|
||||
|
|
@ -141,9 +134,6 @@ private fun Header(
|
|||
) {
|
||||
if (hasEditingWallets) {
|
||||
EditWalletsBar(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.fillMaxWidth(),
|
||||
editingWalletsSize = editingWalletsSize,
|
||||
onClearSelectedClick = onClearSelectedClick,
|
||||
onEditSelectedWalletClick = onEditSelectedWalletClick,
|
||||
|
|
@ -175,7 +165,6 @@ private fun WalletsTitle(@StringRes textResId: Int, wallets: List<*>) {
|
|||
|
||||
@Composable
|
||||
private fun Footer(
|
||||
modifier: Modifier = Modifier,
|
||||
isLocked: Boolean,
|
||||
showUnlockProgress: Boolean,
|
||||
showAddCardProgress: Boolean,
|
||||
|
|
@ -183,7 +172,13 @@ private fun Footer(
|
|||
onAddCardClick: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
top = dimensionResource(id = R.dimen.spacing24),
|
||||
bottom = dimensionResource(id = R.dimen.spacing16),
|
||||
)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
if (isLocked) {
|
||||
|
|
@ -209,7 +204,6 @@ private fun Footer(
|
|||
|
||||
@Composable
|
||||
private fun EditWalletsBar(
|
||||
modifier: Modifier = Modifier,
|
||||
editingWalletsSize: Int,
|
||||
onClearSelectedClick: () -> Unit,
|
||||
onEditSelectedWalletClick: () -> Unit,
|
||||
|
|
@ -220,7 +214,9 @@ private fun EditWalletsBar(
|
|||
}
|
||||
|
||||
Row(
|
||||
modifier = modifier,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import com.tangem.core.ui.components.SpacerH2
|
|||
import com.tangem.core.ui.components.SpacerW6
|
||||
import com.tangem.core.ui.components.SpacerW8
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.tap.common.compose.TangemTypography
|
||||
import com.tangem.tap.features.walletSelector.ui.model.MultiCurrencyUserWalletItem
|
||||
import com.tangem.tap.features.walletSelector.ui.model.SingleCurrencyUserWalletItem
|
||||
|
|
@ -42,14 +41,14 @@ internal fun WalletItem(
|
|||
wallet: UserWalletItem,
|
||||
isSelected: Boolean,
|
||||
isChecked: Boolean,
|
||||
onWalletClick: (UserWalletId) -> Unit,
|
||||
onWalletLongClick: (UserWalletId) -> Unit,
|
||||
onWalletClick: () -> Unit,
|
||||
onWalletLongClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.combinedClickable(
|
||||
onClick = { onWalletClick(wallet.id) },
|
||||
onLongClick = { onWalletLongClick(wallet.id) },
|
||||
onClick = onWalletClick,
|
||||
onLongClick = onWalletLongClick,
|
||||
)
|
||||
.height(72.dp)
|
||||
.padding(all = TangemTheme.dimens.spacing16),
|
||||
|
|
@ -61,14 +60,9 @@ internal fun WalletItem(
|
|||
isSelected = isSelected,
|
||||
)
|
||||
SpacerW8()
|
||||
WalletInfo(
|
||||
modifier = Modifier.weight(weight = .6f),
|
||||
wallet = wallet,
|
||||
isSelected = isSelected,
|
||||
)
|
||||
WalletInfo(wallet = wallet, isSelected = isSelected)
|
||||
SpacerW6()
|
||||
TokensInfo(
|
||||
modifier = Modifier.weight(weight = .4f),
|
||||
isLocked = wallet.isLocked,
|
||||
balance = wallet.balance,
|
||||
tokensCount = (wallet as? MultiCurrencyUserWalletItem)?.tokensCount,
|
||||
|
|
@ -78,13 +72,12 @@ internal fun WalletItem(
|
|||
|
||||
@Composable
|
||||
private fun WalletCardImage(
|
||||
modifier: Modifier = Modifier,
|
||||
cardImageUrl: String,
|
||||
isChecked: Boolean,
|
||||
isSelected: Boolean,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.width(TangemTheme.dimens.size62)
|
||||
.height(TangemTheme.dimens.size42),
|
||||
) {
|
||||
|
|
@ -133,13 +126,12 @@ private fun WalletCardImage(
|
|||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
private fun WalletInfo(
|
||||
modifier: Modifier = Modifier,
|
||||
private fun RowScope.WalletInfo(
|
||||
wallet: UserWalletItem,
|
||||
isSelected: Boolean,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
modifier = Modifier.weight(weight = .6f),
|
||||
verticalArrangement = Arrangement.SpaceAround,
|
||||
) {
|
||||
Text(
|
||||
|
|
@ -166,14 +158,13 @@ private fun WalletInfo(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun TokensInfo(
|
||||
modifier: Modifier = Modifier,
|
||||
private fun RowScope.TokensInfo(
|
||||
isLocked: Boolean,
|
||||
balance: UserWalletItem.Balance,
|
||||
tokensCount: Int?,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
modifier = Modifier.weight(weight = .4f),
|
||||
verticalArrangement = Arrangement.SpaceAround,
|
||||
horizontalAlignment = Alignment.End,
|
||||
) {
|
||||
|
|
@ -181,9 +172,7 @@ private fun TokensInfo(
|
|||
LockedPlaceholder()
|
||||
} else {
|
||||
if (balance.isLoading) {
|
||||
LoadingTokensInfo(
|
||||
isMultiCurrencyWallet = tokensCount != null,
|
||||
)
|
||||
LoadingTokensInfo(isMultiCurrencyWallet = tokensCount != null)
|
||||
} else {
|
||||
LoadedTokensInfo(
|
||||
balanceAmount = balance.amount,
|
||||
|
|
@ -195,12 +184,9 @@ private fun TokensInfo(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun LoadingTokensInfo(
|
||||
modifier: Modifier = Modifier,
|
||||
isMultiCurrencyWallet: Boolean,
|
||||
) {
|
||||
private fun LoadingTokensInfo(isMultiCurrencyWallet: Boolean) {
|
||||
Column(
|
||||
modifier = modifier.shimmer(),
|
||||
modifier = Modifier.shimmer(),
|
||||
horizontalAlignment = Alignment.End,
|
||||
verticalArrangement = Arrangement.SpaceAround,
|
||||
) {
|
||||
|
|
@ -230,15 +216,8 @@ private fun LoadingTokensInfo(
|
|||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
private fun LoadedTokensInfo(
|
||||
modifier: Modifier = Modifier,
|
||||
balanceAmount: String,
|
||||
tokensCount: Int?,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.End,
|
||||
) {
|
||||
private fun LoadedTokensInfo(balanceAmount: String, tokensCount: Int?) {
|
||||
Column(horizontalAlignment = Alignment.End) {
|
||||
Text(
|
||||
text = balanceAmount,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
|
|
|
|||
|
|
@ -34,10 +34,7 @@ internal class WelcomeFragment : ComposeFragment<WelcomeScreenState>() {
|
|||
}
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(
|
||||
modifier: Modifier,
|
||||
state: WelcomeScreenState,
|
||||
) {
|
||||
override fun ScreenContent(state: WelcomeScreenState, modifier: Modifier) {
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference())
|
||||
|
||||
|
|
|
|||
|
|
@ -27,16 +27,12 @@ import com.tangem.wallet.R
|
|||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
internal fun WelcomeScreenContent(
|
||||
modifier: Modifier = Modifier,
|
||||
showUnlockProgress: Boolean,
|
||||
showScanCardProgress: Boolean,
|
||||
onUnlockClick: () -> Unit,
|
||||
onScanCardClick: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
SpacerHMax()
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size96),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue