Merge branch 'master' into fiat-value-not-formatted-2-decimals-in-import-ui

pull/629/head
James Sangalli 6 years ago committed by GitHub
commit 00b2a2edef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 66
      AlphaWallet/AssetDefinition/XMLHandler.swift
  2. 65
      AlphaWallet/Localization/en.lproj/Localizable.strings
  3. 65
      AlphaWallet/Localization/es.lproj/Localizable.strings
  4. 65
      AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings
  5. 5
      AlphaWallet/Market/Coordinators/UniversalLinkCoordinator.swift
  6. 10
      AlphaWallet/Models/Ether.swift
  7. 3
      AlphaWallet/Redeem/ViewControllers/RedeemTokenCardQuantitySelectionViewController.swift
  8. 3
      AlphaWallet/Redeem/ViewControllers/RedeemTokenViewController.swift
  9. 3
      AlphaWallet/Redeem/ViewControllers/TokenCardRedemptionViewController.swift
  10. 6
      AlphaWallet/Redeem/ViewModels/RedeemTokenCardQuantitySelectionViewModel.swift
  11. 3
      AlphaWallet/Redeem/ViewModels/RedeemTokenCardViewModel.swift
  12. 6
      AlphaWallet/Sell/ViewControllers/EnterSellTokensCardPriceQuantityViewController.swift
  13. 3
      AlphaWallet/Sell/ViewControllers/SellTokensCardViewController.swift
  14. 8
      AlphaWallet/Sell/ViewModels/EnterSellTokensCardPriceQuantityViewControllerViewModel.swift
  15. 11
      AlphaWallet/Sell/ViewModels/GenerateSellMagicLinkViewControllerViewModel.swift
  16. 6
      AlphaWallet/Sell/ViewModels/GenerateTransferMagicLinkViewControllerViewModel.swift
  17. 3
      AlphaWallet/Sell/ViewModels/SellTokensCardViewModel.swift
  18. 17
      AlphaWallet/Sell/ViewModels/SetSellTokensCardExpiryDateViewControllerViewModel.swift
  19. 37
      AlphaWallet/Settings/Types/Config.swift
  20. 9
      AlphaWallet/Settings/Types/Constants.swift
  21. 2
      AlphaWallet/Tokens/Types/Token.swift
  22. 6
      AlphaWallet/Tokens/Types/TokensDataStore.swift
  23. 2
      AlphaWallet/Tokens/ViewModels/EditTokenViewModel.swift
  24. 27
      AlphaWallet/Tokens/ViewModels/TokensViewModel.swift
  25. 11
      AlphaWallet/Transfer/Coordinators/TransferNFTCoordinator.swift
  26. 3
      AlphaWallet/Transfer/ViewControllers/TransferTokensCardQuantitySelectionViewController.swift
  27. 3
      AlphaWallet/Transfer/ViewControllers/TransferTokensCardViewController.swift
  28. 3
      AlphaWallet/Transfer/ViewModels/ChooseTokenCardTransferModeViewControllerViewModel.swift
  29. 3
      AlphaWallet/Transfer/ViewModels/SetTransferTokensCardExpiryDateViewControllerViewModel.swift
  30. 6
      AlphaWallet/Transfer/ViewModels/TransferTokensCardQuantitySelectionViewModel.swift
  31. 3
      AlphaWallet/Transfer/ViewModels/TransferTokensCardViaWalletAddressViewControllerViewModel.swift
  32. 3
      AlphaWallet/Transfer/ViewModels/TransferTokensCardViewModel.swift
  33. 2
      AlphaWalletTests/Market/UniversalLinkHandlerTests.swift
  34. 5
      AlphaWalletTests/Models/EtherTests.swift
  35. BIN
      AlphaWalletTests/Snapshots/ReferenceImage_64/AlphaWalletTests.EnterSellTokensCardPriceQuantityViewControllerTests/testSellTokensCardPriceQuantityViewControllerDisplay_iPhone11_3_320x568@2x.png
  36. BIN
      AlphaWalletTests/Snapshots/ReferenceImage_64/AlphaWalletTests.EnterSellTokensCardPriceQuantityViewControllerTests/testSellTokensCardPriceQuantityViewControllerDisplay_iPhone11_3_375x812@3x.png
  37. BIN
      AlphaWalletTests/Snapshots/ReferenceImage_64/AlphaWalletTests.EnterSellTokensCardPriceQuantityViewControllerTests/testSellTokensCardPriceQuantityViewControllerDisplay_iPhone11_4_375x812@3x.png
  38. BIN
      AlphaWalletTests/Snapshots/ReferenceImage_64/AlphaWalletTests.TransferTokensCardQuantitySelectionViewControllerTests/testTransferTokensCardQuantitySelectionViewControllerCanBeCreated_iPhone11_3_320x568@2x.png
  39. BIN
      AlphaWalletTests/Snapshots/ReferenceImage_64/AlphaWalletTests.TransferTokensCardQuantitySelectionViewControllerTests/testTransferTokensCardQuantitySelectionViewControllerCanBeCreated_iPhone11_3_375x812@3x.png
  40. BIN
      AlphaWalletTests/Snapshots/ReferenceImage_64/AlphaWalletTests.TransferTokensCardQuantitySelectionViewControllerTests/testTransferTokensCardQuantitySelectionViewControllerCanBeCreated_iPhone11_4_375x812@3x.png
  41. 3
      AlphaWalletTests/Transfer/ViewControllers/TransferTokensCardQuantitySelectionViewControllerTests.swift

@ -10,6 +10,15 @@ import SwiftyXMLParser
import BigInt
import TrustKeystore
enum SingularOrPlural {
case singular
case plural
}
enum TitlecaseOrNot {
case titlecase
case notTitlecase
}
// Interface to extract data from non fungible token
private class PrivateXMLHandler {
@ -74,11 +83,61 @@ private class PrivateXMLHandler {
func getName(lang: String) -> String {
if let name = contract?["name"].getElementWithLangAttribute(equals: lang)?.text {
if contractAddress.sameContract(as: Constants.ticketContractAddress) || contractAddress.sameContract(as: Constants.ticketContractAddressRopsten ) {
return "\(Constants.fifaWorldCup2018TokenNamePrefix) \(name)"
}
return name
}
return "N/A"
}
func getTokenTypeName(_ type: SingularOrPlural = .plural, titlecase: TitlecaseOrNot = .titlecase) -> String {
if contractAddress.sameContract(as: Constants.ticketContractAddress) || contractAddress.sameContract(as: Constants.ticketContractAddressRopsten) {
switch type {
case .singular:
switch titlecase {
case .titlecase:
return R.string.localizable.ticketTitlecase()
case .notTitlecase:
return R.string.localizable.ticketLowercase()
}
case .plural:
switch titlecase {
case .titlecase:
return R.string.localizable.ticketsTitlecase()
case .notTitlecase:
return R.string.localizable.ticketsLowercase()
}
}
}
if contractAddress.sameContract(as: Constants.cryptoKittiesContractAddress) {
switch titlecase {
case .titlecase:
return R.string.localizable.cryptokittiesTitlecase()
case .notTitlecase:
return R.string.localizable.cryptokittiesLowercase()
}
}
//TODO read from XML (and programatically titlecase if necessary) and fallback if missing
switch type {
case .singular:
switch titlecase {
case .titlecase:
return R.string.localizable.tokenTitlecase()
case .notTitlecase:
return R.string.localizable.tokenLowercase()
}
case .plural:
switch titlecase {
case .titlecase:
return R.string.localizable.tokensTitlecase()
case .notTitlecase:
return R.string.localizable.tokensLowercase()
}
}
}
func getLang() -> String {
let lang = Locale.preferredLanguages[0]
if lang.hasPrefix("en") {
@ -142,6 +201,11 @@ public class XMLHandler {
return privateXMLHandler.getName(lang: lang)
}
/// Expected to return names like "cryptokitties", "tickets" that are specified in the asset definition. If absent, fallback to "tokens"
func getTokenTypeName(_ type: SingularOrPlural = .plural, titlecase: TitlecaseOrNot = .titlecase) -> String {
return privateXMLHandler.getTokenTypeName(type, titlecase: titlecase)
}
func getLang() -> String {
return privateXMLHandler.getLang()
}

@ -101,7 +101,16 @@
"settings.wallets.button.title" = "Wallets";
"Symbol" = "Symbol";
"Today" = "Today";
"Tokens" = "Tokens";
"token.lowercase" = "token";
"token.titlecase" = "Token";
"tokens.lowercase" = "tokens";
"tokens.titlecase" = "Tokens";
"ticket.lowercase" = "ticket";
"ticket.titlecase" = "Ticket";
"tickets.lowercase" = "tickets";
"tickets.titlecase" = "Tickets";
"cryptokitties.lowercase" = "cryptokitties";
"cryptokitties.titlecase" = "Cryptokitties";
"tokens.newtoken.navigation.title" = "Add Custom Token";
"transaction.cell.error.title" = "Error";
"transaction.cell.received.title" = "Received";
@ -150,31 +159,31 @@
"a.wallet.ticketToken.unverifiedContract" = "UNVERIFIED";
"a.wallet.ticketToken.match.vs" = "%@-%@";
"a.wallet.ticketToken.redeem.button.title" = "Redeem";
"a.wallet.ticketToken.redeem.selectTickets.title" = "Select Tickets To Redeem:";
"a.wallet.ticketToken.redeem.selectTicketQuantity.atLeastOne.title" = "Please select quantity of tickets";
"a.wallet.ticketToken.redeem.selectTickets.atLeastOne.title" = "Please select a ticket to redeem";
"a.wallet.ticketToken.redeem.selectQuantity.title" = "Select Quantity of Tickets";
"a.wallet.ticketToken.redeem.quantity.title" = "QUANTITY OF TICKETS";
"a.wallet.ticketToken.redeem.selectTickets.title" = "Select %@ To Redeem:";
"a.wallet.ticketToken.redeem.selectTicketQuantity.atLeastOne.title" = "Please select quantity of %@";
"a.wallet.ticketToken.redeem.selectTickets.atLeastOne.title" = "Please select a %@ to redeem";
"a.wallet.ticketToken.redeem.selectQuantity.title" = "Select Quantity of %@";
"a.wallet.ticketToken.redeem.quantity.title" = "QUANTITY OF %@";
"a.wallet.ticketToken.redeem.showQRCode.title" = "Show QR Code to Redemption Booth";
"a.wallet.ticketToken.redeem.successful.title" = "Congrats";
"a.wallet.ticketToken.redeem.successful.description" = "You have successfully redeemed your ticket(s)";
"a.wallet.ticketToken.redeem.successful.description" = "You have successfully redeemed your %@";
"a.wallet.ticketToken.sell.button.title" = "Sell";
"a.wallet.ticketToken.sell.selectTickets.title" = "Select Tickets To Sell:";
"a.wallet.ticketToken.sell.selectTicketQuantity.atLeastOne.title" = "Please select quantity of tickets";
"a.wallet.ticketToken.sell.price.provide.title" = "Please enter price of tickets";
"a.wallet.ticketToken.sell.selectTickets.atLeastOne.title" = "Please select a ticket to sell";
"a.wallet.ticketToken.sell.selectTickets.title" = "Select %@ To Sell:";
"a.wallet.ticketToken.sell.selectTicketQuantity.atLeastOne.title" = "Please select quantity of %@";
"a.wallet.ticketToken.sell.price.provide.title" = "Please enter price of %@";
"a.wallet.ticketToken.sell.selectTickets.atLeastOne.title" = "Please select a %@ to sell";
"a.wallet.ticketToken.sell.selectQuantity.title" = "Set a Price";
"a.wallet.ticketToken.sell.pricePerTicket.title" = "PRICE PER TICKET";
"a.wallet.ticketToken.sell.pricePerTicket.title" = "PRICE PER %@";
"a.wallet.ticketToken.sell.dollarCostLabel.title" = "EQUIVALENT IN USD";
"a.wallet.ticketToken.sell.quantity.title" = "QUANTITY OF TICKETS";
"a.wallet.ticketToken.sell.quantity.title" = "QUANTITY OF %@";
"a.wallet.ticketToken.sell.enterLinkExpiryDate.title" = "Set MagicLink Expiry";
"a.wallet.ticketToken.sell.singleTicketSelected.title" = "1 Ticket Selected";
"a.wallet.ticketToken.sell.multipleTicketSelected.title" = "%d Tickets Selected";
"a.wallet.ticketToken.sell.perTicketEthPrice.title" = "%@ ETH/Ticket";
"a.wallet.ticketToken.sell.singleTicketSelected.title" = "1 %@ Selected";
"a.wallet.ticketToken.sell.multipleTicketSelected.title" = "%d %@ Selected";
"a.wallet.ticketToken.sell.perTicketEthPrice.title" = "%@ ETH/%@";
"a.wallet.ticketToken.sell.totalEthPrice.title" = "Total: %@ ETH";
"a.wallet.ticketToken.sell.magicLinkDescription.title" = "A MagicLink will be created to allow buyers to purchase your tickets.";
"a.wallet.ticketToken.sell.magicLinkDescription.title" = "A MagicLink will be created to allow buyers to purchase your %@.";
"a.wallet.ticketToken.sell.noteTitleLabel.title" = "IMPORTANT";
"a.wallet.ticketToken.sell.noteLabel.title" = "Before the link expires, anyone with the MagicLink can purchase your tickets with one click";
"a.wallet.ticketToken.sell.noteLabel.title" = "Before the link expires, anyone with the MagicLink can purchase your %@ with one click";
"a.wallet.ticketToken.sell.linkExpiryDate.title" = "LINK EXPIRY DATE";
"a.wallet.ticketToken.sell.linkExpiryTime.title" = "LINK EXPIRY TIME";
"a.wallet.ticketToken.sell.linkExpiryTime.atLeastNow.title" = "Please select a date in the future";
@ -184,14 +193,14 @@
"a.wallet.ticketToken.sell.confirm.cancel.button.title" = "Cancel";
"a.wallet.ticketToken.sell.confirm.button.title" = "Share MagicLink";
"a.wallet.ticketToken.sell.confirm.expiryDateDescription" = "MagicLink expires on: %@";
"a.wallet.ticketToken.sell.confirm.singleTicketSelected.title" = "1 Ticket";
"a.wallet.ticketToken.sell.confirm.multipleTicketSelected.title" = "%d Tickets";
"a.wallet.ticketToken.sell.confirm.singleTicketSelected.title" = "1 %@";
"a.wallet.ticketToken.sell.confirm.multipleTicketSelected.title" = "%d %@";
"a.wallet.ticketToken.transfer.button.title" = "Transfer";
"a.wallet.ticketToken.transfer.selectTickets.title" = "Select Tickets To Transfer:";
"a.wallet.ticketToken.transfer.selectTicketQuantity.atLeastOne.title" = "Please select quantity of tickets";
"a.wallet.ticketToken.transfer.selectTickets.atLeastOne.title" = "Please select a ticket to transfer";
"a.wallet.ticketToken.transfer.selectQuantity.title" = "Transfer Tickets";
"a.wallet.ticketToken.transfer.quantity.title" = "QUANTITY OF TICKETS";
"a.wallet.ticketToken.transfer.selectTickets.title" = "Select %@ To Transfer:";
"a.wallet.ticketToken.transfer.selectTicketQuantity.atLeastOne.title" = "Please select quantity of %@";
"a.wallet.ticketToken.transfer.selectTickets.atLeastOne.title" = "Please select a %@ to transfer";
"a.wallet.ticketToken.transfer.selectQuantity.title" = "Transfer %@";
"a.wallet.ticketToken.transfer.quantity.title" = "QUANTITY OF %@";
"a.wallet.ticketToken.transfer.mode.magicLink.button.title" = "MagicLink for Picking Up";
"a.wallet.ticketToken.transfer.mode.now.button.title" = "Transfer now";
"a.wallet.ticketToken.transfer.confirm.title" = "Generate MagicLink";
@ -201,9 +210,9 @@
"a.wallet.ticketToken.transfer.linkExpiryTime.atLeastNow.title" = "Please select a date in the future";
"a.wallet.ticketToken.transfer" = "PHONE NUMBER";
"a.wallet.ticketToken.transfer.noteLabel.title" = "Before the link expires, anyone with the MagicLink can claim your tickets with one click";
"a.wallet.ticketToken.transfer.success.title" = "Your ticket has been transferred";
"a.wallet.ticketToken.transfer.failed.title" = "Your ticket was not transferred";
"a.wallet.ticketToken.transfer.inProgress.title" = "Transferring ticket...";
"a.wallet.ticketToken.transfer.success.title" = "Your %@ has been transferred";
"a.wallet.ticketToken.transfer.failed.title" = "Your %@ was not transferred";
"a.wallet.ticketToken.transfer.inProgress.title" = "Transferring %@...";
"a.wallet.ticketTokenBundle.status.sold.title" = "Sold";
"a.wallet.ticketTokenBundle.status.redeemed.title" = "Redeemed";
"a.wallet.ticketTokenBundle.status.transferred.title" = "Transferred";

@ -111,7 +111,16 @@
"settings.wallets.button.title" = "Carteras";
"Symbol" = "Symbol";
"Today" = "Hoy";
"Tokens" = "Tokens";
"token.lowercase" = "token";
"token.titlecase" = "Token";
"tokens.lowercase" = "tokens";
"tokens.titlecase" = "Tokens";
"ticket.lowercase" = "ticket";
"ticket.titlecase" = "Ticket";
"tickets.lowercase" = "tickets";
"tickets.titlecase" = "Tickets";
"cryptokitties.lowercase" = "cryptokitties";
"cryptokitties.titlecase" = "Cryptokitties";
"tokens.newtoken.navigation.title" = "Add Custom Token";
"transaction.cell.error.title" = "Error";
"transaction.cell.received.title" = "Recibido";
@ -150,31 +159,31 @@
"a.wallet.ticketToken.unverifiedContract" = "UNVERIFIED";
"a.wallet.ticketToken.match.vs" = "%@-%@";
"a.wallet.ticketToken.redeem.button.title" = "Redeem";
"a.wallet.ticketToken.redeem.selectTickets.title" = "Select Tickets To Redeem:";
"a.wallet.ticketToken.redeem.selectTicketQuantity.atLeastOne.title" = "Please select quantity of tickets";
"a.wallet.ticketToken.redeem.selectTickets.atLeastOne.title" = "Please select a ticket to redeem";
"a.wallet.ticketToken.redeem.selectQuantity.title" = "Select Quantity of Tickets";
"a.wallet.ticketToken.redeem.quantity.title" = "QUANTITY OF TICKETS";
"a.wallet.ticketToken.redeem.selectTickets.title" = "Select %@ To Redeem:";
"a.wallet.ticketToken.redeem.selectTicketQuantity.atLeastOne.title" = "Please select quantity of %@";
"a.wallet.ticketToken.redeem.selectTickets.atLeastOne.title" = "Please select a %@ to redeem";
"a.wallet.ticketToken.redeem.selectQuantity.title" = "Select Quantity of %@";
"a.wallet.ticketToken.redeem.quantity.title" = "QUANTITY OF %@";
"a.wallet.ticketToken.redeem.showQRCode.title" = "Show QR Code to Redemption Booth";
"a.wallet.ticketToken.redeem.successful.title" = "Congrats";
"a.wallet.ticketToken.redeem.successful.description" = "You have successfully redeemed your ticket(s)";
"a.wallet.ticketToken.redeem.successful.description" = "You have successfully redeemed your %@";
"a.wallet.ticketToken.sell.button.title" = "Sell";
"a.wallet.ticketToken.sell.selectTickets.title" = "Select Tickets To Sell:";
"a.wallet.ticketToken.sell.selectTicketQuantity.atLeastOne.title" = "Please select quantity of tickets";
"a.wallet.ticketToken.sell.price.provide.title" = "Please enter price of tickets";
"a.wallet.ticketToken.sell.selectTickets.atLeastOne.title" = "Please select a ticket to sell";
"a.wallet.ticketToken.sell.selectTickets.title" = "Select %@ To Sell:";
"a.wallet.ticketToken.sell.selectTicketQuantity.atLeastOne.title" = "Please select quantity of %@";
"a.wallet.ticketToken.sell.price.provide.title" = "Please enter price of %@";
"a.wallet.ticketToken.sell.selectTickets.atLeastOne.title" = "Please select a %@ to sell";
"a.wallet.ticketToken.sell.selectQuantity.title" = "Set a Price";
"a.wallet.ticketToken.sell.pricePerTicket.title" = "PRICE PER TICKET";
"a.wallet.ticketToken.sell.pricePerTicket.title" = "PRICE PER %@";
"a.wallet.ticketToken.sell.dollarCostLabel.title" = "EQUIVALENT IN USD";
"a.wallet.ticketToken.sell.quantity.title" = "QUANTITY OF TICKETS";
"a.wallet.ticketToken.sell.quantity.title" = "QUANTITY OF %@";
"a.wallet.ticketToken.sell.enterLinkExpiryDate.title" = "Set MagicLink Expiry";
"a.wallet.ticketToken.sell.singleTicketSelected.title" = "1 Ticket Selected";
"a.wallet.ticketToken.sell.multipleTicketSelected.title" = "%d Tickets Selected";
"a.wallet.ticketToken.sell.perTicketEthPrice.title" = "%@ ETH/Ticket";
"a.wallet.ticketToken.sell.singleTicketSelected.title" = "1 %@ Selected";
"a.wallet.ticketToken.sell.multipleTicketSelected.title" = "%d %@ Selected";
"a.wallet.ticketToken.sell.perTicketEthPrice.title" = "%@ ETH/%@";
"a.wallet.ticketToken.sell.totalEthPrice.title" = "Total: %@ ETH";
"a.wallet.ticketToken.sell.magicLinkDescription.title" = "A MagicLink will be created to allow buyers to purchase your tickets.";
"a.wallet.ticketToken.sell.magicLinkDescription.title" = "A MagicLink will be created to allow buyers to purchase your %@.";
"a.wallet.ticketToken.sell.noteTitleLabel.title" = "IMPORTANT";
"a.wallet.ticketToken.sell.noteLabel.title" = "Before the link expires, anyone with the MagicLink can purchase your tickets with one click";
"a.wallet.ticketToken.sell.noteLabel.title" = "Before the link expires, anyone with the MagicLink can purchase your %@ with one click";
"a.wallet.ticketToken.sell.linkExpiryDate.title" = "LINK EXPIRY DATE";
"a.wallet.ticketToken.sell.linkExpiryTime.title" = "LINK EXPIRY TIME";
"a.wallet.ticketToken.sell.linkExpiryTime.atLeastNow.title" = "Please select a date in the future";
@ -184,14 +193,14 @@
"a.wallet.ticketToken.sell.confirm.cancel.button.title" = "Cancel";
"a.wallet.ticketToken.sell.confirm.button.title" = "Share MagicLink";
"a.wallet.ticketToken.sell.confirm.expiryDateDescription" = "MagicLink expires on: %@";
"a.wallet.ticketToken.sell.confirm.singleTicketSelected.title" = "1 Ticket";
"a.wallet.ticketToken.sell.confirm.multipleTicketSelected.title" = "%d Tickets";
"a.wallet.ticketToken.sell.confirm.singleTicketSelected.title" = "1 %@";
"a.wallet.ticketToken.sell.confirm.multipleTicketSelected.title" = "%d %@";
"a.wallet.ticketToken.transfer.button.title" = "Transfer";
"a.wallet.ticketToken.transfer.selectTickets.title" = "Select Tickets To Transfer:";
"a.wallet.ticketToken.transfer.selectTicketQuantity.atLeastOne.title" = "Please select quantity of tickets";
"a.wallet.ticketToken.transfer.selectTickets.atLeastOne.title" = "Please select a ticket to transfer";
"a.wallet.ticketToken.transfer.selectQuantity.title" = "Transfer Tickets";
"a.wallet.ticketToken.transfer.quantity.title" = "QUANTITY OF TICKETS";
"a.wallet.ticketToken.transfer.selectTickets.title" = "Select %@ To Transfer:";
"a.wallet.ticketToken.transfer.selectTicketQuantity.atLeastOne.title" = "Please select quantity of %@";
"a.wallet.ticketToken.transfer.selectTickets.atLeastOne.title" = "Please select a %@ to transfer";
"a.wallet.ticketToken.transfer.selectQuantity.title" = "Transfer %@";
"a.wallet.ticketToken.transfer.quantity.title" = "QUANTITY OF %@";
"a.wallet.ticketToken.transfer.mode.magicLink.button.title" = "MagicLink for Picking Up";
"a.wallet.ticketToken.transfer.mode.now.button.title" = "Transfer now";
"a.wallet.ticketToken.transfer.confirm.title" = "Generate MagicLink";
@ -201,9 +210,9 @@
"a.wallet.ticketToken.transfer.linkExpiryTime.atLeastNow.title" = "Please select a date in the future";
"a.wallet.ticketToken.transfer" = "PHONE NUMBER";
"a.wallet.ticketToken.transfer.noteLabel.title" = "Before the link expires, anyone with the MagicLink can claim your tickets with one click";
"a.wallet.ticketToken.transfer.success.title" = "Your ticket has been transferred";
"a.wallet.ticketToken.transfer.failed.title" = "Your ticket was not transferred";
"a.wallet.ticketToken.transfer.inProgress.title" = "Transferring ticket...";
"a.wallet.ticketToken.transfer.success.title" = "Your %@ has been transferred";
"a.wallet.ticketToken.transfer.failed.title" = "Your %@ was not transferred";
"a.wallet.ticketToken.transfer.inProgress.title" = "Transferring %@...";
"a.wallet.ticketTokenBundle.status.sold.title" = "Sold";
"a.wallet.ticketTokenBundle.status.redeemed.title" = "Redeemed";
"a.wallet.ticketTokenBundle.status.transferred.title" = "Transferred";

@ -90,7 +90,16 @@
"settings.wallets.button.title" = "钱包";
"Symbol" = "符号";
"Today" = "今天";
"Tokens" = "通证";
"token.lowercase" = "通证";
"token.titlecase" = "通证";
"tokens.lowercase" = "通证";
"tokens.titlecase" = "通证";
"ticket.lowercase" = "门票";
"ticket.titlecase" = "门票";
"tickets.lowercase" = "门票";
"tickets.titlecase" = "门票";
"cryptokitties.lowercase" = "cryptokitties";
"cryptokitties.titlecase" = "Cryptokitties";
"tokens.newtoken.navigation.title" = "添加自定义通证";
"transaction.cell.error.title" = "错误";
"transaction.cell.received.title" = "已收到";
@ -150,31 +159,31 @@
"a.wallet.ticketToken.unverifiedContract" = "没有验证";
"a.wallet.ticketToken.match.vs" = "%@-%@";
"a.wallet.ticketToken.redeem.button.title" = "兑换";
"a.wallet.ticketToken.redeem.selectTickets.title" = "选择要兑换的门票:";
"a.wallet.ticketToken.redeem.selectTicketQuantity.atLeastOne.title" = "选择门票数量";
"a.wallet.ticketToken.redeem.selectTickets.atLeastOne.title" = "选择门票数量";
"a.wallet.ticketToken.redeem.selectQuantity.title" = "选择门票数量";
"a.wallet.ticketToken.redeem.quantity.title" = "门票数量";
"a.wallet.ticketToken.redeem.selectTickets.title" = "选择要兑换的%@:";
"a.wallet.ticketToken.redeem.selectTicketQuantity.atLeastOne.title" = "选择%@数量";
"a.wallet.ticketToken.redeem.selectTickets.atLeastOne.title" = "选择%@数量";
"a.wallet.ticketToken.redeem.selectQuantity.title" = "选择%@数量";
"a.wallet.ticketToken.redeem.quantity.title" = "%@数量";
"a.wallet.ticketToken.redeem.showQRCode.title" = "请在兑票柜台展示你的QR码";
"a.wallet.ticketToken.redeem.successful.title" = "恭喜";
"a.wallet.ticketToken.redeem.successful.description" = "您刚刚成功的兑换了你的门票";
"a.wallet.ticketToken.redeem.successful.description" = "您刚刚成功的兑换了你的%@";
"a.wallet.ticketToken.sell.button.title" = "出售";
"a.wallet.ticketToken.sell.selectTickets.title" = "选择要出售的门票:";
"a.wallet.ticketToken.sell.selectTicketQuantity.atLeastOne.title" = "选择门票数量";
"a.wallet.ticketToken.sell.price.provide.title" = "请输入价";
"a.wallet.ticketToken.sell.selectTickets.atLeastOne.title" = "选择门票数量";
"a.wallet.ticketToken.sell.selectTickets.title" = "选择要出售的%@:";
"a.wallet.ticketToken.sell.selectTicketQuantity.atLeastOne.title" = "选择%@数量";
"a.wallet.ticketToken.sell.price.provide.title" = "请输入%@价";
"a.wallet.ticketToken.sell.selectTickets.atLeastOne.title" = "选择%@数量";
"a.wallet.ticketToken.sell.selectQuantity.title" = "设置一个价格";
"a.wallet.ticketToken.sell.pricePerTicket.title" = "门票单价";
"a.wallet.ticketToken.sell.pricePerTicket.title" = "%@单价";
"a.wallet.ticketToken.sell.dollarCostLabel.title" = "相当于USD";
"a.wallet.ticketToken.sell.quantity.title" = "门票数量";
"a.wallet.ticketToken.sell.quantity.title" = "%@数量";
"a.wallet.ticketToken.sell.enterLinkExpiryDate.title" = "设置MagicLink的有效期";
"a.wallet.ticketToken.sell.singleTicketSelected.title" = "已选择1张门票";
"a.wallet.ticketToken.sell.multipleTicketSelected.title" = "已选择%d张门票";
"a.wallet.ticketToken.sell.perTicketEthPrice.title" = "%@ ETH/门票";
"a.wallet.ticketToken.sell.singleTicketSelected.title" = "已选择1张%@";
"a.wallet.ticketToken.sell.multipleTicketSelected.title" = "已选择%d张%@";
"a.wallet.ticketToken.sell.perTicketEthPrice.title" = "%@ ETH/%@";
"a.wallet.ticketToken.sell.totalEthPrice.title" = "总价: %@ ETH";
"a.wallet.ticketToken.sell.magicLinkDescription.title" = "你将创建一个MagicLink销售链接,买家可以通过点击MagicLink来购买你的门票.";
"a.wallet.ticketToken.sell.magicLinkDescription.title" = "你将创建一个MagicLink销售链接,买家可以通过点击MagicLink来购买你的%@.";
"a.wallet.ticketToken.sell.noteTitleLabel.title" = "注意";
"a.wallet.ticketToken.sell.noteLabel.title" = "在MagicLink链接失效前,任何人都可以通过点击链接来购买你的门票";
"a.wallet.ticketToken.sell.noteLabel.title" = "在MagicLink链接失效前,任何人都可以通过点击链接来购买你的%@";
"a.wallet.ticketToken.sell.linkExpiryDate.title" = "链接失效日期";
"a.wallet.ticketToken.sell.linkExpiryTime.title" = "链接失效时间";
"a.wallet.ticketToken.sell.linkExpiryTime.atLeastNow.title" = "请输入一个未来时间";
@ -184,14 +193,14 @@
"a.wallet.ticketToken.sell.confirm.cancel.button.title" = "取消";
"a.wallet.ticketToken.sell.confirm.button.title" = "分享MagicLink链接";
"a.wallet.ticketToken.sell.confirm.expiryDateDescription" = "MagicLink有效期至: %@";
"a.wallet.ticketToken.sell.confirm.singleTicketSelected.title" = "1 张门票";
"a.wallet.ticketToken.sell.confirm.multipleTicketSelected.title" = "%d 张门票";
"a.wallet.ticketToken.sell.confirm.singleTicketSelected.title" = "1 张%@";
"a.wallet.ticketToken.sell.confirm.multipleTicketSelected.title" = "%d 张%@";
"a.wallet.ticketToken.transfer.button.title" = "转让";
"a.wallet.ticketToken.transfer.selectTickets.title" = "选择要转让的门票:";
"a.wallet.ticketToken.transfer.selectTicketQuantity.atLeastOne.title" = "选择门票数量";
"a.wallet.ticketToken.transfer.selectTickets.atLeastOne.title" = "选择门票数量";
"a.wallet.ticketToken.transfer.selectQuantity.title" = "转让门票";
"a.wallet.ticketToken.transfer.quantity.title" = "门票数量";
"a.wallet.ticketToken.transfer.selectTickets.title" = "选择要转让的%@:";
"a.wallet.ticketToken.transfer.selectTicketQuantity.atLeastOne.title" = "选择%@数量";
"a.wallet.ticketToken.transfer.selectTickets.atLeastOne.title" = "选择%@数量";
"a.wallet.ticketToken.transfer.selectQuantity.title" = "转让%@";
"a.wallet.ticketToken.transfer.quantity.title" = "%@数量";
"a.wallet.ticketToken.transfer.mode.magicLink.button.title" = "通过MagicLink导出门票";
"a.wallet.ticketToken.transfer.mode.now.button.title" = "现在直接转让门票";
"a.wallet.ticketToken.transfer.confirm.title" = "MagicLink转让链接";
@ -201,9 +210,9 @@
"a.wallet.ticketToken.transfer.linkExpiryTime.atLeastNow.title" = "请选择一个未来时间";
"a.wallet.ticketToken.transfer" = "电话号码";
"a.wallet.ticketToken.transfer.noteLabel.title" = "在MagicLink链接失效之前,任何人都可以通过点击MagicLink来导入你的门票";
"a.wallet.ticketToken.transfer.success.title" = "你的门票已经被转让";
"a.wallet.ticketToken.transfer.failed.title" = "你的门票没有被转让";
"a.wallet.ticketToken.transfer.inProgress.title" = "转让门票中...";
"a.wallet.ticketToken.transfer.success.title" = "你的%@已经被转让";
"a.wallet.ticketToken.transfer.failed.title" = "你的%@没有被转让";
"a.wallet.ticketToken.transfer.inProgress.title" = "转让%@中...";
"a.wallet.ticketTokenBundle.status.sold.title" = "已出售";
"a.wallet.ticketTokenBundle.status.redeemed.title" = "已兑换";
"a.wallet.ticketTokenBundle.status.transferred.title" = "已转让";

@ -75,10 +75,11 @@ class UniversalLinkCoordinator: Coordinator {
@discardableResult private func handlePaidImportsImpl(signedOrder: SignedOrder) -> Bool {
guard isShowingImportUserInterface else { return false }
//TODO we might not need to pass a TokenObject. Maybe something simpler? Especially since name and symbol is unused
//TODO: not always ERC875
let tokenObject = TokenObject(contract: signedOrder.order.contractAddress,
name: Constants.event,
symbol: "FIFA",
name: "",
symbol: "",
decimals: 0,
value: signedOrder.order.price.description,
isCustom: true,

@ -22,8 +22,18 @@ public struct Ether {
extension Ether: CustomStringConvertible {
public var description: String {
return unformattedDescription
}
public var formattedDescription: String {
return EtherNumberFormatter().string(from: ether)
}
public var unformattedDescription: String {
let formatter = EtherNumberFormatter()
formatter.groupingSeparator = ""
return formatter.string(from: ether)
}
}
extension Ether: LosslessStringConvertible {

@ -116,8 +116,9 @@ class RedeemTokenCardQuantitySelectionViewController: UIViewController, TokenVer
@objc
func nextButtonTapped() {
if quantityStepper.value == 0 {
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenRedeemSelectTicketQuantityAtLeastOneTitle(),
message: R.string.localizable.aWalletTicketTokenRedeemSelectTicketQuantityAtLeastOneTitle(tokenTypeName),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,

@ -107,8 +107,9 @@ class RedeemTokenViewController: UIViewController, TokenVerifiableStatusViewCont
func nextButtonTapped() {
let selectedTicketHolders = viewModel.ticketHolders.filter { $0.isSelected }
if selectedTicketHolders.isEmpty {
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.singular, titlecase: .notTitlecase)
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenRedeemSelectTicketsAtLeastOneTitle(),
message: R.string.localizable.aWalletTicketTokenRedeemSelectTicketsAtLeastOneTitle(tokenTypeName),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,

@ -135,8 +135,9 @@ class TokenCardRedemptionViewController: UIViewController, TokenVerifiableStatus
private func showSuccessMessage() {
invalidateTimer()
let tokenTypeName = XMLHandler(contract: contract).getTokenTypeName()
UIAlertController.alert(title: R.string.localizable.aWalletTicketTokenRedeemSuccessfulTitle(),
message: R.string.localizable.aWalletTicketTokenRedeemSuccessfulDescription(),
message: R.string.localizable.aWalletTicketTokenRedeemSuccessfulDescription(tokenTypeName),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,

@ -15,7 +15,8 @@ struct RedeemTokenCardQuantitySelectionViewModel {
var ticketHolder: TokenHolder
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenRedeemSelectQuantityTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
return R.string.localizable.aWalletTicketTokenRedeemSelectQuantityTitle(tokenTypeName)
}
var maxValue: Int {
@ -51,6 +52,7 @@ struct RedeemTokenCardQuantitySelectionViewModel {
}
var subtitleText: String {
return R.string.localizable.aWalletTicketTokenRedeemQuantityTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
return R.string.localizable.aWalletTicketTokenRedeemQuantityTitle(tokenTypeName.localizedUppercase)
}
}

@ -32,7 +32,8 @@ struct RedeemTokenCardViewModel {
}
var title: String {
return R.string.localizable.aWalletTicketTokenRedeemSelectTicketsTitle ()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
return R.string.localizable.aWalletTicketTokenRedeemSelectTicketsTitle(tokenTypeName)
}
var buttonTitleColor: UIColor {

@ -222,8 +222,9 @@ class EnterSellTokensCardPriceQuantityViewController: UIViewController, TokenVer
@objc
func nextButtonTapped() {
guard quantityStepper.value > 0 else {
let tokenTypeName = XMLHandler(contract: contract).getTokenTypeName()
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenSellSelectTicketQuantityAtLeastOneTitle(),
message: R.string.localizable.aWalletTicketTokenSellSelectTicketQuantityAtLeastOneTitle(tokenTypeName),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,
@ -239,8 +240,9 @@ class EnterSellTokensCardPriceQuantityViewController: UIViewController, TokenVer
}
guard !noPrice else {
let tokenTypeName = XMLHandler(contract: contract).getTokenTypeName(.plural, titlecase: .notTitlecase)
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenSellPriceProvideTitle(),
message: R.string.localizable.aWalletTicketTokenSellPriceProvideTitle(tokenTypeName),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,

@ -101,8 +101,9 @@ class SellTokensCardViewController: UIViewController, TokenVerifiableStatusViewC
func nextButtonTapped() {
let selectedTicketHolders = viewModel.ticketHolders.filter { $0.isSelected }
if selectedTicketHolders.isEmpty {
let tokenTypeName = XMLHandler(contract: contract).getTokenTypeName(.singular, titlecase: .notTitlecase)
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenSellSelectTicketsAtLeastOneTitle(),
message: R.string.localizable.aWalletTicketTokenSellSelectTicketsAtLeastOneTitle(tokenTypeName),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,

@ -47,11 +47,13 @@ struct EnterSellTokensCardPriceQuantityViewControllerViewModel {
}
var quantityLabelText: String {
return R.string.localizable.aWalletTicketTokenSellQuantityTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
return R.string.localizable.aWalletTicketTokenSellQuantityTitle(tokenTypeName.localizedUppercase)
}
var pricePerTicketLabelText: String {
return R.string.localizable.aWalletTicketTokenSellPricePerTicketTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.singular)
return R.string.localizable.aWalletTicketTokenSellPricePerTicketTitle(tokenTypeName.localizedUppercase)
}
var linkExpiryDateLabelText: String {
@ -75,7 +77,7 @@ struct EnterSellTokensCardPriceQuantityViewControllerViewModel {
}
var ethCostLabelText: String {
return "\(ethCost) ETH"
return "\(ethCost.formattedDescription) ETH"
}
var ethCostLabelColor: UIColor {

@ -63,19 +63,22 @@ struct GenerateSellMagicLinkViewControllerViewModel {
var ticketCountLabelText: String {
if ticketCount == 1 {
return R.string.localizable.aWalletTicketTokenSellConfirmSingleTicketSelectedTitle()
let tokenTypeName = XMLHandler(contract: ticketHolder.contractAddress).getTokenTypeName(.singular, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenSellConfirmSingleTicketSelectedTitle(tokenTypeName)
} else {
return R.string.localizable.aWalletTicketTokenSellConfirmMultipleTicketSelectedTitle(ticketHolder.count)
let tokenTypeName = XMLHandler(contract: ticketHolder.contractAddress).getTokenTypeName(.plural, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenSellConfirmMultipleTicketSelectedTitle(ticketHolder.count, tokenTypeName)
}
}
var perTicketPriceLabelText: String {
let tokenTypeName = XMLHandler(contract: ticketHolder.contractAddress).getTokenTypeName(.singular, titlecase: .titlecase)
let amount = ethCost / ticketCount
return R.string.localizable.aWalletTicketTokenSellPerTicketEthPriceTitle(String(amount))
return R.string.localizable.aWalletTicketTokenSellPerTicketEthPriceTitle(amount.formattedDescription)
}
var totalEthLabelText: String {
return R.string.localizable.aWalletTicketTokenSellTotalEthPriceTitle(String(ethCost))
return R.string.localizable.aWalletTicketTokenSellTotalEthPriceTitle(ethCost.formattedDescription)
}
var detailsBackgroundBackgroundColor: UIColor {

@ -62,9 +62,11 @@ struct GenerateTransferMagicLinkViewControllerViewModel {
var ticketCountLabelText: String {
if ticketCount == 1 {
return R.string.localizable.aWalletTicketTokenSellConfirmSingleTicketSelectedTitle()
let tokenTypeName = XMLHandler(contract: ticketHolder.contractAddress).getTokenTypeName(.singular, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenSellConfirmSingleTicketSelectedTitle(tokenTypeName)
} else {
return R.string.localizable.aWalletTicketTokenSellConfirmMultipleTicketSelectedTitle(ticketHolder.count)
let tokenTypeName = XMLHandler(contract: ticketHolder.contractAddress).getTokenTypeName(.plural, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenSellConfirmMultipleTicketSelectedTitle(ticketHolder.count, tokenTypeName)
}
}

@ -26,7 +26,8 @@ struct SellTokensCardViewModel {
}
var title: String {
return R.string.localizable.aWalletTicketTokenSellSelectTicketsTitle ()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
return R.string.localizable.aWalletTicketTokenSellSelectTicketsTitle(tokenTypeName)
}
var buttonTitleColor: UIColor {

@ -54,7 +54,8 @@ struct SetSellTokensCardExpiryDateViewControllerViewModel {
}
var descriptionLabelText: String {
return R.string.localizable.aWalletTicketTokenSellMagicLinkDescriptionTitle()
let tokenTypeName = XMLHandler(contract: token.contract).getTokenTypeName(.plural, titlecase: .notTitlecase)
return R.string.localizable.aWalletTicketTokenSellMagicLinkDescriptionTitle(tokenTypeName)
}
var descriptionLabelFont: UIFont {
@ -67,19 +68,22 @@ struct SetSellTokensCardExpiryDateViewControllerViewModel {
var ticketCountLabelText: String {
if ticketCount == 1 {
return R.string.localizable.aWalletTicketTokenSellSingleTicketSelectedTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.singular, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenSellSingleTicketSelectedTitle(tokenTypeName)
} else {
return R.string.localizable.aWalletTicketTokenSellMultipleTicketSelectedTitle(ticketHolder.count)
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.plural, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenSellMultipleTicketSelectedTitle(ticketHolder.count, tokenTypeName)
}
}
var perTicketPriceLabelText: String {
let tokenTypeName = XMLHandler(contract: token.contract).getTokenTypeName(.singular, titlecase: .titlecase)
let amount = ethCost / ticketCount
return R.string.localizable.aWalletTicketTokenSellPerTicketEthPriceTitle(String(amount))
return R.string.localizable.aWalletTicketTokenSellPerTicketEthPriceTitle(amount.formattedDescription)
}
var totalEthLabelText: String {
return R.string.localizable.aWalletTicketTokenSellTotalEthPriceTitle(String(ethCost))
return R.string.localizable.aWalletTicketTokenSellTotalEthPriceTitle(ethCost.formattedDescription)
}
var noteTitleLabelText: String {
@ -95,7 +99,8 @@ struct SetSellTokensCardExpiryDateViewControllerViewModel {
}
var noteLabelText: String {
return R.string.localizable.aWalletTicketTokenSellNoteLabelTitle()
let tokenTypeName = XMLHandler(contract: token.contract).getTokenTypeName(.plural, titlecase: .notTitlecase)
return R.string.localizable.aWalletTicketTokenSellNoteLabelTitle(tokenTypeName)
}
var noteLabelFont: UIFont {

@ -126,47 +126,18 @@ struct Config {
}
}
var ticketContractAddress: String? {
switch server {
case .main:
return "0xA66A3F08068174e8F005112A8b2c7A507a822335"
case .ropsten:
return "0xd8e5f58de3933e1e35f9c65eb72cb188674624f3"
default:
return nil
}
}
///Debugging flag. Set to false to disable auto fetching prices, etc to cut down on network calls
let isAutoFetchingDisabled = false
func createDefaultTicketToken(forContract contract: String) -> ERCToken? {
//TODO move?
func getContractLocalizedName(forContract contract: String) -> String? {
guard let contractAddress = Address(string: contract) else { return nil }
let xmlHandler = XMLHandler(contract: contract)
let lang = xmlHandler.getLang()
let name = xmlHandler.getName(lang: lang)
//TODO get symbol from RPC node, but this doesn't provide much benefit as it is a hardcoded
//placeholder anyway
//GetSymbolCoordinator(web3: Web3Swift()).getSymbol(for: contractAddress) { result in }
switch server {
case .main:
return ERCToken(
contract: contractAddress,
name: Constants.event + " " + name,
symbol: "SHANKAI",
decimals: 0,
type: .erc875,
balance: []
)
case .ropsten:
return ERCToken(
contract: contractAddress,
name: name,
symbol: "TEST",
decimals: 0,
type: .erc875,
balance: []
)
case .main, .ropsten:
return name
case .kovan, .rinkeby, .poa, .sokol, .classic, .callisto, .custom:
return nil
}

@ -32,13 +32,14 @@ public struct Constants {
public static let donationAddress = "0xFE6d4bC2De2D0b0E6FE47f08A28Ed52F9d052A02"
public static let dappsBrowserURL = "https://www.stateofthedapps.com"
// FIFA hardcoded FIFA token address. Look for "//FIFA" for relevant changes
public static let ticketContractAddress = "0xA66A3F08068174e8F005112A8b2c7A507a822335"
public static let ticketContractAddressRopsten = "0xD8e5F58DE3933E1E35f9c65eb72cb188674624F3"
public static let nullTicket = "0x0000000000000000000000000000000000000000000000000000000000000000"
public static let nullTicketBigUInt = BigUInt(0)
public static let burnAddressString = "0x000000000000000000000000000000000000dEaD"
public static let event = "FIFA WC2018"
// FIFA hardcoded FIFA token address
public static let ticketContractAddress = "0xA66A3F08068174e8F005112A8b2c7A507a822335"
public static let ticketContractAddressRopsten = "0xD8e5F58DE3933E1E35f9c65eb72cb188674624F3"
public static let fifaWorldCup2018TokenNamePrefix = "FIFA WC2018"
//etherscan APIs
public static let mainnetEtherscanAPI = "https://api.etherscan.io/api?module=account&action=txlist&address="

@ -19,7 +19,7 @@ struct Token {
return Token(
id: Constants.nullTicketBigUInt,
index: 0,
name: "FIFA WC",
name: R.string.localizable.tokensTitlecase(),
values: [
"locality": "N/A",
"venue": "N/A",

@ -513,10 +513,8 @@ class TokensDataStore {
public func updateERC875TokensToLocalizedName() {
assetDefinitionStore.forEachContractWithXML { contract in
if let token = config.createDefaultTicketToken(forContract: contract) {
let contract = token.contract.eip55String
let localizedName = token.name
if let storedTicketToken = enabledObject.first(where: { $0.contract == contract }) {
if let localizedName = config.getContractLocalizedName(forContract: contract) {
if let storedTicketToken = enabledObject.first(where: { $0.contract.sameContract(as: contract) }) {
//TODO multiple realm writes in a loop. Should we group them together?
updateTicketTokenName(token: storedTicketToken, to: localizedName)
}

@ -6,6 +6,6 @@ import UIKit
struct EditTokenViewModel {
var title: String {
return R.string.localizable.tokens()
return R.string.localizable.tokenTitlecase()
}
}

@ -6,11 +6,7 @@ import UIKit
//Must be a class, and not a struct, otherwise changing `filter` will silently create a copy of TokensViewModel when user taps to change the filter in the UI and break filtering
class TokensViewModel {
var config: Config
var tokens: [TokenObject] = [] {
willSet {
tokens = reorderTokensSoFIFAAtIndex1(tokens: newValue)
}
}
var tokens: [TokenObject] = []
var tickers: [String: CoinTicker]?
var etherTokenContract: String
var filter: WalletFilter = .all
@ -91,10 +87,6 @@ class TokensViewModel {
if etherTokenContract == token.contract {
return false
}
if let ticketContractAddress = config.ticketContractAddress,
token.contract.lowercased() == ticketContractAddress.lowercased() {
return false
}
return true
}
@ -113,22 +105,7 @@ class TokensViewModel {
) {
self.config = config
self.etherTokenContract = TokensDataStore.etherToken(for: config).contract
self.tokens = reorderTokensSoFIFAAtIndex1(tokens: tokens)
self.tokens = tokens
self.tickers = tickers
}
//FIFA make the FIFA token be index 1. Can remove the function and replace with the argument when we no longer need this
private func reorderTokensSoFIFAAtIndex1(tokens: [TokenObject]) -> [TokenObject] {
guard let contract = config.ticketContractAddress else { return tokens }
let index = tokens.index { $0.address.eip55String.sameContract(as: contract) }
if let index = index, tokens.count >= 2 {
var reorderedTokens = tokens
let target = reorderedTokens[index]
reorderedTokens.remove(at: index)
reorderedTokens.insert(target, at: 1)
return reorderedTokens
} else {
return tokens
}
}
}

@ -44,19 +44,20 @@ class TransferNFTCoordinator: Coordinator {
func start() {
guard let address = validateAddress() else { return }
showProgressViewController()
showProgressViewController(address: address)
transfer(address: address)
}
private func showProgressViewController() {
private func showProgressViewController(address: Address) {
statusViewController = StatusViewController()
if let vc = statusViewController {
vc.delegate = self
let tokenTypeName = XMLHandler(contract: address.eip55String).getTokenTypeName(.singular)
vc.configure(viewModel: .init(
state: .processing,
inProgressText: R.string.localizable.aWalletTicketTokenTransferInProgressTitle(),
succeededTextText: R.string.localizable.aWalletTicketTokenTransferSuccessTitle(),
failedText: R.string.localizable.aWalletTicketTokenTransferFailedTitle()
inProgressText: R.string.localizable.aWalletTicketTokenTransferInProgressTitle(tokenTypeName),
succeededTextText: R.string.localizable.aWalletTicketTokenTransferSuccessTitle(tokenTypeName),
failedText: R.string.localizable.aWalletTicketTokenTransferFailedTitle(tokenTypeName)
))
vc.modalPresentationStyle = .overCurrentContext
viewController.present(vc, animated: true)

@ -117,8 +117,9 @@ class TransferTokensCardQuantitySelectionViewController: UIViewController, Token
@objc
func nextButtonTapped() {
if quantityStepper.value == 0 {
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenTransferSelectTicketQuantityAtLeastOneTitle(),
message: R.string.localizable.aWalletTicketTokenTransferSelectTicketQuantityAtLeastOneTitle(tokenTypeName),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,

@ -103,8 +103,9 @@ class TransferTokensCardViewController: UIViewController, TokenVerifiableStatusV
func nextButtonTapped() {
let selectedTicketHolders = viewModel.ticketHolders.filter { $0.isSelected }
if selectedTicketHolders.isEmpty {
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.singular, titlecase: .notTitlecase)
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenTransferSelectTicketsAtLeastOneTitle(),
message: R.string.localizable.aWalletTicketTokenTransferSelectTicketsAtLeastOneTitle(tokenTypeName),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,

@ -9,7 +9,8 @@ struct ChooseTokenCardTransferModeViewControllerViewModel {
var ticketHolder: TokenHolder
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.plural, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle(tokenTypeName)
}
var backgroundColor: UIColor {

@ -9,7 +9,8 @@ struct SetTransferTokensCardExpiryDateViewControllerViewModel {
var ticketHolder: TokenHolder
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.plural, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle(tokenTypeName)
}
var backgroundColor: UIColor {

@ -9,7 +9,8 @@ struct TransferTokensCardQuantitySelectionViewModel {
var ticketHolder: TokenHolder
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.plural, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle(tokenTypeName)
}
var maxValue: Int {
@ -45,6 +46,7 @@ struct TransferTokensCardQuantitySelectionViewModel {
}
var subtitleText: String {
return R.string.localizable.aWalletTicketTokenTransferQuantityTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
return R.string.localizable.aWalletTicketTokenTransferQuantityTitle(tokenTypeName.localizedUppercase)
}
}

@ -9,7 +9,8 @@ struct TransferTokensCardViaWalletAddressViewControllerViewModel {
var ticketHolder: TokenHolder
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName(.plural, titlecase: .titlecase)
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle(tokenTypeName)
}
var backgroundColor: UIColor {

@ -26,7 +26,8 @@ struct TransferTokensCardViewModel {
}
var title: String {
return R.string.localizable.aWalletTicketTokenTransferSelectTicketsTitle ()
let tokenTypeName = XMLHandler(contract: token.address.eip55String).getTokenTypeName()
return R.string.localizable.aWalletTicketTokenTransferSelectTicketsTitle(tokenTypeName)
}
var buttonTitleColor: UIColor {

@ -23,7 +23,7 @@ class UniversalLinkHandlerTests: XCTestCase {
func testCreateUniversalLink() {
var indices = [UInt16]()
indices.append(1)
let contractAddress = Config().ticketContractAddress!
let contractAddress = "0x1"
let testOrder1 = Order(price: BigUInt("1000000000")!,
indices: indices,
expiry: BigUInt("0")!,

@ -14,4 +14,9 @@ class EtherTests: XCTestCase {
XCTAssertEqual(String(e * 10), "12")
XCTAssertEqual(String(e / 10), "0.12")
}
func testDescriptionShouldNotIncludeFormatting() {
let e = Ether(string: "1000")!
XCTAssertEqual(String(e), "1000")
}
}

@ -3,6 +3,7 @@
import FBSnapshotTestCase
@testable import Trust
import UIKit
import TrustKeystore
class TransferTokensCardQuantitySelectionViewControllerTests: FBSnapshotTestCase {
override func setUp() {
@ -12,7 +13,7 @@ class TransferTokensCardQuantitySelectionViewControllerTests: FBSnapshotTestCase
}
func testTransferTokensCardQuantitySelectionViewControllerCanBeCreated() {
let token = TokenObject()
let token = TokenObject(contract: "0x0000000000000000000000000000000000000001", name: "", symbol: "", decimals: 0, value: "", isCustom: true, isDisabled: false, type: .erc875)
let type = PaymentFlow.send(type: .ERC875Token(token))
let ticket = Token(id: "1", index: 1, name: "", values: ["city": "", "venue": "", "match": 9, "time": GeneralisedTime(string: "20010203160500+0300")!, "numero": 1, "category": "MATCH CLUB", "countryA": "Team A", "countryB": "Team B"])
let ticketHolder = TokenHolder(tickets: [ticket], status: .available, contractAddress: "0x1")

Loading…
Cancel
Save