From 7e82b3650902b903dc1a3dd77e81563accbc0b0d Mon Sep 17 00:00:00 2001 From: Khushboo Mehta Date: Tue, 27 Sep 2022 10:30:18 +0200 Subject: [PATCH] feat(@desktop/wallet): Create API to retrieve historical price for a token fixes #7260 --- .../wallet_section/all_tokens/controller.nim | 8 ++ .../all_tokens/io_interface.nim | 6 + .../main/wallet_section/all_tokens/module.nim | 11 ++ .../main/wallet_section/all_tokens/view.nim | 5 + src/app_service/service/token/async_tasks.nim | 52 ++++++++- src/app_service/service/token/dto.nim | 6 + src/app_service/service/token/service.nim | 26 +++++ src/backend/backend.nim | 15 ++- .../StatusQ/Components/StatusChartPanel.qml | 7 ++ .../AppLayouts/Wallet/views/RightTabView.qml | 20 +++- ui/imports/shared/stores/RootStore.qml | 6 + .../shared/stores/TokenMarketValuesStore.qml | 104 +++++++++++++++++ ui/imports/shared/views/AssetsDetailView.qml | 107 ++++-------------- ui/imports/shared/views/AssetsView.qml | 1 + .../shared/views/TransactionDetailView.qml | 17 +-- ui/imports/utils/Utils.qml | 16 +++ 16 files changed, 305 insertions(+), 102 deletions(-) create mode 100644 ui/imports/shared/stores/TokenMarketValuesStore.qml diff --git a/src/app/modules/main/wallet_section/all_tokens/controller.nim b/src/app/modules/main/wallet_section/all_tokens/controller.nim index 00f9ada89b..69fd44fe9e 100644 --- a/src/app/modules/main/wallet_section/all_tokens/controller.nim +++ b/src/app/modules/main/wallet_section/all_tokens/controller.nim @@ -36,6 +36,10 @@ proc init*(self: Controller) = self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args): self.delegate.refreshTokens() + self.events.on(SIGNAL_TOKEN_HISTORICAL_DATA_LOADED) do(e:Args): + let args = TokenHistoricalDataArgs(e) + self.delegate.tokenHistoricalDataResolved(args.result) + proc getTokens*(self: Controller): seq[token_service.TokenDto] = proc compare(x, y: token_service.TokenDto): int = if x.name < y.name: @@ -65,3 +69,7 @@ proc getTokenDetails*(self: Controller, address: string) = method findTokenSymbolByAddress*(self: Controller, address: string): string = return self.walletAccountService.findTokenSymbolByAddress(address) + +method getHistoricalDataForToken*(self: Controller, symbol: string, currency: string, range: int) = + self.tokenService.getHistoricalDataForToken(symbol, currency, range) + diff --git a/src/app/modules/main/wallet_section/all_tokens/io_interface.nim b/src/app/modules/main/wallet_section/all_tokens/io_interface.nim index 40f28fea9e..e4cd3335ac 100644 --- a/src/app/modules/main/wallet_section/all_tokens/io_interface.nim +++ b/src/app/modules/main/wallet_section/all_tokens/io_interface.nim @@ -32,6 +32,12 @@ method tokenDetailsWereResolved*(self: AccessInterface, tokenDetails: string) {. method findTokenSymbolByAddress*(self: AccessInterface, address: string): string {.base.} = raise newException(ValueError, "No implementation available") +method getHistoricalDataForToken*(self: AccessInterface, symbol: string, currency: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method tokenHistoricalDataResolved*(self: AccessInterface, tokenDetails: string) {.base.} = + raise newException(ValueError, "No implementation available") + # View Delegate Interface # Delegate for the view must be declared here due to use of QtObject and multi # inheritance, which is not well supported in Nim. diff --git a/src/app/modules/main/wallet_section/all_tokens/module.nim b/src/app/modules/main/wallet_section/all_tokens/module.nim index 30d1b06a66..b82e1488e8 100644 --- a/src/app/modules/main/wallet_section/all_tokens/module.nim +++ b/src/app/modules/main/wallet_section/all_tokens/module.nim @@ -7,6 +7,7 @@ import ../../../../global/global_singleton import ../../../../core/eventemitter import ../../../../../app_service/service/token/service as token_service import ../../../../../app_service/service/wallet_account/service as wallet_account_service +import ../../../../../app_service/service/token/dto export io_interface @@ -91,3 +92,13 @@ method tokenDetailsWereResolved*(self: Module, tokenDetails: string) = method findTokenSymbolByAddress*(self: Module, address: string): string = return self.controller.findTokenSymbolByAddress(address) + +method getHistoricalDataForToken*(self: Module, symbol: string, currency: string) = + self.controller.getHistoricalDataForToken(symbol, currency, WEEKLY_TIME_RANGE) + self.controller.getHistoricalDataForToken(symbol, currency, MONTHLY_TIME_RANGE) + self.controller.getHistoricalDataForToken(symbol, currency, HALF_YEARLY_TIME_RANGE) + self.controller.getHistoricalDataForToken(symbol, currency, YEARLY_TIME_RANGE) + self.controller.getHistoricalDataForToken(symbol, currency, ALL_TIME_RANGE) + +method tokenHistoricalDataResolved*(self: Module, tokenDetails: string) = + self.view.tokenHistoricalDataReady(tokenDetails) diff --git a/src/app/modules/main/wallet_section/all_tokens/view.nim b/src/app/modules/main/wallet_section/all_tokens/view.nim index 788dbec44d..6baaf5dc1e 100644 --- a/src/app/modules/main/wallet_section/all_tokens/view.nim +++ b/src/app/modules/main/wallet_section/all_tokens/view.nim @@ -77,3 +77,8 @@ QtObject: proc findTokenSymbolByAddress*(self: View, address: string): string {.slot.} = return self.delegate.findTokenSymbolByAddress(address) + + proc getHistoricalDataForToken*(self: View, symbol: string, currency: string) {.slot.} = + self.delegate.getHistoricalDataForToken(symbol, currency) + + proc tokenHistoricalDataReady*(self: View, tokenDetails: string) {.signal.} diff --git a/src/app_service/service/token/async_tasks.nim b/src/app_service/service/token/async_tasks.nim index d952bcbdb1..369895f0fa 100644 --- a/src/app_service/service/token/async_tasks.nim +++ b/src/app_service/service/token/async_tasks.nim @@ -1,12 +1,16 @@ -# include strformat, json +import times include ../../common/json_utils import ../eth/utils import ../../../backend/backend as backend +import ./dto ################################################# # Async load transactions ################################################# +const DAYS_IN_WEEK = 7 +const HOURS_IN_DAY = 24 + type GetTokenDetailsTaskArg = ref object of QObjectTaskArg chainIds: seq[int] @@ -35,3 +39,49 @@ const getTokenDetailsTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} "error": "Is this an ERC-20 or ERC-721 contract?", } arg.finish(output) + +type + GetTokenHistoricalDataTaskArg = ref object of QObjectTaskArg + symbol: string + currency: string + range: int + +const getTokenHistoricalDataTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = + let arg = decode[GetTokenHistoricalDataTaskArg](argEncoded) + var response = %*{} + try: + let td = now() + case arg.range: + of WEEKLY_TIME_RANGE: + response = backend.getHourlyMarketValues(arg.symbol, arg.currency, DAYS_IN_WEEK*HOURS_IN_DAY, 1).result + of MONTHLY_TIME_RANGE: + response = backend.getHourlyMarketValues(arg.symbol, arg.currency, getDaysInMonth(td.month, td.year)*HOURS_IN_DAY, 2).result + of HALF_YEARLY_TIME_RANGE: + response = backend.getDailyMarketValues(arg.symbol, arg.currency, int(getDaysInYear(td.year)/2), false, 1).result + of YEARLY_TIME_RANGE: + response = backend.getDailyMarketValues(arg.symbol, arg.currency, getDaysInYear(td.year), false, 1).result + of ALL_TIME_RANGE: + response = backend.getDailyMarketValues(arg.symbol, arg.currency, 1, true, 12).result + else: + let output = %* { + "symbol": arg.symbol, + "range": arg.range, + "error": "Range not defined", + } + + let output = %* { + "symbol": arg.symbol, + "range": arg.range, + "historicalData": response + } + + arg.finish(output) + return + except Exception as e: + let output = %* { + "symbol": arg.symbol, + "range": arg.range, + "error": "Historical market value not found", + } + arg.finish(output) + diff --git a/src/app_service/service/token/dto.nim b/src/app_service/service/token/dto.nim index e862654ebe..c42ebbe898 100644 --- a/src/app_service/service/token/dto.nim +++ b/src/app_service/service/token/dto.nim @@ -6,6 +6,12 @@ import web3/ethtypes, json_serialization from web3/conversions import `$` +const WEEKLY_TIME_RANGE* = 0 +const MONTHLY_TIME_RANGE* = 1 +const HALF_YEARLY_TIME_RANGE* = 2 +const YEARLY_TIME_RANGE* = 3 +const ALL_TIME_RANGE* = 4 + type TokenDto* = ref object of RootObj name*: string diff --git a/src/app_service/service/token/service.nim b/src/app_service/service/token/service.nim index 1f2c742ddf..dff5f6fd9b 100644 --- a/src/app_service/service/token/service.nim +++ b/src/app_service/service/token/service.nim @@ -21,6 +21,7 @@ include async_tasks # Signals which may be emitted by this service: const SIGNAL_TOKEN_DETAILS_LOADED* = "tokenDetailsLoaded" const SIGNAL_TOKEN_LIST_RELOADED* = "tokenListReloaded" +const SIGNAL_TOKEN_HISTORICAL_DATA_LOADED* = "tokenHistoricalDataLoaded" type TokenDetailsLoadedArgs* = ref object of Args @@ -38,6 +39,10 @@ type VisibilityToggled* = ref object of Args token*: TokenDto +type + TokenHistoricalDataArgs* = ref object of Args + result*: string + QtObject: type Service* = ref object of QObject events: EventEmitter @@ -192,3 +197,24 @@ QtObject: address: address ) self.threadpool.start(arg) + + proc tokenHistorticalDataResolved*(self: Service, response: string) {.slot.} = + let responseObj = response.parseJson + if (responseObj.kind != JObject): + info "prepared tokens are not a json object" + return + + self.events.emit(SIGNAL_TOKEN_HISTORICAL_DATA_LOADED, TokenHistoricalDataArgs( + result: response + )) + + proc getHistoricalDataForToken*(self: Service, symbol: string, currency: string, range: int) = + let arg = GetTokenHistoricalDataTaskArg( + tptr: cast[ByteAddress](getTokenHistoricalDataTask), + vptr: cast[ByteAddress](self.vptr), + slot: "tokenHistorticalDataResolved", + symbol: symbol, + currency: currency, + range: range + ) + self.threadpool.start(arg) diff --git a/src/backend/backend.nim b/src/backend/backend.nim index 466370cb39..d788b21e34 100644 --- a/src/backend/backend.nim +++ b/src/backend/backend.nim @@ -240,4 +240,17 @@ rpc(updateKeycardUID, "accounts"): newKeycardUID: string rpc(deleteKeycard, "accounts"): - keycardUid: string \ No newline at end of file + keycardUid: string + +rpc(getHourlyMarketValues, "wallet"): + symbol: string + currency: string + limit: int + aggregate: int + +rpc(getDailyMarketValues, "wallet"): + symbol: string + currency: string + limit: int + allDate: bool + aggregate: int diff --git a/ui/StatusQ/src/StatusQ/Components/StatusChartPanel.qml b/ui/StatusQ/src/StatusQ/Components/StatusChartPanel.qml index 50b417f1dc..41f2c2c55f 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusChartPanel.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusChartPanel.qml @@ -84,6 +84,12 @@ Page { */ property string selectedTimeRange: timeRangeTabBar.currentItem.text + /*! + \qmlproperty string StatusChartPanel::defaultTimeRangeIndexShown + This property holds the index of the time range tabbar to be shown by default + */ + property int defaultTimeRangeIndexShown: 0 + /*! \qmlsignal This signal is emitted when a header tab bar is clicked. @@ -108,6 +114,7 @@ Page { enabled: timeRangeModel[i].enabled }); timeRangeTabBar.addItem(timeTab); } + timeRangeTabBar.currentIndex = defaultTimeRangeIndexShown } if (!!graphsModel) { for (var j = 0; j < graphsModel.length; j++) { diff --git a/ui/app/AppLayouts/Wallet/views/RightTabView.qml b/ui/app/AppLayouts/Wallet/views/RightTabView.qml index eb06e011a0..aae6813bda 100644 --- a/ui/app/AppLayouts/Wallet/views/RightTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/RightTabView.qml @@ -24,6 +24,22 @@ Item { stack.currentIndex = 0; } + QtObject { + id: d + function getBackButtonText(index) { + switch(index) { + case 1: + return qsTr("Assets") + case 2: + return qsTr("Assets") + case 3: + return qsTr("Activity") + default: + return "" + } + } + } + ColumnLayout { anchors.fill: parent @@ -32,7 +48,7 @@ Item { Layout.fillWidth: true Layout.preferredHeight: parent.height - footer.height onCurrentIndexChanged: { - RootStore.backButtonName = ((currentIndex === 1) || (currentIndex === 2)) ? qsTr("Assets") : ""; + RootStore.backButtonName = d.getBackButtonText(currentIndex) } ColumnLayout { @@ -112,7 +128,7 @@ Item { Layout.fillHeight: true sendModal: root.sendModal contactsStore: root.contactsStore - onGoBack: stack.currentIndex = 0 + visible: (stack.currentIndex === 3) } } diff --git a/ui/imports/shared/stores/RootStore.qml b/ui/imports/shared/stores/RootStore.qml index 5fb15f9f71..cd28071e9c 100644 --- a/ui/imports/shared/stores/RootStore.qml +++ b/ui/imports/shared/stores/RootStore.qml @@ -43,6 +43,8 @@ QtObject { property var tokens: walletSectionAllTokens.all property var accounts: walletSectionAccounts.model + property var marketValueStore: TokenMarketValuesStore{} + function getNetworkColor(chainId) { return networksModule.all.getChainColor(chainId) } @@ -199,4 +201,8 @@ QtObject { function getGasEthValue(gweiValue, gasLimit) { return profileSectionModule.ensUsernamesModule.getGasEthValue(gweiValue, gasLimit) } + + function getHistoricalDataForToken(symbol, currency) { + walletSectionAllTokens.getHistoricalDataForToken(symbol,currency) + } } diff --git a/ui/imports/shared/stores/TokenMarketValuesStore.qml b/ui/imports/shared/stores/TokenMarketValuesStore.qml new file mode 100644 index 0000000000..253f1a77c9 --- /dev/null +++ b/ui/imports/shared/stores/TokenMarketValuesStore.qml @@ -0,0 +1,104 @@ +import QtQuick 2.13 + +import utils 1.0 + +QtObject { + id: root + + + enum TimeRange { + Weekly = 0, + Monthly, + HalfYearly, + Yearly, + All + } + + readonly property int hoursInADay: 24 + readonly property int avgLengthOfMonth: 30 + + readonly property var graphTabsModel: [{text: qsTr("Price"), enabled: true}, {text: qsTr("Balance"), enabled: false}] + readonly property var timeRangeTabsModel: [{text: qsTr("7D"), enabled: true}, + {text: qsTr("1M"), enabled: true}, {text: qsTr("6M"), enabled: true}, + {text: qsTr("1Y"), enabled: true}, {text: qsTr("ALL"), enabled: true}] + + property var weeklyData + property var monthlyData + property var halfYearlyData + property var yearlyData + property var allData + + property var weeklyTimeRange + property var monthlyTimeRange + property var halfYearlyTimeRange + property var yearlyTimeRange + property var allTimeRange + + readonly property var timeRange: [ + {'7D': weeklyTimeRange}, + {'1M': monthlyTimeRange}, + {'6M': halfYearlyTimeRange}, + {'1Y': yearlyTimeRange}, + {'ALL': allTimeRange} + ] + + readonly property var dataRange: [ + {'7D': weeklyData}, + {'1M': monthlyData}, + {'6M': halfYearlyData}, + {'1Y': yearlyData}, + {'ALL': allData} + ] + + property int allTimeRangeTicks: 0 + + readonly property var maxTicks: [ + {'7D': weeklyTimeRange.length/hoursInADay}, + {'1M': monthlyTimeRange.length/hoursInADay}, + {'6M': halfYearlyTimeRange.length/avgLengthOfMonth}, + {'1Y': yearlyTimeRange.length/avgLengthOfMonth}, + {'ALL': allTimeRangeTicks} + ] + + function setTimeAndValueData(data, range) { + var marketValues = [] + var timeRanges = [] + for (var i = 0; i < data.length; ++i) { + marketValues[i] = data[i].close; + + timeRanges[i] = range === TokenMarketValuesStore.TimeRange.Weekly || range === TokenMarketValuesStore.TimeRange.Monthly ? + Utils.getDayMonth(data[i].time * 1000, RootStore.accountSensitiveSettings.is24hTimeFormat): + Utils.getMonthYear(data[i].time * 1000) + } + + switch(range) { + case TokenMarketValuesStore.TimeRange.Weekly: { + weeklyData = marketValues + weeklyTimeRange = timeRanges + break + } + case TokenMarketValuesStore.TimeRange.Monthly: { + monthlyData = marketValues + monthlyTimeRange = timeRanges + break + } + case TokenMarketValuesStore.TimeRange.HalfYearly: { + halfYearlyData = marketValues + halfYearlyTimeRange = timeRanges + break + } + case TokenMarketValuesStore.TimeRange.Yearly: { + yearlyData = marketValues + yearlyTimeRange = timeRanges + break + } + case TokenMarketValuesStore.TimeRange.All: { + allData = marketValues + allTimeRange = timeRanges + if(data.length > 0) + allTimeRangeTicks = Math.abs(Qt.formatDate(new Date(data[0].time*1000), 'yyyy') - Qt.formatDate(new Date(data[data.length-1].time*1000), 'yyyy')) + break + } + } + } +} diff --git a/ui/imports/shared/views/AssetsDetailView.qml b/ui/imports/shared/views/AssetsDetailView.qml index f38eeb9b04..d8074c1c6b 100644 --- a/ui/imports/shared/views/AssetsDetailView.qml +++ b/ui/imports/shared/views/AssetsDetailView.qml @@ -21,72 +21,21 @@ Item { QtObject { id: d - //dummy data - property real stepSize: 1000 - property real minStep: 12000 - property real maxStep: 22000 + property var marketValueStore : RootStore.marketValueStore + } - property var graphTabsModel: [{text: qsTr("Price"), enabled: true}, {text: qsTr("Balance"), enabled: false}] - property var timeRangeTabsModel: [{text: qsTr("1H"), enabled: true}, - {text: qsTr("1D"), enabled: true},{text: qsTr("7D"), enabled: true}, - {text: qsTr("1M"), enabled: true}, {text: qsTr("6M"), enabled: true}, - {text: qsTr("1Y"), enabled: true}, {text: qsTr("ALL"), enabled: true}] - - property var simTimer: Timer { - running: root.visible - interval: 3000 - repeat: true - onTriggered: { - d.generateData(); + Connections { + target: walletSectionAllTokens + onTokenHistoricalDataReady: { + let response = JSON.parse(tokenDetails) + if (response === null) { + console.debug("error parsing message for tokenHistoricalDataReady: error: ", response.error) + return } - } + if(response.historicalData === null || response.historicalData <= 0) + return - function minutes(minutes = 0) { - var newMinute = new Date(new Date().getTime() - (minutes * 60 * 1000)).toString(); - if (newMinute.slice(10,12) === "00") { - var dateToday = new Date(Date.now()).toString(); - return dateToday.slice(4,7) + " " + dateToday.slice(8,10); - } - return newMinute.slice(10,16); - } - - function hour(hours = 0) { - var newHour = new Date(new Date().getTime() - (hours * 60 * 60 * 1000)).toString(); - if (newHour.slice(10,12) === "00") { - var dateToday = new Date(Date.now()).toString(); - return dateToday.slice(4,7) + " " + dateToday.slice(8,10); - } - return newHour.slice(10,16); - } - - function day(before = 0) { - var newDay = new Date(Date.now() - before * 24 * 60 * 60 * 1000).toString(); - return newDay.slice(4,7) + " " + newDay.slice(8,10); - } - - function month(before = 0) { - var newMonth = new Date(Date.now() - before * 24 * 60 * 60 * 1000).toString(); - return newMonth.slice(4,7) + " '" + newMonth.slice(newMonth.indexOf("G")-3, newMonth.indexOf("G")-1); - } - - property var timeRange: [ - {'1H': [minutes(60), minutes(55), minutes(50), minutes(45), minutes(40), minutes(35), minutes(30), minutes(25), minutes(20), minutes(15), minutes(10), minutes(5), minutes()]}, - {'1D': [hour(24), hour(23), hour(22), hour(21), hour(20), hour(19), hour(18), hour(17), hour(16), hour(15), hour(14), hour(13), - hour(12), hour(11), hour(10), hour(9), hour(8), hour(7), hour(6), hour(5), hour(4), hour(3), hour(2), hour(1), hour()]}, - {'7D': [day(6), day(5), day(4), day(3), day(2), day(1), day()]}, - {'1M': [day(30), day(28), day(26), day(24), day(22), day(20), day(18), day(16), day(14), day(12), day(10), day(8), day(6), day(4), day()]}, - {'6M': [month(150), month(120), month(90), month(60), month(30), month()]}, - {'1Y': [month(330), month(300), month(270), month(240), month(210), month(180), month(150), month(120), month(90), month(60), month(30), month()]}, - {'ALL': ['2016', '2017', '2018', '2019', '2020', '2021', '2022']} - ] - - function generateData() { - var result = []; - for (var i = 0; i < timeRange[graphDetailLoader.item.timeRangeTabBarIndex][graphDetailLoader.item.selectedTimeRange].length; ++i) { - result[i] = Math.random() * (maxStep - minStep) + minStep; - } - graphDetailLoader.item.chart.chartData.datasets[0].data = result; - graphDetailLoader.item.chart.animateToNewData(); + d.marketValueStore.setTimeAndValueData(response.historicalData, response.range) } } @@ -119,28 +68,23 @@ Item { active: root.visible sourceComponent: StatusChartPanel { id: graphDetail - graphsModel: d.graphTabsModel - timeRangeModel: d.timeRangeTabsModel - onHeaderTabClicked: { - //TODO - //if time range tab - d.generateData(); - //if graph bar - //switch graph - } + graphsModel: d.marketValueStore.graphTabsModel + defaultTimeRangeIndexShown: TokenMarketValuesStore.TimeRange.All + timeRangeModel: d.marketValueStore.timeRangeTabsModel + onHeaderTabClicked: chart.animateToNewData() chart.chartType: 'line' chart.chartData: { return { - labels: d.timeRange[graphDetail.timeRangeTabBarIndex][graphDetail.selectedTimeRange], + labels: d.marketValueStore.timeRange[graphDetail.timeRangeTabBarIndex][graphDetail.selectedTimeRange], datasets: [{ - label: 'Price', xAxisId: 'x-axis-1', yAxisId: 'y-axis-1', backgroundColor: (Theme.palette.name === "dark") ? 'rgba(136, 176, 255, 0.2)' : 'rgba(67, 96, 223, 0.2)', borderColor: (Theme.palette.name === "dark") ? 'rgba(136, 176, 255, 1)' : 'rgba(67, 96, 223, 1)', borderWidth: 3, pointRadius: 0, - //data: d.generateData() + data: d.marketValueStore.dataRange[graphDetail.timeRangeTabBarIndex][graphDetail.selectedTimeRange], + parsing: false, }] } } @@ -164,14 +108,13 @@ Item { intersect: false, displayColors: false, callbacks: { - footer: function(tooltipItem, data) { return 'Vol: $43,042,678,876'; }, label: function(tooltipItem, data) { let label = data.datasets[tooltipItem.datasetIndex].label || ''; if (label) { label += ': '; } label += tooltipItem.yLabel.toFixed(2); - return label.slice(0,label.indexOf(":")+1)+ " $"+label.slice(label.indexOf(":")+2, label.length); + return label.slice(0,label.indexOf(":")+1) + " %1".arg(RootStore.currencyStore.currentCurrencySymbol) + label.slice(label.indexOf(":") + 2, label.length); } } }, @@ -188,7 +131,10 @@ Item { fontSize: 10, fontColor: (Theme.palette.name === "dark") ? '#909090' : '#939BA1', padding: 16, - } + maxRotation: 0, + minRotation: 0, + maxTicksLimit: d.marketValueStore.maxTicks[graphDetail.timeRangeTabBarIndex][graphDetail.selectedTimeRange], + }, }], yAxes: [{ position: 'left', @@ -207,11 +153,8 @@ Item { fontSize: 10, fontColor: (Theme.palette.name === "dark") ? '#909090' : '#939BA1', padding: 8, - min: d.minStep, - max: d.maxStep, - stepSize: d.stepSize, callback: function(value, index, ticks) { - return '$' + value; + return LocaleUtils.numberToLocaleString(value) }, } }] diff --git a/ui/imports/shared/views/AssetsView.qml b/ui/imports/shared/views/AssetsView.qml index b477c6db8b..b34134ebc4 100644 --- a/ui/imports/shared/views/AssetsView.qml +++ b/ui/imports/shared/views/AssetsView.qml @@ -86,6 +86,7 @@ Item { } ] onClicked: { + RootStore.getHistoricalDataForToken(symbol, RootStore.currencyStore.currentCurrency) d.selectedAssetIndex = index assetClicked(model) } diff --git a/ui/imports/shared/views/TransactionDetailView.qml b/ui/imports/shared/views/TransactionDetailView.qml index 3b90c10ae5..950306220e 100644 --- a/ui/imports/shared/views/TransactionDetailView.qml +++ b/ui/imports/shared/views/TransactionDetailView.qml @@ -23,7 +23,6 @@ Item { property var transaction property var sendModal - signal goBack() QtObject { id: d @@ -38,23 +37,9 @@ Item { } } - StatusFlatButton { - id: backButton - anchors.top: parent.top - anchors.left: parent.left - Layout.alignment: Qt.AlignTop - anchors.topMargin: -Style.current.xlPadding - anchors.leftMargin: -Style.current.xlPadding - icon.name: "arrow-left" - icon.width: 20 - icon.height: 20 - text: qsTr("Activity") - size: StatusBaseButton.Size.Large - onClicked: root.goBack() - } StatusScrollView { - anchors.top: backButton.bottom + anchors.top: parent.top anchors.left: parent.left width: parent.width diff --git a/ui/imports/utils/Utils.qml b/ui/imports/utils/Utils.qml index c82efa65b5..9b2b6f31db 100644 --- a/ui/imports/utils/Utils.qml +++ b/ui/imports/utils/Utils.qml @@ -295,6 +295,22 @@ QtObject { return qsTr("%1D").arg(diffDay) } + function getDayMonth(value, isDDMMYYDateFormat) { + const formatDDMMYY = "d MMMM" + const formatMMDDYY = "MMMM d" + const currentFormat = isDDMMYYDateFormat ? formatDDMMYY : formatMMDDYY + var timeStamp = checkTimestamp(value, "formatLongDate") ? Qt.formatDate(new Date(value), currentFormat) : + Qt.formatDate(new Date(), currentFormat) + return formatShortDateStr(timeStamp) + } + + function getMonthYear(value) { + const formatDDMMYY = "MMMM yyyy" + var timeStamp = checkTimestamp(value, "formatLongDate") ? Qt.formatDate(new Date(value), formatDDMMYY) : + Qt.formatDate(new Date(), formatDDMMYY) + return formatShortDateStr(timeStamp) + } + function formatShortDate(value, isDDMMYYDateFormat) { const formatDDMMYY = "d MMMM yyyy" const formatMMDDYY = "MMMM d yyyy"