Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ import com.gemwallet.android.model.AssetInfo
import com.gemwallet.android.model.Crypto
import com.gemwallet.android.model.TransactionExtended
import com.gemwallet.android.model.format
import com.gemwallet.android.domains.asset.chain
import com.wallet.core.primitives.Asset
import com.wallet.core.primitives.BlockExplorerLink
import com.wallet.core.primitives.Currency
import com.wallet.core.primitives.TransactionDirection
import com.wallet.core.primitives.TransactionState
import com.wallet.core.primitives.TransactionSwapMetadata
import com.wallet.core.primitives.TransactionType
import uniffi.gemstone.Explorer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -54,6 +57,8 @@ class GetTransactionDetailsImpl(
val explorerInfo = getCurrentBlockExplorer.getBlockExplorerInfo(data.transaction).let { (url, name) ->
TransactionDetailsValue.Explorer(url, name)
}
val chainExplorer = Explorer(data.asset.chain.string)
val explorerName = explorerInfo.name
assetsRepository.getAssetsInfo(ids).mapLatest { assets ->
val swapMetadata = data.transaction.getSwapMetadata()
val provider = gemSwapper.getProviders().firstOrNull { it.protocolId == swapMetadata?.provider }
Expand All @@ -64,6 +69,8 @@ class GetTransactionDetailsImpl(
currency = session.currency,
swapProvider = provider,
swapMetadata = swapMetadata,
senderExplorerLink = BlockExplorerLink(explorerName, chainExplorer.getAddressUrl(explorerName, data.transaction.from)),
recipientExplorerLink = BlockExplorerLink(explorerName, chainExplorer.getAddressUrl(explorerName, data.transaction.to)),
)
}
}
Expand All @@ -79,6 +86,8 @@ class TransactionDetailsAggregateImpl(
override val explorer: TransactionDetailsValue.Explorer,
override val currency: Currency,
swapProvider: SwapperProviderType? = null,
private val senderExplorerLink: BlockExplorerLink? = null,
private val recipientExplorerLink: BlockExplorerLink? = null,
) : TransactionDetailsAggregate {

override val id: String = data.transaction.id
Expand Down Expand Up @@ -186,8 +195,8 @@ class TransactionDetailsAggregateImpl(
TransactionType.Transfer,
TransactionType.TransferNFT -> when (data.transaction.direction) {
TransactionDirection.SelfTransfer,
TransactionDirection.Outgoing -> TransactionDetailsValue.Destination.Recipient(data.transaction.to)
TransactionDirection.Incoming -> TransactionDetailsValue.Destination.Sender(data.transaction.from)
TransactionDirection.Outgoing -> TransactionDetailsValue.Destination.Recipient(data.transaction.to, recipientExplorerLink)
TransactionDirection.Incoming -> TransactionDetailsValue.Destination.Sender(data.transaction.from, senderExplorerLink)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,34 @@
package com.gemwallet.android.features.activities.presents.details.components

import androidx.compose.foundation.clickable
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ContentCopy
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext
import androidx.compose.foundation.layout.padding
import com.gemwallet.android.ext.AddressFormatter
import com.gemwallet.android.domains.transaction.values.TransactionDetailsValue
import com.gemwallet.android.ui.R
import com.gemwallet.android.ui.components.clipboard.setPlainText
import com.gemwallet.android.ui.components.list_item.property.PropertyDataText
import com.gemwallet.android.ui.components.list_item.property.AddressPropertyItem
import com.gemwallet.android.ui.components.list_item.property.PropertyItem
import com.gemwallet.android.ui.components.list_item.property.PropertyTitleText
import com.gemwallet.android.ui.components.list_item.property.PropertyDataText
import com.gemwallet.android.ui.models.ListPosition
import com.gemwallet.android.ui.theme.paddingSmall

@Composable
fun DestinationPropertyItem(property: TransactionDetailsValue.Destination, listPosition: ListPosition) {
val context = LocalContext.current
val clipboardManager = LocalClipboard.current.nativeClipboard
val title = when (property) {
is TransactionDetailsValue.Destination.Recipient -> R.string.transaction_recipient
is TransactionDetailsValue.Destination.Sender -> R.string.transaction_sender
is TransactionDetailsValue.Destination.Provider -> R.string.common_provider
}
val isCopied = when (property) {
is TransactionDetailsValue.Destination.Recipient,
is TransactionDetailsValue.Destination.Sender -> true
is TransactionDetailsValue.Destination.Provider -> false
}

val displayData = when (property) {
when (property) {
is TransactionDetailsValue.Destination.Recipient,
is TransactionDetailsValue.Destination.Sender -> AddressFormatter(property.data).value()
is TransactionDetailsValue.Destination.Provider -> property.data
is TransactionDetailsValue.Destination.Sender -> AddressPropertyItem(
title = when (property) {
is TransactionDetailsValue.Destination.Recipient -> R.string.transaction_recipient
is TransactionDetailsValue.Destination.Sender -> R.string.transaction_sender
else -> return
},
displayText = AddressFormatter(property.data).value(),
copyValue = property.data,
explorerLink = property.explorerLink,
listPosition = listPosition,
)
is TransactionDetailsValue.Destination.Provider -> PropertyItem(
title = { PropertyTitleText(R.string.common_provider) },
data = { PropertyDataText(text = property.data) },
listPosition = listPosition,
)
}
PropertyItem(
title = { PropertyTitleText(title) },
data = {
PropertyDataText(
text = displayData,
modifier = Modifier
.clickable(enabled = isCopied) { clipboardManager.setPlainText(context, property.data) },
badge = if (isCopied) {
{
Icon(
modifier = Modifier.padding(start = paddingSmall),
imageVector = Icons.Default.ContentCopy,
tint = MaterialTheme.colorScheme.secondary,
contentDescription = null,
)
}
} else {
null
}
)
},
listPosition = listPosition,
)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.gemwallet.android.features.asset.presents.chart

import androidx.compose.foundation.clickable
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.foundation.combinedClickable
import com.gemwallet.android.ext.AddressFormatter
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.lazy.LazyColumn
Expand All @@ -17,7 +15,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.platform.testTag
Expand All @@ -28,19 +25,18 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.gemwallet.android.domains.asset.chain
import com.gemwallet.android.domains.percentage.formatAsPercentage
import com.gemwallet.android.domains.price.toPriceState
import com.gemwallet.android.ext.AddressFormatter
import com.gemwallet.android.model.compactFormatter
import com.gemwallet.android.model.formatSupply
import com.gemwallet.android.ui.R
import com.gemwallet.android.ui.components.InfoSheetEntity
import com.gemwallet.android.ui.components.clipboard.setPlainText
import com.gemwallet.android.ui.components.image.AsyncImage
import com.gemwallet.android.ui.components.list_item.ChipBadge
import com.gemwallet.android.ui.components.list_item.ListItem
import com.gemwallet.android.ui.components.list_item.ListItemSupportText
import com.gemwallet.android.ui.components.list_item.ListItemTitleText
import com.gemwallet.android.ui.components.list_item.SubheaderItem
import com.gemwallet.android.ui.components.list_item.color
import com.gemwallet.android.ui.components.list_item.property.AddressPropertyItem
import com.gemwallet.android.ui.components.list_item.property.DataBadgeChevron
import com.gemwallet.android.ui.components.list_item.property.PropertyDataText
import com.gemwallet.android.ui.components.list_item.property.PropertyItem
Expand All @@ -59,6 +55,7 @@ import com.gemwallet.android.features.asset.viewmodels.chart.viewmodels.ChartVie
import com.wallet.core.primitives.Asset
import com.wallet.core.primitives.AssetId
import com.wallet.core.primitives.AssetMarket
import com.wallet.core.primitives.BlockExplorerLink
import com.wallet.core.primitives.Currency
import uniffi.gemstone.Explorer
import java.text.DateFormat
Expand Down Expand Up @@ -176,12 +173,6 @@ private fun LazyListScope.links(links: List<AssetMarketUIModel.Link>) {
private fun LazyListScope.assetMarket(currency: Currency, asset: Asset, marketInfo: AssetMarket?, explorerName: String) {
marketInfo ?: return
val marketItems = listOfNotNull(
asset.id.tokenId?.let {
MarketInfoUIModel(
type = MarketInfoUIModel.MarketInfoTypeUIModel.Contract,
value = it,
)
},
marketInfo.marketCap?.let {
MarketInfoUIModel(
type = MarketInfoUIModel.MarketInfoTypeUIModel.MarketCap,
Expand Down Expand Up @@ -226,6 +217,14 @@ private fun LazyListScope.assetMarket(currency: Currency, asset: Asset, marketIn
info = InfoSheetEntity.MaxSupply,
)
},
asset.id.tokenId?.let { tokenId ->
MarketInfoUIModel(
type = MarketInfoUIModel.MarketInfoTypeUIModel.Contract,
value = tokenId,
explorerLink = Explorer(asset.chain.string).getTokenUrl(explorerName, tokenId)
?.let { BlockExplorerLink(name = explorerName, link = it) },
)
},
)

val allTime = listOfNotNull(
Expand Down Expand Up @@ -257,26 +256,12 @@ private fun LazyListScope.marketProperties(asset: Asset, explorerName: String, i
listPosition = position
)
MarketInfoUIModel.MarketInfoTypeUIModel.Contract -> {
val context = LocalContext.current
val clipboardManager = LocalClipboard.current.nativeClipboard
val uriHandler = LocalUriHandler.current
PropertyItem(
modifier = Modifier.combinedClickable(
onLongClick = {
clipboardManager.setPlainText(context, item.value)
},
onClick = {
uriHandler.open(context, Explorer(asset.chain.string).getTokenUrl(explorerName, item.value) ?: return@combinedClickable)
}
),
title = { PropertyTitleText(R.string.asset_contract) },
data = {
PropertyDataText(
text = AddressFormatter(item.value, chain = asset.chain).value(),
badge = { DataBadgeChevron() }
)
},
listPosition = position
AddressPropertyItem(
title = R.string.asset_contract,
displayText = AddressFormatter(item.value, chain = asset.chain).value(),
copyValue = item.value,
explorerLink = item.explorerLink,
listPosition = position,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package com.gemwallet.android.features.asset.viewmodels.chart.models
import androidx.annotation.StringRes
import com.gemwallet.android.ui.R
import com.gemwallet.android.ui.components.InfoSheetEntity
import com.wallet.core.primitives.BlockExplorerLink

class MarketInfoUIModel(
val type: MarketInfoTypeUIModel,
val value: String,
val badge: String? = null,
val info: InfoSheetEntity? = null,
val explorerLink: BlockExplorerLink? = null,
) {
enum class MarketInfoTypeUIModel(@param:StringRes val label: Int) {
MarketCap(R.string.asset_market_cap),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import com.gemwallet.android.ext.AddressFormatter
import com.gemwallet.android.ui.R
import com.gemwallet.android.ui.components.list_item.property.AddressPropertyItem
import com.gemwallet.android.ui.components.list_item.property.PropertyDataText
import com.gemwallet.android.ui.components.list_item.property.PropertyItem
import com.gemwallet.android.ui.components.list_item.property.PropertyTitleText
Expand All @@ -20,32 +21,53 @@ fun PropertyDestination(
) {
model ?: return

val title = when (model) {
is ConfirmProperty.Destination.Provider -> R.string.common_provider
is ConfirmProperty.Destination.Stake -> R.string.stake_validator
is ConfirmProperty.Destination.Transfer -> R.string.transaction_recipient
is ConfirmProperty.Destination.Generic -> R.string.wallet_connect_app
is ConfirmProperty.Destination.PerpetualOper -> R.string.common_provider
}
PropertyItem(
title = {
PropertyTitleText(title)
},
data = {
Column(horizontalAlignment = Alignment.End) {
Row(horizontalArrangement = Arrangement.End) { PropertyDataText(model.displayData()) }
when (model) {
is ConfirmProperty.Destination.Transfer -> {
val domain = model.domain
if (domain != null) {
PropertyItem(
title = { PropertyTitleText(R.string.transaction_recipient) },
data = {
Column(horizontalAlignment = Alignment.End) {
Row(horizontalArrangement = Arrangement.End) { PropertyDataText(domain) }
}
},
listPosition = listPosition,
)
} else {
AddressPropertyItem(
title = R.string.transaction_recipient,
displayText = AddressFormatter(model.address).value(),
copyValue = model.address,
explorerLink = model.explorerLink,
listPosition = listPosition,
)
}
},
listPosition = listPosition,
)
}

internal fun ConfirmProperty.Destination.displayData(): String {
return when (this) {
is ConfirmProperty.Destination.Stake,
is ConfirmProperty.Destination.Provider -> data
is ConfirmProperty.Destination.Transfer -> domain ?: AddressFormatter(address).value()
is ConfirmProperty.Destination.Generic -> appName
is ConfirmProperty.Destination.PerpetualOper -> providerName
}
else -> {
val title = when (model) {
is ConfirmProperty.Destination.Provider -> R.string.common_provider
is ConfirmProperty.Destination.Stake -> R.string.stake_validator
is ConfirmProperty.Destination.Generic -> R.string.wallet_connect_app
is ConfirmProperty.Destination.PerpetualOper -> R.string.common_provider
is ConfirmProperty.Destination.Transfer -> return
}
val text = when (model) {
is ConfirmProperty.Destination.Provider,
is ConfirmProperty.Destination.Stake -> AddressFormatter(model.data).value()
is ConfirmProperty.Destination.Generic -> model.appName
is ConfirmProperty.Destination.PerpetualOper -> model.providerName
is ConfirmProperty.Destination.Transfer -> return
}
PropertyItem(
title = { PropertyTitleText(title) },
data = {
Column(horizontalAlignment = Alignment.End) {
Row(horizontalArrangement = Arrangement.End) { PropertyDataText(text) }
}
},
listPosition = listPosition,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.gemwallet.android.features.confirm.models

import com.gemwallet.android.model.ConfirmParams
import com.wallet.core.primitives.Asset
import com.wallet.core.primitives.BlockExplorerLink
import com.wallet.core.primitives.DelegationValidator

sealed interface ConfirmProperty {
Expand All @@ -16,7 +17,7 @@ sealed interface ConfirmProperty {

class Provider(data: String) : Destination(data)

class Transfer(val domain: String?, val address: String) : Destination(address)
class Transfer(val domain: String?, val address: String, val explorerLink: BlockExplorerLink? = null) : Destination(address)

class Generic(val appName: String) : Destination(appName)

Expand Down
Loading