Align Android history handling with iOS and bump app version

This commit is contained in:
2026-04-29 11:22:19 +07:00
parent 7cc3d1ceb3
commit 648584f133
5 changed files with 46 additions and 7 deletions

View File

@ -13,8 +13,8 @@ android {
applicationId = "com.iiyh.emoneyinfo" applicationId = "com.iiyh.emoneyinfo"
minSdk = 28 minSdk = 28
targetSdk = 36 targetSdk = 36
versionCode = 3 versionCode = 4
versionName = "1.0.1" versionName = "1.0.2"
vectorDrawables { vectorDrawables {
useSupportLibrary = true useSupportLibrary = true

View File

@ -44,6 +44,18 @@ data class TransactionItem(
append(locationName) append(locationName)
} }
} }
fun historyKey(): String = buildString {
append(date.time / 1000)
append('|')
append(amount)
append('|')
append(if (isCredit) 1 else 0)
append('|')
append(locationName.trim())
append('|')
append(title)
}
} }
data class EmoneyUiState( data class EmoneyUiState(
@ -63,6 +75,16 @@ data class EmoneyUiState(
} }
fun hasCardData(): Boolean = cardType != CardType.UNKNOWN || cardNumber.isNotBlank() || balance > 0 || transactions.isNotEmpty() fun hasCardData(): Boolean = cardType != CardType.UNKNOWN || cardNumber.isNotBlank() || balance > 0 || transactions.isNotEmpty()
fun clearingHistory(scanMessage: String): EmoneyUiState = copy(
transactions = emptyList(),
scanMessage = scanMessage
)
fun deduplicatingHistory(): EmoneyUiState {
val deduplicated = transactions.distinctBy { it.historyKey() }
return if (deduplicated.size == transactions.size) this else copy(transactions = deduplicated)
}
} }
fun String.formatCardNumber(): String { fun String.formatCardNumber(): String {

View File

@ -51,7 +51,8 @@ class UnifiedNfcReader(private val context: Context) {
} }
fun startScan() { fun startScan() {
refreshStatus() resetMessageJob?.cancel()
_uiState.value = _uiState.value.clearingHistory(currentScanMessage())
} }
fun onNewIntent(intent: Intent) { fun onNewIntent(intent: Intent) {
@ -65,7 +66,7 @@ class UnifiedNfcReader(private val context: Context) {
AppLog.d("EmoneyInfoNfc", "onNewIntent techs=${tag.techList.joinToString()}") AppLog.d("EmoneyInfoNfc", "onNewIntent techs=${tag.techList.joinToString()}")
val reader = readers.firstOrNull { it.canHandle(tag) } ?: return val reader = readers.firstOrNull { it.canHandle(tag) } ?: return
runCatching { runCatching {
_uiState.value = reader.read(tag, strings) _uiState.value = reader.read(tag, strings).deduplicatingHistory()
scheduleResetToRescanHint() scheduleResetToRescanHint()
}.onFailure { }.onFailure {
AppLog.e("EmoneyInfoNfc", "Scan failed: ${it.message}", it) AppLog.e("EmoneyInfoNfc", "Scan failed: ${it.message}", it)

View File

@ -95,7 +95,11 @@ fun EmoneyInfoApp(
adsEnabled = adsEnabled, adsEnabled = adsEnabled,
showCardNumber = showCardNumber, showCardNumber = showCardNumber,
onScanTapped = { nfcReader.startScan() }, onScanTapped = { nfcReader.startScan() },
onViewHistoryTapped = { navController.navigate("history") }, onViewHistoryTapped = {
if (uiState.transactions.isNotEmpty()) {
navController.navigate("history")
}
},
onSettingsTapped = { navController.navigate("settings") } onSettingsTapped = { navController.navigate("settings") }
) )
} }

View File

@ -2,6 +2,7 @@ package com.iiyh.emoneyinfo.ui.screens
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -70,6 +71,7 @@ fun HomeScreen(
val clipboard = LocalClipboardManager.current val clipboard = LocalClipboardManager.current
val context = LocalContext.current val context = LocalContext.current
val latestTransaction = state.transactions.firstOrNull() val latestTransaction = state.transactions.firstOrNull()
val hasHistory = state.transactions.isNotEmpty()
val hasCardData = state.hasCardData() val hasCardData = state.hasCardData()
val displayCardNumber = when { val displayCardNumber = when {
state.cardNumber.isBlank() -> "" state.cardNumber.isBlank() -> ""
@ -288,6 +290,7 @@ fun HomeScreen(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable( .clickable(
enabled = hasHistory,
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
indication = null, indication = null,
onClick = onViewHistoryTapped onClick = onViewHistoryTapped
@ -295,8 +298,17 @@ fun HomeScreen(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp) horizontalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
Icon(Icons.Default.History, contentDescription = null) val historyColor = if (hasHistory) {
Text(stringResource(R.string.view_full_history), fontWeight = FontWeight.SemiBold) MaterialTheme.colorScheme.primary
} else {
TextSecondary.copy(alpha = if (isSystemInDarkTheme()) 0.7f else 0.4f)
}
Icon(Icons.Default.History, contentDescription = null, tint = historyColor)
Text(
stringResource(R.string.view_full_history),
fontWeight = FontWeight.SemiBold,
color = historyColor
)
} }
} }
} }