Updated on 2026-08-14
This commit is contained in:
parent
139df9e5f4
commit
96f5aa8238
40 changed files with 1503 additions and 388 deletions
|
|
@ -0,0 +1,103 @@
|
|||
package com.tangem.core.ui.components.appbar
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
fun AppBarWithBackButtonAndIcon(
|
||||
onBackClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
text: String? = null,
|
||||
@DrawableRes backIconRes: Int? = null,
|
||||
@DrawableRes iconRes: Int? = null,
|
||||
onIconClick: (() -> Unit)? = null,
|
||||
backgroundColor: Color = TangemTheme.colors.background.secondary,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.background(color = backgroundColor)
|
||||
.fillMaxWidth()
|
||||
.padding(all = TangemTheme.dimens.spacing16),
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(backIconRes ?: R.drawable.ic_back_24),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(size = TangemTheme.dimens.size24)
|
||||
.clickable { onBackClick() },
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
)
|
||||
AnimatedContent(
|
||||
targetState = text,
|
||||
modifier = Modifier.weight(1f),
|
||||
transitionSpec = { fadeIn().togetherWith(fadeOut()) },
|
||||
label = "Toolbar title change",
|
||||
) {
|
||||
if (!it.isNullOrBlank()) {
|
||||
Text(
|
||||
text = it,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
maxLines = 1,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
}
|
||||
}
|
||||
AnimatedContent(
|
||||
targetState = iconRes,
|
||||
transitionSpec = { (fadeIn() + scaleIn()).togetherWith(fadeOut() + scaleOut()) },
|
||||
label = "Toolbar icon change",
|
||||
) {
|
||||
if (onIconClick != null && it != null) {
|
||||
Icon(
|
||||
painter = painterResource(it),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(size = TangemTheme.dimens.size24)
|
||||
.clickable { onIconClick() },
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, heightDp = 56, showBackground = true)
|
||||
@Composable
|
||||
private fun PreviewAppBarWithBackButtonAndIconInLightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
AppBarWithBackButtonAndIcon(
|
||||
text = "Title",
|
||||
iconRes = R.drawable.ic_qrcode_scan_24,
|
||||
onBackClick = {},
|
||||
onIconClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, heightDp = 56, showBackground = true)
|
||||
@Composable
|
||||
private fun PreviewAppBarWithBackButtonAndIconInDarkTheme() {
|
||||
TangemTheme(isDark = true) {
|
||||
AppBarWithBackButtonAndIcon(
|
||||
text = "Title",
|
||||
iconRes = R.drawable.ic_qrcode_scan_24,
|
||||
onBackClick = {},
|
||||
onIconClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.core.ui.components.fields
|
||||
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.input.OffsetMapping
|
||||
import androidx.compose.ui.text.input.TransformedText
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
|
||||
class AmountVisualTransformation(
|
||||
private val symbol: String,
|
||||
) : VisualTransformation {
|
||||
override fun filter(text: AnnotatedString): TransformedText {
|
||||
return TransformedText(
|
||||
buildAnnotatedString {
|
||||
append(text)
|
||||
if (text.isNotBlank()) {
|
||||
append(" ")
|
||||
append(symbol)
|
||||
}
|
||||
},
|
||||
object : OffsetMapping {
|
||||
override fun originalToTransformed(offset: Int): Int {
|
||||
return text.length
|
||||
}
|
||||
|
||||
override fun transformedToOriginal(offset: Int): Int {
|
||||
return text.length
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -9,12 +9,14 @@ import java.util.Locale
|
|||
@Suppress("MagicNumber")
|
||||
object DateTimeFormatters {
|
||||
|
||||
private const val DDMMYYYY = "dd.MM.yyyy"
|
||||
|
||||
/**
|
||||
* Two SS means, SHORT style for date and time.
|
||||
* If pattern contains "a", it means time is in 12 hour format.
|
||||
* [Documentation](https://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html)
|
||||
*/
|
||||
val timeFormatter by lazy {
|
||||
val timeFormatter: DateTimeFormatter by lazy {
|
||||
val is12HourFormat = DateTimeFormat.patternForStyle("SS", Locale.getDefault()).contains("a")
|
||||
if (is12HourFormat) {
|
||||
DateTimeFormatterBuilder()
|
||||
|
|
@ -35,7 +37,7 @@ object DateTimeFormatters {
|
|||
}
|
||||
}
|
||||
|
||||
val dateFormatter by lazy {
|
||||
val dateFormatter: DateTimeFormatter by lazy {
|
||||
DateTimeFormatterBuilder()
|
||||
.appendDayOfMonth(1)
|
||||
.appendLiteral(' ')
|
||||
|
|
@ -46,6 +48,13 @@ object DateTimeFormatters {
|
|||
.withLocale(Locale.getDefault())
|
||||
}
|
||||
|
||||
val dateDDMMYYYY: DateTimeFormatter by lazy {
|
||||
DateTimeFormatterBuilder()
|
||||
.appendPattern(DDMMYYYY)
|
||||
.toFormatter()
|
||||
.withLocale(Locale.getDefault())
|
||||
}
|
||||
|
||||
fun formatTime(formatter: DateTimeFormatter = timeFormatter, time: DateTime): String {
|
||||
return formatter.print(time)
|
||||
}
|
||||
|
|
|
|||
33
core/ui/src/main/java/com/tangem/core/ui/utils/DateUtils.kt
Normal file
33
core/ui/src/main/java/com/tangem/core/ui/utils/DateUtils.kt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.core.ui.utils
|
||||
|
||||
import android.text.format.DateUtils
|
||||
import com.tangem.utils.extensions.isToday
|
||||
import com.tangem.utils.extensions.isYesterday
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.DateTimeZone
|
||||
import org.joda.time.format.DateTimeFormatter
|
||||
|
||||
/**
|
||||
* If [this] timestamp is today or yesterday, returns relative date,
|
||||
* otherwise returns formatting date.
|
||||
*/
|
||||
fun Long.toDateFormat(formatter: DateTimeFormatter = DateTimeFormatters.dateFormatter): String {
|
||||
val localDate = DateTime(this, DateTimeZone.getDefault())
|
||||
return if (localDate.isToday() || localDate.isYesterday()) {
|
||||
DateUtils.getRelativeTimeSpanString(
|
||||
this,
|
||||
DateTime.now().millis,
|
||||
DateUtils.DAY_IN_MILLIS,
|
||||
DateUtils.FORMAT_ABBREV_RELATIVE,
|
||||
).toString()
|
||||
} else {
|
||||
DateTimeFormatters.formatDate(formatter = formatter, date = localDate)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted time according to [formatter].
|
||||
*/
|
||||
fun Long.toTimeFormat(formatter: DateTimeFormatter = DateTimeFormatters.timeFormatter): String {
|
||||
return DateTimeFormatters.formatTime(formatter = formatter, time = DateTime(this, DateTimeZone.getDefault()))
|
||||
}
|
||||
13
core/ui/src/main/res/drawable/ic_qrcode_scan_24.xml
Normal file
13
core/ui/src/main/res/drawable/ic_qrcode_scan_24.xml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h24v24h-24z"/>
|
||||
<path
|
||||
android:pathData="M4,4H10V10H4V4ZM20,4V10H14V4H20ZM14,15H16V13H14V11H16V13H18V11H20V13H18V15H20V18H18V20H16V18H13V20H11V16H14V15ZM16,15V18H18V15H16ZM4,20V14H10V20H4ZM6,6V8H8V6H6ZM16,6V8H18V6H16ZM6,16V18H8V16H6ZM4,11H6V13H4V11ZM9,11H13V15H11V13H9V11ZM11,6H13V10H11V6ZM2,2V6H0V2C0,1.47 0.211,0.961 0.586,0.586C0.961,0.211 1.47,0 2,0L6,0V2H2ZM22,0C22.53,0 23.039,0.211 23.414,0.586C23.789,0.961 24,1.47 24,2V6H22V2H18V0H22ZM2,18V22H6V24H2C1.47,24 0.961,23.789 0.586,23.414C0.211,23.039 0,22.53 0,22V18H2ZM22,22V18H24V22C24,22.53 23.789,23.039 23.414,23.414C23.039,23.789 22.53,24 22,24H18V22H22Z"
|
||||
android:fillColor="#1E1E1E"/>
|
||||
</group>
|
||||
</vector>
|
||||
Loading…
Add table
Add a link
Reference in a new issue