[#1143] Transaction ID row in Transaction item
* [#1143] Transaction ID row in Transaction item - Added a new transaction ID row into the transaction item on the Transactions screen - It displays a TODO value instead of the TXID until the #1316 in SDK done - Closes #1143 Changelog update
This commit is contained in:
parent
b544de316d
commit
2f33ccf818
|
@ -11,6 +11,7 @@ directly impact users rather than highlighting other key architectural updates.*
|
|||
|
||||
### Added
|
||||
- Transaction history items now display Memos within the Android Toast, triggered by clicking the item
|
||||
- Transaction history items add displaying transaction IDs; the ID element is also clickable
|
||||
|
||||
## [0.2.0 (517)] - 2023-12-21
|
||||
|
||||
|
|
|
@ -124,6 +124,27 @@ fun Small(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Suppress("LongParameterList")
|
||||
fun Tiny(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
maxLines: Int = Int.MAX_VALUE,
|
||||
overflow: TextOverflow = TextOverflow.Clip,
|
||||
textAlign: TextAlign = TextAlign.Start,
|
||||
color: Color = MaterialTheme.colorScheme.onBackground,
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
color = color,
|
||||
maxLines = maxLines,
|
||||
overflow = overflow,
|
||||
textAlign = textAlign,
|
||||
modifier = modifier,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ListItem(
|
||||
text: String,
|
||||
|
|
|
@ -12,6 +12,7 @@ class HistoryTestSetup(
|
|||
) {
|
||||
private val onBackClickCount = AtomicInteger(0)
|
||||
private val onItemClickCount = AtomicInteger(0)
|
||||
private val onItemIdClickCount = AtomicInteger(0)
|
||||
|
||||
fun getOnBackClickCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
|
@ -23,6 +24,11 @@ class HistoryTestSetup(
|
|||
return onItemClickCount.get()
|
||||
}
|
||||
|
||||
fun getOnItemIdClickCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onItemIdClickCount.get()
|
||||
}
|
||||
|
||||
init {
|
||||
composeTestRule.setContent {
|
||||
ZcashTheme {
|
||||
|
@ -33,6 +39,9 @@ class HistoryTestSetup(
|
|||
},
|
||||
onItemClick = {
|
||||
onItemClickCount.incrementAndGet()
|
||||
},
|
||||
onTransactionIdClick = {
|
||||
onItemIdClickCount.incrementAndGet()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package co.electriccoin.zcash.ui.screen.history.view
|
||||
|
||||
import androidx.compose.ui.test.assertCountEquals
|
||||
import androidx.compose.ui.test.assertHeightIsAtLeast
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onAllNodesWithTag
|
||||
|
@ -127,7 +128,9 @@ class HistoryViewTest {
|
|||
|
||||
assertEquals(0, testSetup.getOnItemClickCount())
|
||||
|
||||
composeTestRule.onAllNodesWithTag(HistoryTag.TRANSACTION_ITEM).also {
|
||||
composeTestRule.onAllNodesWithTag(HistoryTag.TRANSACTION_ITEM, useUnmergedTree = true).also {
|
||||
it.assertCountEquals(TransactionHistorySyncStateFixture.TRANSACTIONS.size)
|
||||
|
||||
TransactionHistorySyncStateFixture.TRANSACTIONS.forEachIndexed { index, _ ->
|
||||
it[index].performClick()
|
||||
}
|
||||
|
@ -136,6 +139,24 @@ class HistoryViewTest {
|
|||
assertEquals(TransactionHistorySyncStateFixture.TRANSACTIONS.size, testSetup.getOnItemClickCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun transaction_id_click_test() {
|
||||
val testSetup = newTestSetup(TransactionHistorySyncStateFixture.STATE)
|
||||
|
||||
assertEquals(0, testSetup.getOnItemIdClickCount())
|
||||
|
||||
composeTestRule.onAllNodesWithTag(HistoryTag.TRANSACTION_ID).also {
|
||||
it.assertCountEquals(TransactionHistorySyncStateFixture.TRANSACTIONS.size)
|
||||
|
||||
TransactionHistorySyncStateFixture.TRANSACTIONS.forEachIndexed { index, _ ->
|
||||
it[index].performClick()
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(TransactionHistorySyncStateFixture.TRANSACTIONS.size, testSetup.getOnItemIdClickCount())
|
||||
}
|
||||
|
||||
private fun newTestSetup(
|
||||
transactionHistorySyncState: TransactionHistorySyncState = TransactionHistorySyncStateFixture.new()
|
||||
): HistoryTestSetup {
|
||||
|
|
|
@ -10,7 +10,6 @@ import co.electriccoin.zcash.spackle.ClipboardManagerUtil
|
|||
import co.electriccoin.zcash.ui.MainActivity
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||
import co.electriccoin.zcash.ui.screen.history.view.History
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -39,30 +38,31 @@ internal fun WrapHistory(
|
|||
|
||||
Twig.info { "Current transaction history state: $transactionHistoryState" }
|
||||
|
||||
if (synchronizer == null) {
|
||||
// TODO [#1146]: Consider moving CircularScreenProgressIndicator from Android layer to View layer
|
||||
// TODO [#1146]: Improve this by allowing screen composition and updating it after the data is available
|
||||
// TODO [#1146]: https://github.com/Electric-Coin-Company/zashi-android/issues/1146
|
||||
CircularScreenProgressIndicator()
|
||||
} else {
|
||||
History(
|
||||
transactionState = transactionHistoryState,
|
||||
onBack = goBack,
|
||||
onItemClick = { tx ->
|
||||
Twig.debug { "Querying transaction memos..." }
|
||||
val memos = synchronizer.getMemos(tx)
|
||||
queryScope.launch {
|
||||
memos.toList().run {
|
||||
val merged = joinToString().ifEmpty { "-" }
|
||||
Twig.info { "Transaction memos: count: $size, contains: $merged" }
|
||||
ClipboardManagerUtil.copyToClipboard(
|
||||
activity.applicationContext,
|
||||
activity.getString(R.string.history_item_clipboard_tag),
|
||||
merged
|
||||
)
|
||||
}
|
||||
History(
|
||||
transactionState = transactionHistoryState,
|
||||
onBack = goBack,
|
||||
onItemClick = { tx ->
|
||||
Twig.debug { "Transaction item clicked - querying memos..." }
|
||||
val memos = synchronizer?.getMemos(tx)
|
||||
queryScope.launch {
|
||||
memos?.toList()?.let {
|
||||
val merged = it.joinToString().ifEmpty { "-" }
|
||||
Twig.info { "Transaction memos: count: ${it.size}, contains: $merged" }
|
||||
ClipboardManagerUtil.copyToClipboard(
|
||||
activity.applicationContext,
|
||||
activity.getString(R.string.history_item_clipboard_tag),
|
||||
merged
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
onTransactionIdClick = { txId ->
|
||||
Twig.debug { "Transaction ID clicked: $txId" }
|
||||
ClipboardManagerUtil.copyToClipboard(
|
||||
activity.applicationContext,
|
||||
activity.getString(R.string.history_id_clipboard_tag),
|
||||
txId
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,5 +6,6 @@ package co.electriccoin.zcash.ui.screen.history
|
|||
object HistoryTag {
|
||||
const val TRANSACTION_LIST = "transaction_list"
|
||||
const val TRANSACTION_ITEM = "transaction_item"
|
||||
const val TRANSACTION_ID = "transaction_id"
|
||||
const val PROGRESS = "progress_bar"
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.Spacer
|
|||
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.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
|
@ -49,7 +50,9 @@ import cash.z.ecc.android.sdk.model.toZecString
|
|||
import cash.z.ecc.sdk.type.ZcashCurrency
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.design.component.Body
|
||||
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
||||
import co.electriccoin.zcash.ui.design.component.Tiny
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.screen.history.HistoryTag
|
||||
import co.electriccoin.zcash.ui.screen.history.state.TransactionHistorySyncState
|
||||
|
@ -67,7 +70,8 @@ private fun ComposablePreview() {
|
|||
History(
|
||||
transactionState = TransactionHistorySyncState.Loading,
|
||||
onBack = {},
|
||||
onItemClick = {}
|
||||
onItemClick = {},
|
||||
onTransactionIdClick = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +93,8 @@ private fun ComposableHistoryListPreview() {
|
|||
)
|
||||
),
|
||||
onBack = {},
|
||||
onItemClick = {}
|
||||
onItemClick = {},
|
||||
onTransactionIdClick = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +112,8 @@ val dateFormat: DateFormat by lazy {
|
|||
fun History(
|
||||
transactionState: TransactionHistorySyncState,
|
||||
onBack: () -> Unit,
|
||||
onItemClick: (TransactionOverview) -> Unit
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
onTransactionIdClick: (String) -> Unit
|
||||
) {
|
||||
Scaffold(topBar = {
|
||||
HistoryTopBar(onBack = onBack)
|
||||
|
@ -115,6 +121,7 @@ fun History(
|
|||
HistoryMainContent(
|
||||
transactionState = transactionState,
|
||||
onItemClick = onItemClick,
|
||||
onTransactionIdClick = onTransactionIdClick,
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxHeight()
|
||||
|
@ -145,15 +152,17 @@ private fun HistoryTopBar(onBack: () -> Unit) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
@Suppress("LongMethod")
|
||||
private fun HistoryMainContent(
|
||||
transactionState: TransactionHistorySyncState,
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
onTransactionIdClick: (String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Box(modifier = modifier.fillMaxSize()) {
|
||||
when (transactionState) {
|
||||
is TransactionHistorySyncState.Loading -> {
|
||||
CircularProgressIndicator(
|
||||
CircularScreenProgressIndicator(
|
||||
modifier =
|
||||
Modifier
|
||||
.align(alignment = Center)
|
||||
|
@ -177,7 +186,8 @@ private fun HistoryMainContent(
|
|||
)
|
||||
HistoryList(
|
||||
transactions = transactionState.transactions,
|
||||
onItemClick = onItemClick
|
||||
onItemClick = onItemClick,
|
||||
onTransactionIdClick = onTransactionIdClick
|
||||
)
|
||||
}
|
||||
// Add progress indicator only in the state of empty transaction
|
||||
|
@ -202,7 +212,8 @@ private fun HistoryMainContent(
|
|||
} else {
|
||||
HistoryList(
|
||||
transactions = transactionState.transactions,
|
||||
onItemClick = onItemClick
|
||||
onItemClick = onItemClick,
|
||||
onTransactionIdClick = onTransactionIdClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +224,8 @@ private fun HistoryMainContent(
|
|||
@Composable
|
||||
private fun HistoryList(
|
||||
transactions: ImmutableList<TransactionOverview>,
|
||||
onItemClick: (TransactionOverview) -> Unit
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
onTransactionIdClick: (String) -> Unit
|
||||
) {
|
||||
val currency = ZcashCurrency.fromResources(LocalContext.current)
|
||||
LazyColumn(modifier = Modifier.testTag(HistoryTag.TRANSACTION_LIST)) {
|
||||
|
@ -222,7 +234,7 @@ private fun HistoryList(
|
|||
transaction = item,
|
||||
currency = currency,
|
||||
onItemClick = onItemClick,
|
||||
modifier = Modifier.testTag(HistoryTag.TRANSACTION_ITEM)
|
||||
onIdClick = onTransactionIdClick,
|
||||
)
|
||||
if (index < transactions.lastIndex) {
|
||||
Divider(
|
||||
|
@ -240,6 +252,7 @@ fun HistoryItem(
|
|||
transaction: TransactionOverview,
|
||||
currency: ZcashCurrency,
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
onIdClick: (String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val transactionTypeText: String
|
||||
|
@ -269,15 +282,13 @@ fun HistoryItem(
|
|||
|
||||
Row(
|
||||
modifier =
|
||||
modifier.then(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onItemClick(transaction) }
|
||||
.padding(
|
||||
horizontal = ZcashTheme.dimens.spacingDefault,
|
||||
vertical = ZcashTheme.dimens.spacingDefault
|
||||
)
|
||||
),
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onItemClick(transaction) }
|
||||
.padding(
|
||||
horizontal = ZcashTheme.dimens.spacingDefault,
|
||||
vertical = ZcashTheme.dimens.spacingDefault
|
||||
).then(modifier),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Image(
|
||||
|
@ -296,7 +307,8 @@ fun HistoryItem(
|
|||
) {
|
||||
Body(
|
||||
text = transactionTypeText,
|
||||
color = Color.Black
|
||||
color = Color.Black,
|
||||
modifier = Modifier.testTag(HistoryTag.TRANSACTION_ITEM)
|
||||
)
|
||||
|
||||
val dateString =
|
||||
|
@ -332,6 +344,19 @@ fun HistoryItem(
|
|||
}
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingTiny))
|
||||
|
||||
// TODO [#1316]: Provide readable TxId on TransactionOverview
|
||||
// TODO [#1316]: https://github.com/Electric-Coin-Company/zcash-android-wallet-sdk/issues/1316
|
||||
// TODO [#1316]: transaction.rawId.byteArray.toHexReversed()
|
||||
val txId = "TODO [#1316]: SDK: Provide readable TxId"
|
||||
Tiny(
|
||||
text = txId,
|
||||
modifier =
|
||||
Modifier
|
||||
.clickable { onIdClick(txId) }
|
||||
.testTag(HistoryTag.TRANSACTION_ID)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<string name="history_syncing">Additional transactions may be found after syncing completes…</string>
|
||||
<string name="history_empty">No transactions yet</string>
|
||||
<string name="history_item_clipboard_tag">Transaction memo</string>
|
||||
<string name="history_id_clipboard_tag">Transaction ID</string>
|
||||
|
||||
<string name="history_item_sent">Sent</string>
|
||||
<string name="history_item_received">Received</string>
|
||||
|
|
Loading…
Reference in New Issue