From cd8904fe1c2ebad651034dfffb4ec05977b74767 Mon Sep 17 00:00:00 2001 From: Hwee-Boon Yar Date: Mon, 23 Apr 2018 23:41:59 +0800 Subject: [PATCH] Display 24 hours % change, appreciation $ value, current $ value of ETH --- Trust.xcodeproj/project.pbxproj | 4 ++ .../TokensViewController.swift | 6 +- .../Tokens/ViewModels/EthCurrencyHelper.swift | 67 +++++++++++++++++++ .../EthTokenViewCellViewModel.swift | 33 +++++++-- .../ViewModels/BalanceViewModel.swift | 16 +++-- .../ViewControllers/SendViewController.swift | 10 +++ .../ViewModels/SendHeaderViewViewModel.swift | 40 ++++++++--- 7 files changed, 151 insertions(+), 25 deletions(-) create mode 100644 Trust/Tokens/ViewModels/EthCurrencyHelper.swift diff --git a/Trust.xcodeproj/project.pbxproj b/Trust.xcodeproj/project.pbxproj index 15d382caa..4d730c7a7 100644 --- a/Trust.xcodeproj/project.pbxproj +++ b/Trust.xcodeproj/project.pbxproj @@ -352,6 +352,7 @@ 5E7C7C658D619C70F1E3DE59 /* AdvancedSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C719B717E002583B1E2E9 /* AdvancedSettingsViewModel.swift */; }; 5E7C7C98EAF40E8110241DBD /* TicketTokenViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C783E3ADA4CF9554A0E7D /* TicketTokenViewCell.swift */; }; 5E7C7C9E89056069C8FEFA76 /* AlphaWalletSettingsSwitchRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7534FB6BF4D199643246 /* AlphaWalletSettingsSwitchRow.swift */; }; + 5E7C7CCC8D376C6E5C245715 /* EthCurrencyHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C73DF5FBFE756097D32B1 /* EthCurrencyHelper.swift */; }; 5E7C7CDB837DCD57E0594CBA /* TicketsViewControllerTitleHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7821694C489D5114DB18 /* TicketsViewControllerTitleHeader.swift */; }; 5E7C7CE5CA19183FCED8C907 /* TokensViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7EE467A7F5F2E5B1F660 /* TokensViewModel.swift */; }; 5E7C7CF06533EDACC8E220B3 /* StaticHTMLViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C764B98F526271E4C2A6A /* StaticHTMLViewController.swift */; }; @@ -815,6 +816,7 @@ 5E7C731B6F01534683227123 /* TicketTokenViewCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketTokenViewCellViewModel.swift; sourceTree = ""; }; 5E7C73495E0C0A207152EC25 /* LockEnterPasscodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LockEnterPasscodeViewController.swift; path = Trust/AlphaWalletLock/ViewControllers/LockEnterPasscodeViewController.swift; sourceTree = SOURCE_ROOT; }; 5E7C73617E3A4C0B9A90A5F8 /* AmountTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AmountTextField.swift; sourceTree = ""; }; + 5E7C73DF5FBFE756097D32B1 /* EthCurrencyHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EthCurrencyHelper.swift; sourceTree = ""; }; 5E7C741196D9D9C9C3EE5E30 /* LockCreatePasscodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockCreatePasscodeViewController.swift; sourceTree = ""; }; 5E7C7419F47CC8B2996AA8F9 /* TransferTicketsQuantitySelectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsQuantitySelectionViewController.swift; sourceTree = ""; }; 5E7C74A2C738BF2412D412A7 /* TicketSellInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketSellInfoViewController.swift; sourceTree = ""; }; @@ -1679,6 +1681,7 @@ 5E7C75CC640BAFFE0E789F44 /* WalletFilterViewModel.swift */, 5E7C74B82783A94091A43470 /* EthTokenViewCellViewModel.swift */, 5E7C7A16ABC8BD5D508AA641 /* ImportWalletHelpBubbleViewViewModel.swift */, + 5E7C73DF5FBFE756097D32B1 /* EthCurrencyHelper.swift */, ); path = ViewModels; sourceTree = ""; @@ -3610,6 +3613,7 @@ 5E7C76696EF7F27EC0788CDD /* GenerateTransferMagicLinkViewControllerViewModel.swift in Sources */, 5E7C75E5C64619ABFD246183 /* TransferTicketsViaWalletAddressViewController.swift in Sources */, 5E7C7EAEBB435F3909DA36FB /* TransferTicketsViaWalletAddressViewControllerViewModel.swift in Sources */, + 5E7C7CCC8D376C6E5C245715 /* EthCurrencyHelper.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Trust/Tokens/ViewControllers/TokensViewController.swift b/Trust/Tokens/ViewControllers/TokensViewController.swift index f5fb22352..16a63bf50 100644 --- a/Trust/Tokens/ViewControllers/TokensViewController.swift +++ b/Trust/Tokens/ViewControllers/TokensViewController.swift @@ -238,7 +238,8 @@ extension TokensViewController: UITableViewDelegate { let cellViewModel = EthTokenViewCellViewModel( token: token, ticker: viewModel.ticker(for: token), - currencyAmount: session.balanceCoordinator.viewModel.currencyAmount + currencyAmount: session.balanceCoordinator.viewModel.currencyAmount, + currencyAmountWithoutSymbol: session.balanceCoordinator.viewModel.currencyAmountWithoutSymbol ) return cellViewModel.cellHeight case .token: @@ -303,7 +304,8 @@ extension TokensViewController: UITableViewDataSource { viewModel: .init( token: token, ticker: viewModel.ticker(for: token), - currencyAmount: session.balanceCoordinator.viewModel.currencyAmount + currencyAmount: session.balanceCoordinator.viewModel.currencyAmount, + currencyAmountWithoutSymbol: session.balanceCoordinator.viewModel.currencyAmountWithoutSymbol ) ) return cell diff --git a/Trust/Tokens/ViewModels/EthCurrencyHelper.swift b/Trust/Tokens/ViewModels/EthCurrencyHelper.swift new file mode 100644 index 000000000..8e4a12c1b --- /dev/null +++ b/Trust/Tokens/ViewModels/EthCurrencyHelper.swift @@ -0,0 +1,67 @@ +// Copyright © 2018 Stormbird PTE. LTD. + +import Foundation + +class EthCurrencyHelper { + enum Change24h { + case appreciate(percentageChange24h: Double) + case depreciate(percentageChange24h: Double) + case none + } + var ticker: CoinTicker? + var change24h: Change24h { + if let value = percentageChange24h { + if isValueAppreciated24h { + return .appreciate(percentageChange24h: value) + } else if isValueDepreciated24h { + return .depreciate(percentageChange24h: value) + } else { + return .none + } + } else { + return .none + } + } + + private var percentageChange24h: Double? { + if let percent_change_24h = ticker?.percent_change_24h, let percentChange = Double(percent_change_24h) { + return percentChange + } else { + return nil + } + } + + private var isValueAppreciated24h: Bool { + if let percentChange = percentageChange24h { + return percentChange > 0 + } else { + return false + } + } + + private var isValueDepreciated24h: Bool { + if let percentChange = percentageChange24h { + return percentChange < 0 + } else { + return false + } + } + + public func valueChanged24h(currencyAmountWithoutSymbol: Double?) -> String? { + if let percentChange = percentageChange24h, let value = currencyAmountWithoutSymbol { + let change = value * percentChange / 100 + if let string = CurrencyFormatter.formatter.string(from: NSNumber(value: change)) { + return string + } else { + return nil + } + } else { + return nil + } + } + + init(ticker: CoinTicker?) { + self.ticker = ticker + } +} + diff --git a/Trust/Tokens/ViewModels/EthTokenViewCellViewModel.swift b/Trust/Tokens/ViewModels/EthTokenViewCellViewModel.swift index d1083cced..53cf74e6d 100644 --- a/Trust/Tokens/ViewModels/EthTokenViewCellViewModel.swift +++ b/Trust/Tokens/ViewModels/EthTokenViewCellViewModel.swift @@ -8,16 +8,19 @@ struct EthTokenViewCellViewModel { private let shortFormatter = EtherNumberFormatter.short private let token: TokenObject private let currencyAmount: String? + private let currencyAmountWithoutSymbol: Double? let ticker: CoinTicker? init( token: TokenObject, ticker: CoinTicker?, - currencyAmount: String? + currencyAmount: String?, + currencyAmountWithoutSymbol: Double? ) { self.token = token self.ticker = ticker self.currencyAmount = currencyAmount + self.currencyAmountWithoutSymbol = currencyAmountWithoutSymbol } var title: String { @@ -73,8 +76,15 @@ struct EthTokenViewCellViewModel { } var valuePercentageChangeColor: UIColor { - //TODO must have a different color when depreciate? - return Colors.appHighlightGreen + switch EthCurrencyHelper(ticker: ticker).change24h { + case .appreciate(_): + return Colors.appHighlightGreen + case .depreciate(_): + return Colors.appRed + case .none: + //TODO use the constant in Colors + return UIColor(red: 155, green: 155, blue: 155) + } } var textValueFont: UIFont { @@ -86,8 +96,14 @@ struct EthTokenViewCellViewModel { } var valuePercentageChangeValue: String { - //TODO read from model - return "+50%" + switch EthCurrencyHelper(ticker: ticker).change24h { + case .appreciate(let percentageChange24h): + return "+\(percentageChange24h)%" + case .depreciate(let percentageChange24h): + return "-\(percentageChange24h)%" + case .none: + return "-" + } } var valuePercentageChangePeriod: String { @@ -95,8 +111,11 @@ struct EthTokenViewCellViewModel { } var valueChange: String { - //TODO read from model - return "$17,000" + if let value = EthCurrencyHelper(ticker: ticker).valueChanged24h(currencyAmountWithoutSymbol: currencyAmountWithoutSymbol) { + return value + } else { + return "-" + } } var valueChangeName: String { diff --git a/Trust/Transactions/ViewModels/BalanceViewModel.swift b/Trust/Transactions/ViewModels/BalanceViewModel.swift index b843e9b10..8d56abc1d 100644 --- a/Trust/Transactions/ViewModels/BalanceViewModel.swift +++ b/Trust/Transactions/ViewModels/BalanceViewModel.swift @@ -31,14 +31,18 @@ struct BalanceViewModel: BalanceBaseViewModel { } var currencyAmount: String? { + guard let totalAmount = currencyAmountWithoutSymbol else { return nil } + return CurrencyFormatter.formatter.string(from: NSNumber(value: totalAmount)) + } + + var currencyAmountWithoutSymbol: Double? { guard let rate = rate else { return nil } guard - let currentRate = (rate.rates.filter { $0.code == config.server.symbol }.first), - currentRate.price > 0, - amount > 0 - else { return nil } - let totalAmount = amount * currentRate.price - return CurrencyFormatter.formatter.string(from: NSNumber(value: totalAmount)) + let currentRate = (rate.rates.filter { $0.code == config.server.symbol }.first), + currentRate.price > 0, + amount > 0 + else { return nil } + return amount * currentRate.price } var amountFull: String { diff --git a/Trust/Transfer/ViewControllers/SendViewController.swift b/Trust/Transfer/ViewControllers/SendViewController.swift index b789c6278..0a41ab8e3 100644 --- a/Trust/Transfer/ViewControllers/SendViewController.swift +++ b/Trust/Transfer/ViewControllers/SendViewController.swift @@ -506,6 +506,11 @@ class SendViewController: UIViewController { guard let viewModel = viewModel else { return } let amount = viewModel.amountShort self.headerViewModel.title = "\(amount) \(self.session.config.server.name) (\(viewModel.symbol))" + let etherToken = TokensDataStore.etherToken(for: self.session.config) + let ticker = self.storage.coinTicker(for: etherToken) + self.headerViewModel.ticker = ticker + self.headerViewModel.currencyAmount = self.session.balanceCoordinator.viewModel.currencyAmount + self.headerViewModel.currencyAmountWithoutSymbol = self.session.balanceCoordinator.viewModel.currencyAmountWithoutSymbol if let viewModel = self.viewModel { self.configure(viewModel: viewModel) } @@ -515,6 +520,11 @@ class SendViewController: UIViewController { let viewModel = BalanceTokenViewModel(token: token) let amount = viewModel.amountShort headerViewModel.title = "\(amount) \(viewModel.symbol)" + let etherToken = TokensDataStore.etherToken(for: self.session.config) + let ticker = self.storage.coinTicker(for: etherToken) + self.headerViewModel.ticker = ticker + self.headerViewModel.currencyAmount = self.session.balanceCoordinator.viewModel.currencyAmount + self.headerViewModel.currencyAmountWithoutSymbol = self.session.balanceCoordinator.viewModel.currencyAmountWithoutSymbol if let viewModel = self.viewModel { configure(viewModel: self.viewModel) } diff --git a/Trust/Transfer/ViewModels/SendHeaderViewViewModel.swift b/Trust/Transfer/ViewModels/SendHeaderViewViewModel.swift index 97de65e7b..aecfc1583 100644 --- a/Trust/Transfer/ViewModels/SendHeaderViewViewModel.swift +++ b/Trust/Transfer/ViewModels/SendHeaderViewViewModel.swift @@ -4,6 +4,9 @@ import UIKit struct SendHeaderViewViewModel { var title = "" + var ticker: CoinTicker? = nil + var currencyAmount: String? = nil + var currencyAmountWithoutSymbol: Double? = nil var issuer: String { return "" @@ -46,8 +49,15 @@ struct SendHeaderViewViewModel { } var valuePercentageChangeColor: UIColor { - //TODO must have a different color when depreciate? - return Colors.appHighlightGreen + switch EthCurrencyHelper(ticker: ticker).change24h { + case .appreciate(_): + return Colors.appHighlightGreen + case .depreciate(_): + return Colors.appRed + case .none: + //TODO use the constant in Colors + return UIColor(red: 155, green: 155, blue: 155) + } } var textValueFont: UIFont { @@ -59,9 +69,14 @@ struct SendHeaderViewViewModel { } var valuePercentageChangeValue: String { - //TODO read from model -// return "+50%" - return "N/A" + switch EthCurrencyHelper(ticker: ticker).change24h { + case .appreciate(let percentageChange24h): + return "+\(percentageChange24h)%" + case .depreciate(let percentageChange24h): + return "-\(percentageChange24h)%" + case .none: + return "-" + } } var valuePercentageChangePeriod: String { @@ -69,9 +84,11 @@ struct SendHeaderViewViewModel { } var valueChange: String { - //TODO read from model -// return "$17,000" - return "N/A" + if let value = EthCurrencyHelper(ticker: ticker).valueChanged24h(currencyAmountWithoutSymbol: currencyAmountWithoutSymbol) { + return value + } else { + return "-" + } } var valueChangeName: String { @@ -79,8 +96,11 @@ struct SendHeaderViewViewModel { } var value: String { - //TODO read from model - return "N/A" + if let currencyAmount = currencyAmount { + return currencyAmount + } else { + return "-" + } } var valueName: String {