feat(@desktop/wallet): Add loading State for Assets view and Wallet main navigation page

This commit is contained in:
Khushboo Mehta 2023-01-10 14:04:23 +01:00 committed by Anthony Laibe
parent baea10cacf
commit 169de5b5e1
17 changed files with 241 additions and 29 deletions

View File

@ -60,11 +60,11 @@ method getHistoricalDataForToken*(self: Module, symbol: string, currency: string
self.controller.getHistoricalDataForToken(symbol, currency, ALL_TIME_RANGE)
method tokenHistoricalDataResolved*(self: Module, tokenDetails: string) =
self.view.tokenHistoricalDataReady(tokenDetails)
self.view.setTokenHistoricalDataReady(tokenDetails)
method fetchHistoricalBalanceForTokenAsJson*(self: Module, address: string, symbol: string, timeIntervalEnum: int) =
self.controller.fetchHistoricalBalanceForTokenAsJson(address, symbol, timeIntervalEnum)
method tokenBalanceHistoryDataResolved*(self: Module, balanceHistoryJson: string) =
self.view.tokenBalanceHistoryDataReady(balanceHistoryJson)
self.view.setTokenBalanceHistoryDataReady(balanceHistoryJson)

View File

@ -6,6 +6,8 @@ QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
marketHistoryIsLoading: bool
balanceHistoryIsLoading: bool
proc delete*(self: View) =
self.QObject.delete
@ -14,19 +16,61 @@ QtObject:
new(result, delete)
result.QObject.setup
result.delegate = delegate
result.marketHistoryIsLoading = false
result.balanceHistoryIsLoading = false
proc load*(self: View) =
self.delegate.viewDidLoad()
proc marketHistoryIsLoadingChanged*(self: View) {.signal.}
proc getMarketHistoryIsLoading(self: View): QVariant {.slot.} =
return newQVariant(self.marketHistoryIsLoading)
proc setMarketHistoryIsLoading(self: View, isLoading: bool) =
if self.marketHistoryIsLoading == isLoading:
return
self.marketHistoryIsLoading = isLoading
self.marketHistoryIsLoadingChanged()
QtProperty[QVariant] marketHistoryIsLoading:
read = getMarketHistoryIsLoading
notify = marketHistoryIsLoadingChanged
proc balanceHistoryIsLoadingChanged*(self: View) {.signal.}
proc getBalanceHistoryIsLoading(self: View): QVariant {.slot.} =
return newQVariant(self.balanceHistoryIsLoading)
proc setBalanceHistoryIsLoading(self: View, isLoading: bool) =
if self.balanceHistoryIsLoading == isLoading:
return
self.balanceHistoryIsLoading = isLoading
self.balanceHistoryIsLoadingChanged()
QtProperty[QVariant] balanceHistoryIsLoading:
read = getBalanceHistoryIsLoading
notify = balanceHistoryIsLoadingChanged
proc findTokenSymbolByAddress*(self: View, address: string): string {.slot.} =
return self.delegate.findTokenSymbolByAddress(address)
proc getHistoricalDataForToken*(self: View, symbol: string, currency: string) {.slot.} =
self.setMarketHistoryIsLoading(true)
self.delegate.getHistoricalDataForToken(symbol, currency)
proc tokenHistoricalDataReady*(self: View, tokenDetails: string) {.signal.}
proc setTokenHistoricalDataReady*(self: View, tokenDetails: string) =
self.setMarketHistoryIsLoading(false)
self.tokenHistoricalDataReady(tokenDetails)
proc fetchHistoricalBalanceForTokenAsJson*(self: View, address: string, symbol: string, timeIntervalEnum: int) {.slot.} =
self.setBalanceHistoryIsLoading(true)
self.delegate.fetchHistoricalBalanceForTokenAsJson(address, symbol, timeIntervalEnum)
proc tokenBalanceHistoryDataReady*(self: View, balanceHistoryJson: string) {.signal.}
proc tokenBalanceHistoryDataReady*(self: View, balanceHistoryJson: string) {.signal.}
proc setTokenBalanceHistoryDataReady*(self: View, balanceHistoryJson: string) =
self.setBalanceHistoryIsLoading(false)
self.tokenBalanceHistoryDataReady(balanceHistoryJson)

View File

@ -120,6 +120,7 @@ method load*(self: Module) =
self.setTotalCurrencyBalance()
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e:Args):
self.setTotalCurrencyBalance()
self.view.setTokensLoading(false)
self.controller.init()
self.view.load()

View File

@ -11,6 +11,7 @@ QtObject:
totalCurrencyBalance: CurrencyAmount
signingPhrase: string
isMnemonicBackedUp: bool
tokensLoading: bool
proc setup(self: View) =
self.QObject.setup
@ -21,6 +22,7 @@ QtObject:
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.delegate = delegate
result.tokensLoading = true
result.setup()
proc load*(self: View) =
@ -49,6 +51,15 @@ QtObject:
read = getTotalCurrencyBalance
notify = totalCurrencyBalanceChanged
proc tokensLoadingChanged*(self: View) {.signal.}
proc getTokensLoading(self: View): QVariant {.slot.} =
return newQVariant(self.tokensLoading)
QtProperty[QVariant] tokensLoading:
read = getTokensLoading
notify = tokensLoadingChanged
proc getSigningPhrase(self: View): QVariant {.slot.} =
return newQVariant(self.signingPhrase)
@ -82,6 +93,10 @@ QtObject:
proc getCurrencyAmountAsJson*(self: View, amount: float, symbol: string): string {.slot.} =
return $self.delegate.getCurrencyAmount(amount, symbol).toJsonNode()
proc setTokensLoading*(self: View, loading: bool) =
self.tokensLoading = loading
self.tokensLoadingChanged()
proc setData*(self: View, currency, signingPhrase: string, mnemonicBackedUp: bool) =
self.currentCurrency = currency
self.signingPhrase = signingPhrase

View File

@ -40,12 +40,13 @@ Item {
font.bold: true
text: currentAccount.name
}
StatusBaseText {
StatusTextWithLoadingState {
Layout.alignment: Qt.AlignVCenter
font.pixelSize: 28
font.bold: true
color: Theme.palette.baseColor1
customColor: Theme.palette.baseColor1
text: LocaleUtils.currencyAmountToLocaleString(root.currentAccount.currencyBalance)
loading: root.walletStore.tokensLoading
}
}

View File

@ -27,6 +27,7 @@ QtObject {
property var currencyStore: SharedStore.RootStore.currencyStore
property string currentCurrency: currencyStore.currentCurrency
property var totalCurrencyBalance: walletSection.totalCurrencyBalance
property bool tokensLoading: walletSection.tokensLoading
property string signingPhrase: walletSection.signingPhrase
property string mnemonicBackedUp: walletSection.isMnemonicBackedUp

View File

@ -145,7 +145,7 @@ Item {
chart.chartType: 'line'
chart.chartData: {
return {
labels: graphDetail.labelsData,
labels: RootStore.marketHistoryIsLoading ? [] : graphDetail.labelsData,
datasets: [{
xAxisId: 'x-axis-1',
yAxisId: 'y-axis-1',
@ -153,7 +153,7 @@ Item {
borderColor: (Theme.palette.name === "dark") ? 'rgba(136, 176, 255, 1)' : 'rgba(67, 96, 223, 1)',
borderWidth: 3,
pointRadius: 0,
data: graphDetail.dataRange,
data: RootStore.marketHistoryIsLoading ? [] : graphDetail.dataRange,
parsing: false,
}]
}
@ -236,6 +236,11 @@ Item {
}
}
LoadingGraphView {
anchors.fill: chart
active: RootStore.marketHistoryIsLoading
}
TokenBalanceHistoryStore {
id: balanceStore

View File

@ -103,10 +103,10 @@ Rectangle {
Layout.fillWidth: true
Layout.leftMargin: Style.current.padding
StyledTextEdit {
StyledTextEditWithLoadingState {
id: walletAmountValue
objectName: "walletLeftListAmountValue"
color: Style.current.textColor
customColor: Style.current.textColor
text: {
LocaleUtils.currencyAmountToLocaleString(RootStore.totalCurrencyBalance)
}
@ -116,6 +116,7 @@ Rectangle {
width: parent.width
font.weight: Font.Medium
font.pixelSize: 22
loading: RootStore.tokensLoading
}
StatusBaseText {
@ -160,6 +161,7 @@ Rectangle {
asset.bgColor: Theme.palette.primaryColor3
statusListItemTitle.font.weight: Font.Medium
color: sensor.containsMouse || highlighted ? Theme.palette.baseColor3 : "transparent"
statusListItemSubTitle.loading: RootStore.tokensLoading
onClicked: {
changeSelectedAccount(index)
showSavedAddresses = false

View File

@ -0,0 +1,9 @@
<svg width="720" height="127" viewBox="0 0 720 127" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M219.711 51.1867L132.124 17.3753L66.0618 45.9263L-6.10352e-05 31.4775V127H720V47.4298L663.588 25.8281L570.062 51.9788L420.124 0L326.598 36.1594L290.969 23.4801L219.711 51.1867Z" fill="url(#paint0_linear_9476_104484)"/>
<defs>
<linearGradient id="paint0_linear_9476_104484" x1="-6.10352e-05" y1="27.5785" x2="720" y2="27.5785" gradientUnits="userSpaceOnUse">
<stop stop-color="#D7DEE4" stop-opacity="0.25"/>
<stop offset="1" stop-color="#D7DEE4" stop-opacity="0.5"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 608 B

View File

@ -0,0 +1,28 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import StatusQ.Popups 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import utils 1.0
TokenDelegate {
id: root
title: Constants.dummyText
subTitle: Constants.dummyText
asset.name: Constants.dummyText
change24HourPercentage.text: Constants.dummyText
change24Hour.text: Constants.dummyText
localeCurrencyBalance.text: Constants.dummyText
statusListItemSubTitle.loading: true
statusListItemTitle.loading: true
statusListItemIcon.loading: true
change24HourPercentage.loading: true
change24Hour.loading: true
localeCurrencyBalance.loading: true
textColor: Theme.palette.baseColor1
}

View File

@ -0,0 +1,30 @@
import QtQuick 2.13
import utils 1.0
import StatusQ.Components 0.1
StyledTextEdit {
id: root
property bool loading: false
property color customColor: Style.current.textColor
color: loading ? "transparent" : customColor
Loader {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
active: root.loading
sourceComponent: LoadingComponent {
radius: textMetrics.font.pixelSize <= 15 ? 4 : 8
height: textMetrics.tightBoundingRect.height
width: Math.min(root.width, 140)
}
}
TextMetrics {
id: textMetrics
font: root.font
text: root.text
}
}

View File

@ -5,22 +5,33 @@ import StatusQ.Popups 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import utils 1.0
StatusListItem {
id: root
property alias localeCurrencyBalance: localeCurrencyBalance
property alias change24Hour: change24HourText
property alias change24HourPercentage: change24HourPercentageText
property string currentCurrencySymbol
property string textColor: changePct24hour === undefined ? Theme.palette.baseColor1 :
Math.sign(changePct24hour) === 0 ? Theme.palette.baseColor1 :
Math.sign(changePct24hour) === -1 ? Theme.palette.dangerColor1 :
Theme.palette.successColor1
title: name
subTitle: LocaleUtils.currencyAmountToLocaleString(enabledNetworkBalance)
asset.name: symbol ? Style.png("tokens/" + symbol) : ""
asset.isImage: true
components: [
Column {
id: valueColumn
property string textColor: Math.sign(Number(changePct24hour)) === 0 ? Theme.palette.baseColor1 :
Math.sign(Number(changePct24hour)) === -1 ? Theme.palette.dangerColor1 :
Theme.palette.successColor1
StatusBaseText {
StatusTextWithLoadingState {
id: localeCurrencyBalance
anchors.right: parent.right
font.pixelSize: 15
font.strikeout: false
@ -29,11 +40,11 @@ StatusListItem {
Row {
anchors.horizontalCenter: parent.horizontalCenter
spacing: 8
StatusBaseText {
StatusTextWithLoadingState {
id: change24HourText
font.pixelSize: 15
font.strikeout: false
color: valueColumn.textColor
customColor: root.textColor
text: LocaleUtils.currencyAmountToLocaleString(currencyPrice)
}
Rectangle {
@ -41,10 +52,11 @@ StatusListItem {
height: change24HourText.implicitHeight
color: Theme.palette.directColor9
}
StatusBaseText {
StatusTextWithLoadingState {
id: change24HourPercentageText
font.pixelSize: 15
font.strikeout: false
color: valueColumn.textColor
customColor: root.textColor
text: changePct24hour !== "" ? changePct24hour.toFixed(2) + "%" : "---"
}
}

View File

@ -30,3 +30,5 @@ AssetsDetailsHeader 1.0 AssetsDetailsHeader.qml
InformationTag 1.0 InformationTag.qml
TransactionDetailsHeader.qml 1.0 TransactionDetailsHeader.qml
TokenDelegate 1.0 TokenDelegate.qml
StyledTextEditWithLoadingState 1.0 StyledTextEditWithLoadingState.qml
LoadingTokenDelegate 1.0 LoadingTokenDelegate.qml

View File

@ -38,7 +38,7 @@ QtObject {
property var historyTransactions: walletSectionTransactions.model
property bool isNonArchivalNode: history ? history.isNonArchivalNode
: false
property bool tokensLoading: walletSection.tokensLoading
property var currentAccount: walletSectionCurrent
property var marketValueStore: TokenMarketValuesStore{}
@ -226,8 +226,13 @@ QtObject {
walletSectionAllTokens.getHistoricalDataForToken(symbol,currency)
}
property bool marketHistoryIsLoading: walletSectionAllTokens.marketHistoryIsLoading
// TODO: range until we optimize to cache the data and abuse the requests
function fetchHistoricalBalanceForTokenAsJson(address, symbol, timeIntervalEnum) {
walletSectionAllTokens.fetchHistoricalBalanceForTokenAsJson(address, symbol, timeIntervalEnum)
}
property bool balanceHistoryIsLoading: walletSectionAllTokens.balanceHistoryIsLoading
}

View File

@ -32,16 +32,31 @@ Item {
id: assetListView
objectName: "assetViewStatusListView"
anchors.fill: parent
model: SortFilterProxyModel {
sourceModel: account.assets
filters: [
ExpressionFilter {
expression: visibleForNetworkWithPositiveBalance
}
]
}
model: RootStore.tokensLoading ? 25 : filteredModel
delegate: RootStore.tokensLoading ? loadingTokenDelegate : tokenDelegate
ScrollBar.vertical: StatusScrollBar {}
}
delegate: TokenDelegate {
SortFilterProxyModel {
id: filteredModel
sourceModel: account.assets
filters: [
ExpressionFilter {
expression: visibleForNetworkWithPositiveBalance
}
]
}
Component {
id: loadingTokenDelegate
LoadingTokenDelegate {
width: ListView.view.width
}
}
Component {
id: tokenDelegate
TokenDelegate {
objectName: "AssetView_TokenListItem_" + symbol
readonly property string balance: "%1".arg(enabledNetworkBalance.amount) // Needed for the tests
width: ListView.view.width
@ -56,7 +71,5 @@ Item {
assetClicked(model)
}
}
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
}
}

View File

@ -0,0 +1,42 @@
import QtQuick 2.13
import QtQuick.Layouts 1.13
import QtQuick.Controls 2.14
import QtQuick.Window 2.12
import QtGraphicalEffects 1.12
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.views 1.0
import shared.controls 1.0
import "../stores"
Loader {
id: root
active: false
sourceComponent: Item {
LoadingComponent {
id: loadingComp
anchors.fill: parent
visible: false
}
Image {
id: mask
source: Style.svg("mask/dummyLineGraph")
sourceSize: Qt.size(parent.width, parent.height)
smooth: true
visible: false
}
OpacityMask {
source: loadingComp
anchors.fill: loadingComp
maskSource: mask
}
}
}

View File

@ -655,6 +655,8 @@ QtObject {
readonly property string seedWalletType: "seed"
readonly property string generatedWalletType: "generated"
readonly property string dummyText: "Dummy"
readonly property string windows: "windows"
readonly property string linux: "linux"
readonly property string mac: "mac"