Align Android history handling with iOS and bump app version
This commit is contained in:
@ -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
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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") }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user