Updated on 2026-08-14

This commit is contained in:
Tangem 2023-09-26 16:57:53 +05:00
parent d922493a76
commit e3847f8729
5 changed files with 80 additions and 80 deletions

View file

@ -30,4 +30,5 @@ dependencies {
implementation(deps.compose.shimmer)
implementation(deps.kotlin.immutable.collections)
implementation(deps.zxing.qrCore)
implementation(deps.jodatime)
}

View file

@ -0,0 +1,56 @@
package com.tangem.core.ui.utils
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
import org.joda.time.format.DateTimeFormatter
import org.joda.time.format.DateTimeFormatterBuilder
import java.util.Locale
@Suppress("MagicNumber")
object DateTimeFormatters {
/**
* 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 is12HourFormat = DateTimeFormat.patternForStyle("SS", Locale.getDefault()).contains("a")
if (is12HourFormat) {
DateTimeFormatterBuilder()
.appendClockhourOfHalfday(1)
.appendLiteral(':')
.appendMinuteOfHour(2)
.appendLiteral(" ")
.appendHalfdayOfDayText()
.toFormatter()
.withLocale(Locale.getDefault())
} else {
DateTimeFormatterBuilder()
.appendHourOfDay(1)
.appendLiteral(':')
.appendMinuteOfHour(2)
.toFormatter()
.withLocale(Locale.getDefault())
}
}
val dateFormatter by lazy {
DateTimeFormatterBuilder()
.appendDayOfMonth(1)
.appendLiteral(' ')
.appendMonthOfYearShortText()
.appendLiteral(", ")
.appendYear(4, 4)
.toFormatter()
.withLocale(Locale.getDefault())
}
fun formatTime(formatter: DateTimeFormatter = timeFormatter, time: DateTime): String {
return formatter.print(time)
}
fun formatDate(formatter: DateTimeFormatter = dateFormatter, date: DateTime): String {
return formatter.print(date)
}
}

View file

@ -6,6 +6,7 @@ import com.tangem.common.Provider
import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.core.ui.components.transactions.state.TxHistoryState.TxHistoryItemState
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
@ -20,8 +21,6 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.joda.time.format.DateTimeFormatterBuilder
import java.util.Locale
internal class TokenDetailsTxHistoryItemFlowConverter(
private val currentStateProvider: Provider<TokenDetailsState>,
@ -34,28 +33,6 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
TokenDetailsTxHistoryTransactionStateConverter(symbol = symbol, decimals = decimals)
}
/** Example, 2 Aug, 2023 */
private val dateFormatter by lazy {
DateTimeFormatterBuilder()
.appendDayOfMonth(1)
.appendLiteral(' ')
.appendMonthOfYearShortText()
.appendLiteral(", ")
.appendYear(4, 4)
.toFormatter()
.withLocale(Locale.getDefault())
}
/** Example, 13:35 */
private val timeFormatter by lazy {
DateTimeFormatterBuilder()
.appendHourOfDay(1)
.appendLiteral(':')
.appendMinuteOfHour(2)
.toFormatter()
.withLocale(Locale.getDefault())
}
override fun convert(value: Flow<PagingData<TxHistoryItem>>): TxHistoryState {
val txHistoryContent = currentStateProvider().txHistoryState as TxHistoryState.Content
@ -140,7 +117,7 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
/**
* If [this] timestamp is today or yesterday, returns relative date,
* otherwise returns formatting date by [dateFormatter]
* otherwise returns formatting date.
*/
private fun Long.toDateFormat(): String {
val localDate = DateTime(this, DateTimeZone.getDefault())
@ -152,13 +129,11 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
DateUtils.FORMAT_ABBREV_RELATIVE,
).toString()
} else {
dateFormatter.print(localDate)
DateTimeFormatters.formatDate(date = localDate)
}
}
private fun String.toTimeFormat(): String {
return timeFormatter.print(
DateTime(this.toLong(), DateTimeZone.getDefault()),
)
return DateTimeFormatters.formatTime(time = DateTime(this.toLong(), DateTimeZone.getDefault()))
}
}

View file

@ -2,6 +2,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.
import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.features.tokendetails.impl.R
import com.tangem.utils.converter.Converter
@ -9,25 +10,13 @@ import com.tangem.utils.toBriefAddressFormat
import com.tangem.utils.toFormattedCurrencyString
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.joda.time.format.DateTimeFormatterBuilder
import java.math.BigDecimal
import java.util.Locale
internal class TokenDetailsTxHistoryToTransactionStateConverter(
private val symbol: String,
private val decimals: Int,
) : Converter<TxHistoryItem, TransactionState> {
/** Example, 13:35 */
private val timeFormatter by lazy {
DateTimeFormatterBuilder()
.appendHourOfDay(1)
.appendLiteral(':')
.appendMinuteOfHour(2)
.toFormatter()
.withLocale(Locale.getDefault())
}
override fun convert(value: TxHistoryItem): TransactionState {
return createTransactionStateItem(item = value)
}
@ -42,7 +31,7 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
title = TextReference.Str("Deposit"),
subtitle = item.direction.extractAddress(),
@ -52,7 +41,7 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
title = TextReference.Str("Submit"),
subtitle = item.direction.extractAddress(),
@ -62,7 +51,7 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
title = TextReference.Str("Supply"),
subtitle = item.direction.extractAddress(),
@ -72,7 +61,7 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
title = TextReference.Str("Unoswap"),
subtitle = item.direction.extractAddress(),
@ -82,7 +71,7 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
title = TextReference.Str("Withdraw"),
subtitle = item.direction.extractAddress(),
@ -92,7 +81,7 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
title = TextReference.Str(type.id),
subtitle = item.direction.extractAddress(),
@ -107,14 +96,14 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
)
is TxHistoryItem.TransactionDirection.Outgoing -> TransactionState.Send(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
)
}
@ -125,7 +114,7 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
)
}
@ -134,7 +123,7 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
txHash = item.txHash,
address = item.direction.extractAddress(),
amount = item.amount.toCryptoCurrencyFormat(),
timestamp = timeFormatter.print(DateTime(item.timestampInMillis, DateTimeZone.getDefault())),
timestamp = item.timestampInMillis.toTimeFormat(),
status = item.status.tiUiStatus(),
)
}
@ -153,4 +142,8 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
TxHistoryItem.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
TxHistoryItem.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
}
private fun Long.toTimeFormat(): String {
return DateTimeFormatters.formatTime(time = DateTime(this, DateTimeZone.getDefault()))
}
}

View file

@ -7,6 +7,7 @@ import com.tangem.common.Provider
import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.core.ui.components.transactions.state.TxHistoryState.TxHistoryItemState
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
@ -22,8 +23,6 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.joda.time.format.DateTimeFormatterBuilder
import java.util.Locale
/**
* Convert from [Flow] of [TxHistoryItem] to [TxHistoryState]
@ -44,28 +43,6 @@ internal class WalletTxHistoryItemFlowConverter(
WalletTxHistoryTransactionStateConverter(symbol = blockchain.currency, decimals = blockchain.decimals())
}
/** Example, 2 Aug, 2023 */
private val dateFormatter by lazy {
DateTimeFormatterBuilder()
.appendDayOfMonth(1)
.appendLiteral(' ')
.appendMonthOfYearShortText()
.appendLiteral(", ")
.appendYear(4, 4)
.toFormatter()
.withLocale(Locale.getDefault())
}
/** Example, 13:35 */
private val timeFormatter by lazy {
DateTimeFormatterBuilder()
.appendHourOfDay(1)
.appendLiteral(':')
.appendMinuteOfHour(2)
.toFormatter()
.withLocale(Locale.getDefault())
}
override fun convert(value: Flow<PagingData<TxHistoryItem>>): TxHistoryState? {
val state = currentStateProvider() as? WalletSingleCurrencyState ?: return null
val txHistoryContent = state.txHistoryState as? TxHistoryState.Content ?: return state.txHistoryState
@ -151,7 +128,7 @@ internal class WalletTxHistoryItemFlowConverter(
/**
* If [this] timestamp is today or yesterday, returns relative date,
* otherwise returns formatting date by [dateFormatter]
* otherwise returns formatting date.
*/
private fun Long.toDateFormat(): String {
val localDate = DateTime(this, DateTimeZone.getDefault())
@ -163,13 +140,11 @@ internal class WalletTxHistoryItemFlowConverter(
DateUtils.FORMAT_ABBREV_RELATIVE,
).toString()
} else {
dateFormatter.print(localDate)
DateTimeFormatters.formatDate(date = localDate)
}
}
private fun String.toTimeFormat(): String {
return timeFormatter.print(
DateTime(this.toLong(), DateTimeZone.getDefault()),
)
return DateTimeFormatters.formatTime(time = DateTime(this.toLong(), DateTimeZone.getDefault()))
}
}