fix(@desktop/wallet): Remove the 'Load More' button from the Activity view and replace with automatic loading when the user scrolls down using a skeleton loading state
fixes #8987
This commit is contained in:
parent
e8ed91b3ba
commit
2dbf2d4635
|
@ -82,7 +82,7 @@ proc init*(self: Controller) =
|
|||
|
||||
self.events.on(SIGNAL_TRANSACTION_LOADING_COMPLETED_FOR_ALL_NETWORKS) do(e:Args):
|
||||
let args = TransactionsLoadedArgs(e)
|
||||
self.delegate.setHistoryFetchState(args.address, isFetching = false)
|
||||
self.delegate.setHistoryFetchState(args.address, args.allTxLoaded, isFetching = false)
|
||||
|
||||
self.events.on(SIGNAL_CURRENCY_FORMATS_UPDATED) do(e:Args):
|
||||
# TODO: Rebuild Transaction items
|
||||
|
|
|
@ -34,7 +34,7 @@ method setTrxHistoryResult*(self: AccessInterface, transactions: seq[Transaction
|
|||
method setHistoryFetchState*(self: AccessInterface, addresses: seq[string], isFetching: bool) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setHistoryFetchState*(self: AccessInterface, address: string, isFetching: bool) {.base.} =
|
||||
method setHistoryFetchState*(self: AccessInterface, address: string, allTxLoaded: bool, isFetching: bool) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setIsNonArchivalNode*(self: AccessInterface, isNonArchivalNode: bool) {.base.} =
|
||||
|
|
|
@ -29,6 +29,7 @@ type
|
|||
totalFees: CurrencyAmount
|
||||
maxTotalFees: CurrencyAmount
|
||||
symbol: string
|
||||
loadingTransaction: bool
|
||||
|
||||
proc initItem*(
|
||||
id: string,
|
||||
|
@ -56,7 +57,8 @@ proc initItem*(
|
|||
baseGasFees: CurrencyAmount,
|
||||
totalFees: CurrencyAmount,
|
||||
maxTotalFees: CurrencyAmount,
|
||||
symbol: string
|
||||
symbol: string,
|
||||
loadingTransaction: bool = false
|
||||
): Item =
|
||||
result.id = id
|
||||
result.typ = typ
|
||||
|
@ -84,6 +86,7 @@ proc initItem*(
|
|||
result.totalFees = totalFees
|
||||
result.maxTotalFees = maxTotalFees
|
||||
result.symbol = symbol
|
||||
result.loadingTransaction = loadingTransaction
|
||||
|
||||
proc initTimestampItem*(timestamp: int): Item =
|
||||
result.timestamp = timestamp
|
||||
|
@ -98,6 +101,20 @@ proc initTimestampItem*(timestamp: int): Item =
|
|||
result.totalFees = newCurrencyAmount()
|
||||
result.maxTotalFees = newCurrencyAmount()
|
||||
|
||||
proc initLoadingItem*(): Item =
|
||||
result.timestamp = 0
|
||||
result.gasPrice = newCurrencyAmount()
|
||||
result.value = newCurrencyAmount()
|
||||
result.chainId = 0
|
||||
result.maxFeePerGas = newCurrencyAmount()
|
||||
result.maxPriorityFeePerGas = newCurrencyAmount()
|
||||
result.multiTransactionID = 0
|
||||
result.isTimeStamp = false
|
||||
result.baseGasFees = newCurrencyAmount()
|
||||
result.totalFees = newCurrencyAmount()
|
||||
result.maxTotalFees = newCurrencyAmount()
|
||||
result.loadingTransaction = true
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""AllTokensItem(
|
||||
id: {self.id},
|
||||
|
@ -126,6 +143,7 @@ proc `$`*(self: Item): string =
|
|||
totalFees: {self.totalFees},
|
||||
maxTotalFees: {self.maxTotalFees},
|
||||
symbol: {self.symbol},
|
||||
loadingTransaction: {self.loadingTransaction},
|
||||
]"""
|
||||
|
||||
proc getId*(self: Item): string =
|
||||
|
@ -205,3 +223,6 @@ proc getMaxTotalFees*(self: Item): CurrencyAmount =
|
|||
|
||||
proc getSymbol*(self: Item): string =
|
||||
return self.symbol
|
||||
|
||||
proc getLoadingTransaction*(self: Item): bool =
|
||||
return self.loadingTransaction
|
||||
|
|
|
@ -31,6 +31,7 @@ type
|
|||
TotalFees
|
||||
MaxTotalFees
|
||||
Symbol
|
||||
LoadingTransaction
|
||||
|
||||
QtObject:
|
||||
type
|
||||
|
@ -95,7 +96,8 @@ QtObject:
|
|||
ModelRole.BaseGasFees.int: "baseGasFees",
|
||||
ModelRole.TotalFees.int: "totalFees",
|
||||
ModelRole.MaxTotalFees.int: "maxTotalFees",
|
||||
ModelRole.Symbol.int: "symbol"
|
||||
ModelRole.Symbol.int: "symbol",
|
||||
ModelRole.LoadingTransaction.int: "loadingTransaction"
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
|
@ -161,6 +163,8 @@ QtObject:
|
|||
result = newQVariant(item.getMaxTotalFees())
|
||||
of ModelRole.Symbol:
|
||||
result = newQVariant(item.getSymbol())
|
||||
of ModelRole.LoadingTransaction:
|
||||
result = newQVariant(item.getLoadingTransaction())
|
||||
|
||||
proc setItems*(self: Model, items: seq[Item]) =
|
||||
self.beginResetModel()
|
||||
|
@ -185,7 +189,7 @@ QtObject:
|
|||
QtProperty[bool] hasMore:
|
||||
read = getHasMore
|
||||
write = setHasMore
|
||||
notify = currentTransactionsChanged
|
||||
notify = hasMoreChanged
|
||||
|
||||
proc cmpTransactions*(x, y: Item): int =
|
||||
# Sort proc to compare transactions from a single account.
|
||||
|
@ -213,8 +217,27 @@ QtObject:
|
|||
if(durationInDays != 0):
|
||||
itemsWithDateHeaders.add(initTimestampItem(tx.getTimestamp()))
|
||||
itemsWithDateHeaders.add(tx)
|
||||
tempTimeStamp = fromUnix(tx.getTimestamp())
|
||||
tempTimeStamp = fromUnix(tx.getTimestamp())
|
||||
|
||||
self.items = allTxs
|
||||
self.setItems(itemsWithDateHeaders)
|
||||
self.setHasMore(true)
|
||||
|
||||
proc addPageSizeBuffer*(self: Model, pageSize: int) =
|
||||
if pageSize > 0:
|
||||
var itemsWithDateHeaders: seq[Item] = @[]
|
||||
itemsWithDateHeaders.add(initTimestampItem(0))
|
||||
for i in 0 ..< pageSize:
|
||||
self.beginInsertRows(newQModelIndex(), self.itemsWithDateHeaders.len, self.itemsWithDateHeaders.len)
|
||||
self.itemsWithDateHeaders.add(initLoadingItem())
|
||||
self.endInsertRows()
|
||||
self.countChanged()
|
||||
|
||||
proc removePageSizeBuffer*(self: Model) =
|
||||
for i in 0 ..< self.itemsWithDateHeaders.len:
|
||||
if self.itemsWithDateHeaders[i].getLoadingTransaction():
|
||||
self.beginRemoveRows(newQModelIndex(), i, self.itemsWithDateHeaders.len-1)
|
||||
self.itemsWithDateHeaders.delete(i, self.itemsWithDateHeaders.len-1)
|
||||
self.endRemoveRows()
|
||||
self.countChanged()
|
||||
return
|
||||
|
|
|
@ -115,8 +115,8 @@ method setTrxHistoryResult*(self: Module, transactions: seq[TransactionDto], add
|
|||
method setHistoryFetchState*(self: Module, addresses: seq[string], isFetching: bool) =
|
||||
self.view.setHistoryFetchStateForAccounts(addresses, isFetching)
|
||||
|
||||
method setHistoryFetchState*(self: Module, address: string, isFetching: bool) =
|
||||
self.view.setHistoryFetchState(address, isFetching)
|
||||
method setHistoryFetchState*(self: Module, address: string, allTxLoaded: bool, isFetching: bool) =
|
||||
self.view.setHistoryFetchState(address, allTxLoaded, isFetching)
|
||||
|
||||
method setIsNonArchivalNode*(self: Module, isNonArchivalNode: bool) =
|
||||
self.view.setIsNonArchivalNode(isNonArchivalNode)
|
||||
|
|
|
@ -48,15 +48,16 @@ QtObject:
|
|||
|
||||
proc loadingTrxHistoryChanged*(self: View, isLoading: bool, address: string) {.signal.}
|
||||
|
||||
proc setHistoryFetchState*(self: View, address: string, isFetching: bool) =
|
||||
proc setHistoryFetchState*(self: View, address: string, allTxLoaded: bool, isFetching: bool) =
|
||||
if self.models.hasKey(address):
|
||||
if not isFetching:
|
||||
self.models[address].removePageSizeBuffer()
|
||||
elif isFetching and self.models[address].getCount() == 0:
|
||||
self.models[address].addPageSizeBuffer(20)
|
||||
self.models[address].setHasMore(not allTxLoaded)
|
||||
self.fetchingHistoryState[address] = isFetching
|
||||
self.loadingTrxHistoryChanged(isFetching, address)
|
||||
|
||||
proc setHistoryFetchState*(self: View, accounts: seq[string], isFetching: bool) =
|
||||
for acc in accounts:
|
||||
self.fetchingHistoryState[acc] = isFetching
|
||||
self.loadingTrxHistoryChanged(isFetching, acc)
|
||||
|
||||
proc isFetchingHistory*(self: View, address: string): bool {.slot.} =
|
||||
if self.fetchingHistoryState.hasKey(address):
|
||||
return self.fetchingHistoryState[address]
|
||||
|
@ -66,7 +67,9 @@ QtObject:
|
|||
return self.model.getCount() > 0
|
||||
|
||||
proc loadTransactionsForAccount*(self: View, address: string, toBlock: string = "0x0", limit: int = 20, loadMore: bool = false) {.slot.} =
|
||||
self.setHistoryFetchState(address, true)
|
||||
if self.models.hasKey(address):
|
||||
self.setHistoryFetchState(address, allTxLoaded=not self.models[address].getHasMore(), isFetching=true)
|
||||
self.models[address].addPageSizeBuffer(limit)
|
||||
self.delegate.loadTransactions(address, toBlock, limit, loadMore)
|
||||
|
||||
proc setTrxHistoryResult*(self: View, transactions: seq[Item], address: string, wasFetchMore: bool) =
|
||||
|
@ -74,10 +77,15 @@ QtObject:
|
|||
self.models[address] = newModel()
|
||||
|
||||
self.models[address].addNewTransactions(transactions, wasFetchMore)
|
||||
if self.fetchingHistoryState.hasKey(address) and self.fetchingHistoryState[address] and wasFetchMore:
|
||||
self.models[address].addPageSizeBuffer(transactions.len)
|
||||
|
||||
proc setHistoryFetchStateForAccounts*(self: View, addresses: seq[string], isFetching: bool) =
|
||||
for address in addresses:
|
||||
self.setHistoryFetchState(address, isFetching)
|
||||
if self.models.hasKey(address):
|
||||
self.setHistoryFetchState(address, allTxLoaded = not self.models[address].getHasMore(), isFetching)
|
||||
else:
|
||||
self.setHistoryFetchState(address, allTxLoaded = false, isFetching)
|
||||
|
||||
proc setModel*(self: View, address: string) {.slot.} =
|
||||
if not self.models.hasKey(address):
|
||||
|
@ -165,4 +173,4 @@ QtObject:
|
|||
let fromAddress = tx.getfrom()
|
||||
if not self.models.hasKey(fromAddress):
|
||||
self.models[fromAddress] = newModel()
|
||||
self.models[fromAddress].addNewTransactions(@[tx], false)
|
||||
self.models[fromAddress].addNewTransactions(@[tx], wasFetchMore=false)
|
||||
|
|
|
@ -17,16 +17,19 @@ type
|
|||
toBlock: Uint256
|
||||
limit: int
|
||||
loadMore: bool
|
||||
allTxLoaded: bool
|
||||
|
||||
const loadTransactionsTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[LoadTransactionsTaskArg](argEncoded)
|
||||
limitAsHex = "0x" & eth_utils.stripLeadingZeros(arg.limit.toHex)
|
||||
response = transactions.getTransfersByAddress(arg.chainId, arg.address, arg.toBlock, limitAsHex, arg.loadMore).result
|
||||
output = %*{
|
||||
"address": arg.address,
|
||||
"chainId": arg.chainId,
|
||||
"history": transactions.getTransfersByAddress(arg.chainId, arg.address, arg.toBlock, limitAsHex, arg.loadMore),
|
||||
"history": response,
|
||||
"loadMore": arg.loadMore,
|
||||
"allTxLoaded": response.getElems().len < arg.limit
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ type
|
|||
transactions*: seq[TransactionDto]
|
||||
address*: string
|
||||
wasFetchMore*: bool
|
||||
allTxLoaded*: bool
|
||||
tempLoadingTx*: int
|
||||
|
||||
type
|
||||
TransactionSentArgs* = ref object of Args
|
||||
|
@ -96,6 +98,7 @@ QtObject:
|
|||
settingsService: settings_service.Service
|
||||
tokenService: token_service.Service
|
||||
txCounter: Table[string, seq[int]]
|
||||
allTxLoaded: Table[string, bool]
|
||||
|
||||
# Forward declaration
|
||||
proc loadTransactions*(self: Service, address: string, toBlock: Uint256, limit: int = 20, loadMore: bool = false)
|
||||
|
@ -118,6 +121,7 @@ QtObject:
|
|||
result.settingsService = settingsService
|
||||
result.tokenService = tokenService
|
||||
result.txCounter = initTable[string, seq[int]]()
|
||||
result.allTxLoaded = initTable[string, bool]()
|
||||
|
||||
proc init*(self: Service) =
|
||||
signalConnect(singletonInstance.localAccountSensitiveSettings, "isWalletEnabledChanged()", self, "onIsWalletEnabledChanged()", 2)
|
||||
|
@ -202,10 +206,16 @@ QtObject:
|
|||
let address = historyData["address"].getStr
|
||||
let chainID = historyData["chainId"].getInt
|
||||
let wasFetchMore = historyData["loadMore"].getBool
|
||||
let allTxLoaded = historyData["allTxLoaded"].getBool
|
||||
var transactions: seq[TransactionDto] = @[]
|
||||
for tx in historyData["history"]["result"].getElems():
|
||||
for tx in historyData["history"].getElems():
|
||||
transactions.add(tx.toTransactionDto())
|
||||
|
||||
if self.allTxLoaded.hasKey(address):
|
||||
self.allTxLoaded[address] = self.allTxLoaded[address] and allTxLoaded
|
||||
else:
|
||||
self.allTxLoaded[address] = allTxLoaded
|
||||
|
||||
# emit event
|
||||
self.events.emit(SIGNAL_TRANSACTIONS_LOADED, TransactionsLoadedArgs(
|
||||
transactions: transactions,
|
||||
|
@ -214,16 +224,18 @@ QtObject:
|
|||
))
|
||||
|
||||
# when requests for all networks are completed then set loading state as completed
|
||||
if self.txCounter.hasKey(address):
|
||||
if self.txCounter.hasKey(address) and self.allTxLoaded.hasKey(address) :
|
||||
var chainIDs = self.txCounter[address]
|
||||
chainIDs.del(chainIDs.find(chainID))
|
||||
self.txCounter[address] = chainIDs
|
||||
if self.txCounter[address].len == 0:
|
||||
self.txCounter.del(address)
|
||||
self.events.emit(SIGNAL_TRANSACTION_LOADING_COMPLETED_FOR_ALL_NETWORKS, TransactionsLoadedArgs(address: address))
|
||||
self.events.emit(SIGNAL_TRANSACTION_LOADING_COMPLETED_FOR_ALL_NETWORKS, TransactionsLoadedArgs(address: address, allTxLoaded: self.allTxLoaded[address]))
|
||||
|
||||
proc loadTransactions*(self: Service, address: string, toBlock: Uint256, limit: int = 20, loadMore: bool = false) =
|
||||
let networks = self.networkService.getNetworks()
|
||||
self.allTxLoaded.del(address)
|
||||
|
||||
if not self.txCounter.hasKey(address):
|
||||
var networkChains: seq[int] = @[]
|
||||
self.txCounter[address] = networkChains
|
||||
|
|
|
@ -281,7 +281,6 @@ Rectangle {
|
|||
lineHeight: 24
|
||||
|
||||
visible: inlineTagModelRepeater.count > 0
|
||||
loading: statusListItem.loading
|
||||
}
|
||||
|
||||
StatusScrollView {
|
||||
|
|
|
@ -369,9 +369,15 @@ Item {
|
|||
Layout.alignment: detailsFlow.isOverflowing ? Qt.AlignLeft : Qt.AlignRight
|
||||
iconAsset.icon: "browser"
|
||||
tagPrimaryLabel.text: qsTr("Website")
|
||||
controlBackground.color: Theme.palette.baseColor2
|
||||
controlBackground.border.color: "transparent"
|
||||
visible: typeof token != "undefined" && token && token.assetWebsiteUrl !== ""
|
||||
customBackground: Component {
|
||||
Rectangle {
|
||||
color: Theme.palette.baseColor2
|
||||
border.width: 1
|
||||
border.color: "transparent"
|
||||
radius: 36
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
@ -385,9 +391,15 @@ Item {
|
|||
image.source: token && token.builtOn !== "" ? Style.svg("tiny/" + RootStore.getNetworkIconUrl(token.builtOn)) : ""
|
||||
tagPrimaryLabel.text: token && token.builtOn !== "" ? RootStore.getNetworkName(token.builtOn) : "---"
|
||||
tagSecondaryLabel.text: token && token.address !== "" ? token.address : "---"
|
||||
controlBackground.color: Theme.palette.baseColor2
|
||||
controlBackground.border.color: "transparent"
|
||||
visible: typeof token != "undefined" && token && token.builtOn !== "" && token.address !== ""
|
||||
customBackground: Component {
|
||||
Rectangle {
|
||||
color: Theme.palette.baseColor2
|
||||
border.width: 1
|
||||
border.color: "transparent"
|
||||
radius: 36
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,30 +4,44 @@ import QtQuick.Controls 2.14
|
|||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
Control {
|
||||
id: root
|
||||
|
||||
property alias image : image
|
||||
property alias iconAsset : iconAsset
|
||||
property alias tagPrimaryLabel: tagPrimaryLabel
|
||||
property alias tagSecondaryLabel: tagSecondaryLabel
|
||||
property alias controlBackground: controlBackground
|
||||
property alias rightComponent: rightComponent.sourceComponent
|
||||
property bool loading: false
|
||||
|
||||
property Component customBackground: Component {
|
||||
Rectangle {
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: Theme.palette.baseColor2
|
||||
radius: 36
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property var loadingComponent: Component { LoadingComponent {}}
|
||||
}
|
||||
|
||||
horizontalPadding: Style.current.halfPadding
|
||||
verticalPadding: 5
|
||||
|
||||
background: Rectangle {
|
||||
id: controlBackground
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: Theme.palette.baseColor2
|
||||
radius: 36
|
||||
background: Loader {
|
||||
sourceComponent: root.loading ? d.loadingComponent : root.customBackground
|
||||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 4
|
||||
visible: !root.loading
|
||||
// FIXME this could be StatusIcon but it can't load images from an arbitrary URL
|
||||
Image {
|
||||
id: image
|
||||
|
|
|
@ -4,6 +4,7 @@ import QtQuick.Layouts 1.3
|
|||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared 1.0
|
||||
|
@ -11,6 +12,9 @@ import shared 1.0
|
|||
StatusListItem {
|
||||
id: root
|
||||
|
||||
property alias cryptoValueText: cryptoValueText
|
||||
property alias fiatValueText: fiatValueText
|
||||
|
||||
property var modelData
|
||||
property string symbol
|
||||
property bool isIncoming
|
||||
|
@ -24,8 +28,9 @@ StatusListItem {
|
|||
property string savedAddressName
|
||||
|
||||
state: "normal"
|
||||
asset.isImage: true
|
||||
asset.isImage: !loading
|
||||
asset.name: root.symbol ? Style.png("tokens/%1".arg(root.symbol)) : ""
|
||||
asset.isLetterIdenticon: loading
|
||||
title: modelData !== undefined && !!modelData ?
|
||||
isIncoming ? qsTr("Receive %1").arg(root.symbol) : !!savedAddressName ?
|
||||
qsTr("Send %1 to %2").arg(root.symbol).arg(savedAddressName) :
|
||||
|
@ -36,16 +41,23 @@ StatusListItem {
|
|||
tagPrimaryLabel.text: networkName
|
||||
tagPrimaryLabel.color: networkColor
|
||||
image.source: !!networkIcon ? Style.svg("tiny/%1".arg(networkIcon)) : ""
|
||||
background: Rectangle {
|
||||
id: controlBackground
|
||||
implicitWidth: 51
|
||||
implicitHeight: 24
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: Theme.palette.baseColor2
|
||||
radius: 36
|
||||
customBackground: Component {
|
||||
Rectangle {
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: Theme.palette.baseColor2
|
||||
radius: 36
|
||||
}
|
||||
}
|
||||
width: 51
|
||||
height: root.loading ? textMetrics.tightBoundingRect.height : 24
|
||||
rightComponent: transferStatus === Constants.TransactionStatus.Success ? completedIcon : loadingIndicator
|
||||
loading: root.loading
|
||||
}
|
||||
TextMetrics {
|
||||
id: textMetrics
|
||||
font: statusListItemSubTitle.font
|
||||
text: statusListItemSubTitle.text
|
||||
}
|
||||
components: [
|
||||
ColumnLayout {
|
||||
|
@ -57,18 +69,23 @@ StatusListItem {
|
|||
icon: "arrow-up"
|
||||
rotation: isIncoming ? 135 : 45
|
||||
height: 18
|
||||
visible: !root.loading
|
||||
}
|
||||
StatusBaseText {
|
||||
StatusTextWithLoadingState {
|
||||
id: cryptoValueText
|
||||
text: LocaleUtils.currencyAmountToLocaleString(cryptoValue)
|
||||
color: Theme.palette.directColor1
|
||||
customColor: Theme.palette.directColor1
|
||||
loading: root.loading
|
||||
}
|
||||
|
||||
}
|
||||
StatusBaseText {
|
||||
StatusTextWithLoadingState {
|
||||
id: fiatValueText
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text: LocaleUtils.currencyAmountToLocaleString(fiatValue)
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.baseColor1
|
||||
customColor: Theme.palette.baseColor1
|
||||
loading: root.loading
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -15,39 +15,34 @@ import "../stores"
|
|||
import "../controls"
|
||||
|
||||
ColumnLayout {
|
||||
id: historyView
|
||||
id: root
|
||||
|
||||
property var account
|
||||
property int pageSize: 20 // number of transactions per page
|
||||
property bool isLoading: false
|
||||
|
||||
signal launchTransactionDetail(var transaction)
|
||||
|
||||
function fetchHistory() {
|
||||
if (RootStore.isFetchingHistory(historyView.account.address)) {
|
||||
isLoading = true
|
||||
} else {
|
||||
RootStore.loadTransactionsForAccount(historyView.account.address, pageSize)
|
||||
if (!RootStore.isFetchingHistory(root.account.address)) {
|
||||
d.isLoading = true
|
||||
RootStore.loadTransactionsForAccount(root.account.address, pageSize)
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property bool isLoading: false
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: RootStore.history
|
||||
function onLoadingTrxHistoryChanged(isLoading: bool, address: string) {
|
||||
if (historyView.account.address.toLowerCase() === address.toLowerCase()) {
|
||||
historyView.isLoading = isLoading
|
||||
if (root.account.address.toLowerCase() === address.toLowerCase()) {
|
||||
d.isLoading = isLoading
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loadingImg
|
||||
active: isLoading
|
||||
sourceComponent: loadingImageComponent
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
Layout.rightMargin: Style.current.padding
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: nonArchivalNodeError
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
@ -60,7 +55,7 @@ ColumnLayout {
|
|||
|
||||
StyledText {
|
||||
id: noTxs
|
||||
visible: !isLoading && transactionListRoot.count === 0
|
||||
visible: !d.isLoading && transactionListRoot.count === 0
|
||||
text: qsTr("No transactions found")
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
}
|
||||
|
@ -76,26 +71,17 @@ ColumnLayout {
|
|||
|
||||
model: RootStore.historyTransactions
|
||||
delegate: Loader {
|
||||
width: parent.width
|
||||
width: ListView.view.width
|
||||
sourceComponent: isTimeStamp ? dateHeader : transactionDelegate
|
||||
onLoaded: {
|
||||
item.modelData = model
|
||||
}
|
||||
}
|
||||
}
|
||||
footer: footerComp
|
||||
|
||||
ScrollBar.vertical: StatusScrollBar {}
|
||||
|
||||
footer: StatusButton {
|
||||
id: loadMoreButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
text: qsTr("Load More")
|
||||
// TODO: handle case when requested limit === transaction count -- there
|
||||
// is currently no way to know that there are no more results
|
||||
enabled: !isLoading && RootStore.historyTransactions.hasMore
|
||||
onClicked: fetchHistory()
|
||||
loading: isLoading
|
||||
}
|
||||
onAtYEndChanged: if(atYEnd && RootStore.historyTransactions.hasMore) fetchHistory()
|
||||
}
|
||||
|
||||
Component {
|
||||
|
@ -113,23 +99,51 @@ ColumnLayout {
|
|||
Component {
|
||||
id: transactionDelegate
|
||||
TransactionDelegate {
|
||||
property bool modelDataValid: modelData !== undefined && !!modelData
|
||||
property bool modelDataValid: !!modelData
|
||||
isIncoming: modelDataValid ? modelData.to === account.address: false
|
||||
cryptoValue: modelDataValid ? modelData.value : undefined
|
||||
fiatValue: modelDataValid ? RootStore.getFiatValue(cryptoValue.amount, symbol, RootStore.currentCurrency) : undefined
|
||||
fiatValue: modelDataValid && !!cryptoValue ? RootStore.getFiatValue(cryptoValue.amount, symbol, RootStore.currentCurrency) : undefined
|
||||
networkIcon: modelDataValid ? RootStore.getNetworkIcon(modelData.chainId) : ""
|
||||
networkColor: modelDataValid ? RootStore.getNetworkColor(modelData.chainId) : ""
|
||||
networkName: modelDataValid ? RootStore.getNetworkShortName(modelData.chainId) : ""
|
||||
symbol: modelDataValid ? modelData.symbol : ""
|
||||
symbol: modelDataValid && !!modelData.symbol ? modelData.symbol : ""
|
||||
transferStatus: modelDataValid ? RootStore.hex2Dec(modelData.txStatus) : ""
|
||||
shortTimeStamp: modelDataValid ? LocaleUtils.formatTime(modelData.timestamp * 1000, Locale.ShortFormat) : ""
|
||||
savedAddressName: modelDataValid ? RootStore.getNameForSavedWalletAddress(modelData.to) : ""
|
||||
onClicked: launchTransactionDetail(modelData)
|
||||
loading: modelDataValid ? modelData.loadingTransaction : false
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: loadingImageComponent
|
||||
StatusLoadingIndicator {}
|
||||
id: footerComp
|
||||
ColumnLayout {
|
||||
width: root.width
|
||||
visible: !RootStore.historyTransactions.hasMore && transactionListRoot.count !== 0
|
||||
spacing: 12
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: Style.curent.padding
|
||||
Layout.preferredWidth: parent.width - 100
|
||||
Layout.preferredHeight: 1
|
||||
color: Theme.palette.directColor8
|
||||
visible: !RootStore.historyTransactions.hasMore
|
||||
}
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("You have reached the beginning of the activity for this account")
|
||||
font.pixelSize: 13
|
||||
color: Theme.palette.baseColor1
|
||||
visible: !RootStore.historyTransactions.hasMore
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
StatusButton {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Back to most recent transaction")
|
||||
visible: !RootStore.historyTransactions.hasMore
|
||||
onClicked: transactionListRoot.positionViewAtBeginning()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue