Extract magic strings for accessing properties like "tokenId"

pull/3410/head
Hwee-Boon Yar 3 years ago
parent 531dc81d4c
commit 742afd52cb
  1. 14
      AlphaWallet/Activities/ViewModels/ActivitiesViewModel.swift
  2. 16
      AlphaWallet/Activities/ViewModels/DefaultActivityCellViewModel.swift
  3. 6
      AlphaWallet/Activities/ViewModels/DefaultActivityViewModel.swift
  4. 34
      AlphaWallet/Market/ViewModels/ImportMagicTokenCardRowViewModel.swift
  5. 22
      AlphaWallet/Market/ViewModels/ImportMagicTokenViewControllerViewModel.swift
  6. 185
      AlphaWallet/TokenScriptClient/Models/AssetAttributeSyntaxValue.swift
  7. 55
      AlphaWallet/TokenScriptClient/Models/AssetInternalValue.swift
  8. 2
      AlphaWallet/TokenScriptClient/Models/TokenScript.swift
  9. 52
      AlphaWallet/Tokens/Helpers/TokenAdaptor.swift
  10. 4
      AlphaWallet/Tokens/Types/TokenHolder.swift
  11. 2
      AlphaWallet/Tokens/ViewControllers/Collectibles/Coordinators/TokensCardCollectionCoordinator.swift
  12. 4
      AlphaWallet/Tokens/ViewControllers/Collectibles/ViewControllers/Erc1155TokenInstanceViewController.swift
  13. 8
      AlphaWallet/Tokens/ViewControllers/Collectibles/ViewModels/Erc1155TokenInstanceViewModel.swift
  14. 4
      AlphaWallet/Tokens/ViewControllers/Collectibles/ViewModels/TokensCardCollectionInfoPageViewModel.swift
  15. 82
      AlphaWallet/Tokens/ViewControllers/Collectibles/Views/TokenAssetTableViewCell.swift
  16. 6
      AlphaWallet/Tokens/ViewControllers/TokensCardViewController.swift
  17. 7
      AlphaWallet/Tokens/ViewModels/OpenSea/OpenSeaNonFungibleTokenViewCellViewModel.swift
  18. 19
      AlphaWallet/Tokens/ViewModels/OpenSeaNonFungibleTokenCardRowViewModel.swift
  19. 10
      AlphaWallet/Tokens/ViewModels/TokenListFormatRowViewModel.swift
  20. 10
      AlphaWallet/Transactions/ViewModels/ActivityViewModel.swift
  21. 2
      AlphaWallet/Transfer/Collectibles/ViewControllers/TransferTokenBatchCardsViaWalletAddressViewController.swift
  22. 2
      AlphaWallet/Transfer/Coordinators/TransferNFTCoordinator.swift
  23. 54
      AlphaWallet/UI/ViewModels/TokenCardRowViewModel.swift

@ -297,31 +297,31 @@ extension ActivitiesViewModel.functional {
guard let (token, activityName) = extractTokenAndActivityName(fromTransactionRow: transactionRow, cache: cache, wallet: wallet) else { return nil }
var cardAttributes = [AttributeId: AssetInternalValue]()
cardAttributes["symbol"] = .string(transactionRow.server.symbol)
cardAttributes.setSymbol(string: transactionRow.server.symbol)
if let operation = transactionRow.operation, operation.symbol != nil, let value = BigUInt(operation.value) {
cardAttributes["amount"] = .uint(value)
cardAttributes.setAmount(uint: value)
} else {
if let value = BigUInt(transactionRow.value) {
cardAttributes["amount"] = .uint(value)
cardAttributes.setAmount(uint: value)
}
}
if let value = AlphaWallet.Address(string: transactionRow.from) {
cardAttributes["from"] = .address(value)
cardAttributes.setFrom(address: value)
}
if let toString = transactionRow.operation?.to, let to = AlphaWallet.Address(string: toString) {
cardAttributes["to"] = .address(to)
cardAttributes.setTo(address: to)
} else {
if let value = AlphaWallet.Address(string: transactionRow.to) {
cardAttributes["to"] = .address(value)
cardAttributes.setTo(address: value)
}
}
var timestamp: GeneralisedTime = .init()
timestamp.date = transactionRow.date
cardAttributes["timestamp"] = .generalisedTime(timestamp)
cardAttributes.setTimestamp(generalisedTime: timestamp)
let state: Activity.State
switch transactionRow.state {
case .pending:

@ -77,25 +77,25 @@ struct DefaultActivityCellViewModel {
var subTitle: String {
switch activity.nativeViewType {
case .erc20Sent, .erc721Sent, .nativeCryptoSent:
if let address = cardAttributes["to"]?.addressValue?.truncateMiddle {
if let address = cardAttributes.toAddressValue?.truncateMiddle {
return R.string.localizable.activityTo(address)
} else {
return ""
}
case .erc20Received, .erc721Received, .nativeCryptoReceived:
if let address = cardAttributes["from"]?.addressValue?.truncateMiddle {
if let address = cardAttributes.fromAddressValue?.truncateMiddle {
return R.string.localizable.activityFrom(address)
} else {
return ""
}
case .erc20OwnerApproved, .erc721OwnerApproved:
if let address = cardAttributes["spender"]?.addressValue?.truncateMiddle {
if let address = cardAttributes.spenderAddressValue?.truncateMiddle {
return R.string.localizable.activityTo(address)
} else {
return ""
}
case .erc20ApprovalObtained, .erc721ApprovalObtained:
if let address = cardAttributes["owner"]?.addressValue?.truncateMiddle {
if let address = cardAttributes.ownerAddressValue?.truncateMiddle {
return R.string.localizable.activityFrom(address)
} else {
return ""
@ -131,13 +131,13 @@ struct DefaultActivityCellViewModel {
let string: String
switch activity.nativeViewType {
case .erc20Sent, .erc20Received, .nativeCryptoSent, .nativeCryptoReceived:
if let value = cardAttributes["amount"]?.uintValue {
if let value = cardAttributes.amountUIntValue {
string = stringFromFungibleAmount(sign: sign, amount: value)
} else {
string = ""
}
case .erc20OwnerApproved, .erc20ApprovalObtained:
if let value = cardAttributes["amount"]?.uintValue {
if let value = cardAttributes.amountUIntValue {
if doesApprovedAmountLookReallyBig(value, decimals: activity.tokenObject.decimals) {
string = R.string.localizable.activityApproveAmountAll(activity.tokenObject.symbol)
} else {
@ -147,7 +147,7 @@ struct DefaultActivityCellViewModel {
string = ""
}
case .erc721Sent, .erc721Received, .erc721OwnerApproved, .erc721ApprovalObtained:
if let value = cardAttributes["tokenId"]?.uintValue {
if let value = cardAttributes.tokenIdUIntValue {
string = "\(value)"
} else {
string = ""
@ -175,7 +175,7 @@ struct DefaultActivityCellViewModel {
}
private static let formatter: DateFormatter = Date.formatter(with: "dd MMM yyyy h:mm:ss a")
var timestamp: String {
if let date = cardAttributes["timestamp"]?.generalisedTimeValue?.date {
if let date = cardAttributes.timestampGeneralisedTimeValue?.date {
let value = Self.formatter.string(from: date)
return "\(value)"
} else {

@ -38,13 +38,13 @@ struct DefaultActivityViewModel {
let string: String
switch activity.nativeViewType {
case .erc20Sent, .erc20Received, .nativeCryptoSent, .nativeCryptoReceived:
if let value = cardAttributes["amount"]?.uintValue {
if let value = cardAttributes.amountUIntValue {
string = stringFromFungibleAmount(sign: sign, amount: value)
} else {
string = ""
}
case .erc20OwnerApproved, .erc20ApprovalObtained:
if let value = cardAttributes["amount"]?.uintValue {
if let value = cardAttributes.amountUIntValue {
if doesApprovedAmountLookReallyBig(value, decimals: activity.tokenObject.decimals) {
string = R.string.localizable.activityApproveAmountAll(activity.tokenObject.symbol)
} else {
@ -54,7 +54,7 @@ struct DefaultActivityViewModel {
string = ""
}
case .erc721Sent, .erc721Received, .erc721OwnerApproved, .erc721ApprovalObtained:
if let value = cardAttributes["tokenId"]?.uintValue {
if let value = cardAttributes.tokenIdUIntValue {
string = "\(value)"
} else {
string = ""

@ -60,7 +60,7 @@ struct ImportMagicTokenCardRowViewModel: TokenCardRowViewModelProtocol {
}
func subscribeBuilding(withBlock block: @escaping (String) -> Void) {
if case .some(.subscribable(let subscribable)) = importMagicTokenViewControllerViewModel.tokenHolder?.values["building"]?.value {
if let subscribable = importMagicTokenViewControllerViewModel.tokenHolder?.values.buildingSubscribableValue {
subscribable.subscribe { value in
value?.stringValue.flatMap { block($0) }
}
@ -73,51 +73,51 @@ struct ImportMagicTokenCardRowViewModel: TokenCardRowViewModelProtocol {
let string = values.joined(separator: ", ")
block(string)
}
if case .some(.subscribable(let subscribable)) = importMagicTokenViewControllerViewModel.tokenHolder?.values["street"]?.value {
if let subscribable = importMagicTokenViewControllerViewModel.tokenHolder?.values.streetSubscribableValue {
subscribable.subscribe { value in
guard let tokenHolder = self.importMagicTokenViewControllerViewModel.tokenHolder else { return }
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: value,
locality: tokenHolder.values["locality"]?.subscribableStringValue,
state: tokenHolder.values["state"]?.subscribableStringValue,
country: tokenHolder.values["country"]?.stringValue
locality: tokenHolder.values.localitySubscribableStringValue,
state: tokenHolder.values.stateSubscribableStringValue,
country: tokenHolder.values.countryStringValue
)
}
}
}
if case .some(.subscribable(let subscribable)) = importMagicTokenViewControllerViewModel.tokenHolder?.values["state"]?.value {
if let subscribable = importMagicTokenViewControllerViewModel.tokenHolder?.values.stateSubscribableValue {
subscribable.subscribe { value in
guard let tokenHolder = self.importMagicTokenViewControllerViewModel.tokenHolder else { return }
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: tokenHolder.values["street"]?.subscribableStringValue,
locality: tokenHolder.values["locality"]?.subscribableStringValue,
street: tokenHolder.values.streetSubscribableStringValue,
locality: tokenHolder.values.localitySubscribableStringValue,
state: value,
country: tokenHolder.values["country"]?.stringValue
country: tokenHolder.values.countryStringValue
)
}
}
}
if case .some(.subscribable(let subscribable)) = importMagicTokenViewControllerViewModel.tokenHolder?.values["locality"]?.value {
if let subscribable = importMagicTokenViewControllerViewModel.tokenHolder?.values.localitySubscribableValue {
subscribable.subscribe { value in
guard let tokenHolder = self.importMagicTokenViewControllerViewModel.tokenHolder else { return }
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: tokenHolder.values["street"]?.subscribableStringValue,
street: tokenHolder.values.streetSubscribableStringValue,
locality: value,
state: tokenHolder.values["state"]?.subscribableStringValue,
country: tokenHolder.values["country"]?.stringValue
state: tokenHolder.values.stateSubscribableStringValue,
country: tokenHolder.values.countryStringValue
)
}
}
}
if let country = importMagicTokenViewControllerViewModel.tokenHolder?.values["country"]?.stringValue {
if let country = importMagicTokenViewControllerViewModel.tokenHolder?.values.countryStringValue {
guard let tokenHolder = self.importMagicTokenViewControllerViewModel.tokenHolder else { return }
updateStreetLocalityStateCountry(
street: tokenHolder.values["street"]?.subscribableStringValue,
locality: tokenHolder.values["locality"]?.subscribableStringValue,
state: tokenHolder.values["state"]?.subscribableStringValue,
street: tokenHolder.values.streetSubscribableStringValue,
locality: tokenHolder.values.localitySubscribableStringValue,
state: tokenHolder.values.stateSubscribableStringValue,
country: country
)
}

@ -87,7 +87,7 @@ struct ImportMagicTokenViewControllerViewModel {
if case .validating = state {
return ""
} else {
return tokenHolder.values["locality"]?.stringValue ?? emptyCity
return tokenHolder.values.localityStringValue ?? emptyCity
}
}
@ -97,7 +97,7 @@ struct ImportMagicTokenViewControllerViewModel {
return ""
} else {
if tokenHolder.hasAssetDefinition {
return tokenHolder.values["category"]?.stringValue ?? "N/A"
return tokenHolder.values.categoryStringValue ?? "N/A"
} else {
//For ERC75 tokens, display the contract's name as the "title". https://github.com/alpha-wallet/alpha-wallet-ios/issues/664
return tokenHolder.name
@ -115,7 +115,7 @@ struct ImportMagicTokenViewControllerViewModel {
if case .validating = state {
return ""
} else {
let value = tokenHolder.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let value = tokenHolder.values.timeGeneralisedTimeValue ?? GeneralisedTime()
return value.format("hh:mm")
}
}
@ -128,8 +128,8 @@ struct ImportMagicTokenViewControllerViewModel {
if isMeetupContract && tokenHolder.values["expired"] != nil {
return ""
} else {
let countryA = tokenHolder.values["countryA"]?.stringValue ?? ""
let countryB = tokenHolder.values["countryB"]?.stringValue ?? ""
let countryA = tokenHolder.values.countryAStringValue ?? ""
let countryB = tokenHolder.values.countryBStringValue ?? ""
//While both will return emptyTeams, we want to be explicit about using `emptyTeams`
if countryA.isEmpty && countryB.isEmpty {
return emptyTeams
@ -143,13 +143,13 @@ struct ImportMagicTokenViewControllerViewModel {
var match: String {
guard let tokenHolder = tokenHolder else { return "" }
if tokenHolder.values["section"] != nil {
if let section = tokenHolder.values["section"]?.stringValue {
if let section = tokenHolder.values.sectionStringValue {
return "S\(section)"
} else {
return "S0"
}
} else {
let value = tokenHolder.values["match"]?.intValue ?? 0
let value = tokenHolder.values.matchIntValue ?? 0
return "M\(value)"
}
}
@ -159,7 +159,7 @@ struct ImportMagicTokenViewControllerViewModel {
if case .validating = state {
return ""
} else {
return tokenHolder.values["venue"]?.stringValue ?? ""
return tokenHolder.values.venueStringValue ?? ""
}
}
@ -168,14 +168,14 @@ struct ImportMagicTokenViewControllerViewModel {
if case .validating = state {
return ""
} else {
let value = tokenHolder.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let value = tokenHolder.values.timeGeneralisedTimeValue ?? GeneralisedTime()
return value.formatAsShortDateString()
}
}
var numero: String {
guard let tokenHolder = tokenHolder else { return "" }
if let num = tokenHolder.values["numero"]?.intValue {
if let num = tokenHolder.values.numeroIntValue {
return String(num)
} else {
return "N/A"
@ -338,7 +338,7 @@ struct ImportMagicTokenViewControllerViewModel {
if let tokenHolder = tokenHolder, tokenHolder.isSpawnableMeetupContract {
//Not the best check, but we assume that even if the data is just partially available, we can show something
//TODO get rid of this. Do we even use "building" as spawnable check anymore? Testing `is String` is wrong anyway. But probably harmless for now
if case .some(.subscribable(let subscribable)) = tokenHolder.values["building"]?.value, subscribable.value?.stringValue != nil {
if tokenHolder.values.buildingSubscribableValue?.value?.stringValue != nil {
return false
} else {
return true

@ -89,3 +89,188 @@ extension Array where Element == AssetAttributeSyntaxValue {
}
}
}
extension Dictionary where Key == AttributeId, Value == AssetAttributeSyntaxValue {
var tokenIdStringValue: String? {
self["tokenId"]?.stringValue
}
//"setter" functions are intentionally grouped with their complementary "getter" functions
mutating func setTokenId(string: String) {
self["tokenId"] = .init(directoryString: string)
}
var tokenIdUIntValue: BigUInt? {
self["tokenId"]?.uintValue
}
var nameStringValue: String? {
self["name"]?.stringValue
}
mutating func setName(string: String) {
self["name"] = .init(directoryString: string)
}
var descriptionStringValue: String? {
self["description"]?.stringValue
}
mutating func setDescription(string: String) {
self["description"] = .init(directoryString: string)
}
var imageUrlUrlValue: URL? {
self["imageUrl"]?.stringValue.flatMap { URL(string: $0) }
}
mutating func setImageUrl(string: String) {
self["imageUrl"] = .init(directoryString: string)
}
var thumbnailUrlUrlValue: URL? {
self["thumbnailUrl"]?.stringValue.flatMap { URL(string: $0) }
}
mutating func setThumbnailUrl(string: String) {
self["thumbnailUrl"] = .init(directoryString: string)
}
var externalLinkUrlValue: URL? {
self["externalLink"]?.stringValue.flatMap { URL(string: $0) }
}
mutating func setExternalLink(string: String) {
self["externalLink"] = .init(directoryString: string)
}
var localityStringValue: String? {
self["locality"]?.stringValue
}
var venueStringValue: String? {
self["venue"]?.stringValue
}
var countryAStringValue: String? {
self["countryA"]?.stringValue
}
var countryBStringValue: String? {
self["countryB"]?.stringValue
}
var countryStringValue: String? {
self["country"]?.stringValue
}
var categoryStringValue: String? {
self["category"]?.stringValue
}
var sectionStringValue: String? {
self["section"]?.stringValue
}
var matchIntValue: BigInt? {
self["match"]?.intValue
}
var numeroIntValue: BigInt? {
self["numero"]?.intValue
}
var backgroundColorStringValue: String? {
get {
self["backgroundColor"]?.stringValue
}
set {
self["backgroundColor"] = newValue.flatMap { .init(directoryString: $0) }
}
}
var contractImageUrlStringValue: String? {
self["contractImageUrl"]?.stringValue
}
mutating func setContractImageUrl(string: String) {
self["contractImageUrl"] = .init(directoryString: string)
}
var collectionDescriptionStringValue: String? {
get {
self["collectionDescription"]?.stringValue
}
set {
self["collectionDescription"] = newValue.flatMap { .init(directoryString: $0) }
}
}
var valueIntValue: BigInt? {
self["value"]?.intValue
}
mutating func setValue(int: BigInt) {
self["value"] = .init(int: int)
}
var timeGeneralisedTimeValue: GeneralisedTime? {
self["time"]?.generalisedTimeValue
}
var collectionCreatedDateGeneralisedTimeValue: GeneralisedTime? {
self["collectionCreatedDate"]?.generalisedTimeValue
}
mutating func setCollectionCreatedDate(generalisedTime: GeneralisedTime) {
self["collectionCreatedDate"] = .init(generalisedTime: generalisedTime)
}
var buildingSubscribableValue: Subscribable<AssetInternalValue>? {
self["building"]?.subscribableValue
}
var streetSubscribableValue: Subscribable<AssetInternalValue>? {
self["street"]?.subscribableValue
}
var stateSubscribableValue: Subscribable<AssetInternalValue>? {
self["state"]?.subscribableValue
}
var localitySubscribableValue: Subscribable<AssetInternalValue>? {
self["locality"]?.subscribableValue
}
var localitySubscribableStringValue: String? {
self["locality"]?.subscribableStringValue
}
var stateSubscribableStringValue: String? {
self["state"]?.subscribableStringValue
}
var streetSubscribableStringValue: String? {
self["street"]?.subscribableStringValue
}
var traitsAssetInternalValueValue: AssetInternalValue? {
self["traits"]?.value
}
mutating func setTraits(value: [OpenSeaNonFungibleTrait]) {
self["traits"] = .init(openSeaTraits: value)
}
var descriptionAssetInternalValue: AssetInternalValue? {
self["description"]?.value
}
mutating func setDecimals(int: Int) {
self["decimals"] = .init(int: BigInt(int))
}
mutating func setTokenType(string: String) {
self["tokenType"] = .init(directoryString: string)
}
}

@ -180,3 +180,58 @@ extension Array where Element == Subscribable<AssetInternalValue> {
}
}
}
//We can reduce some duplicated code below by implementing a protocol with a default implementation to code share with the (very similar) extension for AssetAttributeSyntaxValue, but there's some more abstraction needed to support it. Not worth it
extension Dictionary where Key == AttributeId, Value == AssetInternalValue {
var tokenIdUIntValue: BigUInt? {
self["tokenId"]?.uintValue
}
var fromAddressValue: AlphaWallet.Address? {
self["from"]?.addressValue
}
mutating func setFrom(address: AlphaWallet.Address) {
self["from"] = .address(address)
}
var toAddressValue: AlphaWallet.Address? {
self["to"]?.addressValue
}
mutating func setTo(address: AlphaWallet.Address) {
self["to"] = .address(address)
}
var senderAddressValue: AlphaWallet.Address? {
self["sender"]?.addressValue
}
var ownerAddressValue: AlphaWallet.Address? {
self["owner"]?.addressValue
}
var spenderAddressValue: AlphaWallet.Address? {
self["spender"]?.addressValue
}
var timestampGeneralisedTimeValue: GeneralisedTime? {
self["timestamp"]?.generalisedTimeValue
}
mutating func setTimestamp(generalisedTime: GeneralisedTime) {
self["timestamp"] = .generalisedTime(generalisedTime)
}
var amountUIntValue: BigUInt? {
self["amount"]?.uintValue
}
mutating func setAmount(uint: BigUInt) {
self["amount"] = .uint(uint)
}
mutating func setSymbol(string: String) {
self["symbol"] = .string(string)
}
}

@ -24,4 +24,4 @@ extension TokenScript {
.erc20: (try! String(contentsOf: R.file.erc20TokenScriptTsml()!)),
.erc721: (try! String(contentsOf: R.file.erc721TokenScriptTsml()!)),
]
}
}

@ -103,8 +103,8 @@ class TokenAdaptor {
private func sortBundlesUpcomingFirst(bundles: [TokenHolder]) -> [TokenHolder] {
return bundles.sorted {
let d0 = $0.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let d1 = $1.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let d0 = $0.values.timeGeneralisedTimeValue ?? GeneralisedTime()
let d1 = $1.values.timeGeneralisedTimeValue ?? GeneralisedTime()
return d0 < d1
}
}
@ -114,8 +114,8 @@ class TokenAdaptor {
///e.g 21, 21, 22, 25 is broken up into 2 bundles: (21,21-22) and 25.
private func breakBundlesFurtherToHaveContinuousSeatRange(tokens: [Token]) -> [[Token]] {
let tokens = tokens.sorted {
let s0 = $0.values["numero"]?.intValue ?? 0
let s1 = $1.values["numero"]?.intValue ?? 0
let s0 = $0.values.numeroIntValue ?? 0
let s1 = $1.values.numeroIntValue ?? 0
return s0 <= s1
}
return tokens.reduce([[Token]]()) { results, token in
@ -135,13 +135,13 @@ class TokenAdaptor {
private func groupTokensByFields(tokens: [Token]) -> Dictionary<String, [Token]>.Values {
var dictionary = [String: [Token]]()
for each in tokens {
let city = each.values["locality"]?.stringValue ?? "N/A"
let venue = each.values["venue"]?.stringValue ?? "N/A"
let date = each.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let countryA = each.values["countryA"]?.stringValue ?? ""
let countryB = each.values["countryB"]?.stringValue ?? ""
let match = each.values["match"]?.intValue ?? 0
let category = each.values["category"]?.stringValue ?? "N/A"
let city = each.values.localityStringValue ?? "N/A"
let venue = each.values.venueStringValue ?? "N/A"
let date = each.values.timeGeneralisedTimeValue ?? GeneralisedTime()
let countryA = each.values.countryAStringValue ?? ""
let countryB = each.values.countryBStringValue ?? ""
let match = each.values.matchIntValue ?? 0
let category = each.values.categoryStringValue ?? "N/A"
let hash = "\(city),\(venue),\(date),\(countryA),\(countryB),\(match),\(category)"
var group = dictionary[hash] ?? []
@ -195,26 +195,26 @@ class TokenAdaptor {
tokenIdOrEvent = .tokenId(tokenId: tokenId)
}
var values = xmlHandler.resolveAttributesBypassingCache(withTokenIdOrEvent: tokenIdOrEvent, server: server, account: account)
values["tokenId"] = .init(directoryString: nonFungible.tokenId)
values.setTokenId(string: nonFungible.tokenId)
if let date = nonFungible.collectionCreatedDate {
//Storing as GeneralisedTime because we only support that for date/time formats in TokenScript. We are using the same `values` infrastructure
var generalisedTime = GeneralisedTime()
generalisedTime.timeZone = TimeZone.current
generalisedTime.date = date
values["collectionCreatedDate"] = .init(generalisedTime: generalisedTime)
values.setCollectionCreatedDate(generalisedTime: generalisedTime)
}
values["collectionDescription"] = nonFungible.collectionDescription.flatMap { .init(directoryString: $0) }
values["name"] = .init(directoryString: nonFungible.name)
values["description"] = .init(directoryString: nonFungible.description)
values["imageUrl"] = .init(directoryString: nonFungible.imageUrl)
values["contractImageUrl"] = .init(directoryString: nonFungible.contractImageUrl)
values["thumbnailUrl"] = .init(directoryString: nonFungible.thumbnailUrl)
values["externalLink"] = .init(directoryString: nonFungible.externalLink)
values["backgroundColor"] = nonFungible.backgroundColor.flatMap { .init(directoryString: $0) }
values["traits"] = .init(openSeaTraits: nonFungible.traits)
values["value"] = .init(int: nonFungible.value)
values["decimals"] = .init(int: BigInt(nonFungible.decimals))
values["tokenType"] = .init(directoryString: nonFungible.tokenType.rawValue)
values.collectionDescriptionStringValue = nonFungible.collectionDescription
values.setName(string: nonFungible.name)
values.setDescription(string: nonFungible.description)
values.setImageUrl(string: nonFungible.imageUrl)
values.setContractImageUrl(string: nonFungible.contractImageUrl)
values.setThumbnailUrl(string: nonFungible.thumbnailUrl)
values.setExternalLink(string: nonFungible.externalLink)
values.backgroundColorStringValue = nonFungible.backgroundColor
values.setTraits(value: nonFungible.traits)
values.setValue(int: nonFungible.value)
values.setDecimals(int: nonFungible.decimals)
values.setTokenType(string: nonFungible.tokenType.rawValue)
let status: Token.Status
let cryptoKittyGenerationWhenDataNotAvailable = "-1"
@ -247,6 +247,6 @@ class TokenAdaptor {
extension Token {
//TODO Convenience-only. (Look for references). Should remove once we generalize things further and not hardcode the use of seatId
var seatId: Int {
return values["numero"]?.intValue.flatMap { Int($0) } ?? 0
return values.numeroIntValue.flatMap { Int($0) } ?? 0
}
}

@ -144,7 +144,7 @@ class TokenHolder {
}
var openSeaNonFungibleTraits: [OpenSeaNonFungibleTrait]? {
guard let traitsValue = values["traits"]?.value else { return nil }
guard let traitsValue = values.traitsAssetInternalValueValue else { return nil }
switch traitsValue {
case .openSeaNonFungibleTraits(let traits):
return traits
@ -194,7 +194,7 @@ class TokenHolder {
}
func openSeaNonFungibleTraits(tokenId: TokenId) -> [OpenSeaNonFungibleTrait]? {
switch token(tokenId: tokenId).flatMap({ $0.values["traits"]?.value }) {
switch token(tokenId: tokenId).flatMap({ $0.values.traitsAssetInternalValueValue }) {
case .openSeaNonFungibleTraits(let traits):
return traits
case .address, .string, .int, .uint, .generalisedTime, .bool, .subscribable, .bytes, .none:

@ -411,7 +411,7 @@ extension TokensCardCollectionCoordinator: TransferTokenBatchCardsViaWalletAddre
data: nil,
tokenIdsAndValues: [.init(tokenId: selection.tokenId, value: BigUInt(selection.value))]
)
let tokenInstanceName = tokenHolder.values["name"]?.stringValue
let tokenInstanceName = tokenHolder.values.nameStringValue
let configuration: TransactionConfirmationConfiguration = .sendNftTransaction(confirmType: .signThenSend, keystore: keystore, ethPrice: ethPrice, tokenInstanceName: tokenInstanceName)
let coordinator = TransactionConfirmationCoordinator(presentingViewController: navigationController, session: session, transaction: transaction, configuration: configuration, analyticsCoordinator: analyticsCoordinator)
addCoordinator(coordinator)

@ -146,10 +146,10 @@ class Erc1155TokenInstanceViewController: UIViewController, TokenVerifiableStatu
}
}
if let url = tokenHolder.values["imageUrl"]?.stringValue.flatMap({ URL(string: $0) }) {
if let url = tokenHolder.values.imageUrlUrlValue {
bigImageView.url = url
bigImageHolderHeightConstraint.constant = 300
} else if let url = tokenHolder.values["thumbnailUrl"]?.stringValue.flatMap({ URL(string: $0) }) {
} else if let url = tokenHolder.values.thumbnailUrlUrlValue {
bigImageView.url = url
bigImageHolderHeightConstraint.constant = 300
} else {

@ -55,16 +55,16 @@ struct Erc1155TokenInstanceViewModel {
var configurations: [TokenInstanceViewConfiguration] {
guard let values = tokenHolder.values(tokenId: tokenId), !values.isEmpty else { return [] }
var previewViewModels: [TokenInstanceViewConfiguration] = []
if let tokenId = values["tokenId"]?.stringValue {
if let tokenId = values.tokenIdStringValue {
previewViewModels += [
.field(viewModel: .init(title: R.string.localizable.semifungiblesTokenId(), attributedValue: TokenInstanceAttributeViewModel.defaultValueAttributedString(tokenId)))
]
}
let value: BigInt = values["value"]?.intValue ?? 0
let value: BigInt = values.valueIntValue ?? 0
previewViewModels += [
.field(viewModel: .init(title: R.string.localizable.semifungiblesValue(), attributedValue: TokenInstanceAttributeViewModel.defaultValueAttributedString(String(value))))
]
if let description = values["description"]?.value.resolvedValue?.stringValue.nilIfEmpty {
if let description = values.descriptionAssetInternalValue?.resolvedValue?.stringValue.nilIfEmpty {
previewViewModels += [
.header(viewModel: .init(title: R.string.localizable.semifungiblesDescription())),
.field(viewModel: .init(title: nil, attributedValue: TokenInstanceAttributeViewModel.defaultValueAttributedString(description, alignment: .left), isSeparatorHidden: true))
@ -77,7 +77,7 @@ struct Erc1155TokenInstanceViewModel {
}
var navigationTitle: String? {
tokenHolder.values["name"]?.stringValue
tokenHolder.values.nameStringValue
}
func toggleSelection(for indexPath: IndexPath) {

@ -35,13 +35,13 @@ struct TokensCardCollectionInfoPageViewModel {
}
var createdDateViewModel: TokenInstanceAttributeViewModel {
let string: String? = tokenHolders.first?.values["collectionCreatedDate"]?.generalisedTimeValue?.formatAsShortDateString()
let string: String? = tokenHolders.first?.values.collectionCreatedDateGeneralisedTimeValue?.formatAsShortDateString()
let attributedString: NSAttributedString? = string.flatMap { TokenInstanceAttributeViewModel.defaultValueAttributedString($0) }
return .init(title: R.string.localizable.semifungiblesCreatedDate(), attributedValue: attributedString)
}
var descriptionViewModel: TokenInstanceAttributeViewModel {
let string: String? = tokenHolders.first?.values["collectionDescription"]?.stringValue
let string: String? = tokenHolders.first?.values.collectionDescriptionStringValue
let attributedString: NSAttributedString? = string.flatMap { TokenInstanceAttributeViewModel.defaultValueAttributedString($0, alignment: .left) }
return .init(title: nil, attributedValue: attributedString, isSeparatorHidden: true)
}

@ -155,8 +155,8 @@ struct Erc875NonFungibleRowViewModel: TokenCardRowViewModelProtocol {
}
var title: String {
let tokenId = tokenHolder.values["tokenId"]?.stringValue ?? ""
if let name = tokenHolder.values["name"]?.stringValue.nilIfEmpty {
let tokenId = tokenHolder.values.tokenIdStringValue ?? ""
if let name = tokenHolder.values.nameStringValue.nilIfEmpty {
return name
} else {
return displayHelper.title(fromTokenName: tokenHolder.name, tokenId: tokenId)
@ -171,7 +171,8 @@ struct Erc875NonFungibleRowViewModel: TokenCardRowViewModelProtocol {
}
var _tokenCount: Int {
Int(tokenHolder.values["value"]?.intValue ?? 0)
Int(tokenHolder.values.valueIntValue ?? 0)
}
var tokenCount: String {
@ -179,13 +180,13 @@ struct Erc875NonFungibleRowViewModel: TokenCardRowViewModelProtocol {
}
var city: String {
let value = tokenHolder.values["locality"]?.stringValue ?? "N/A"
let value = tokenHolder.values.localityStringValue ?? "N/A"
return ", \(value)"
}
var category: String {
if tokenHolder.hasAssetDefinition {
return tokenHolder.values["category"]?.stringValue ?? "N/A"
return tokenHolder.values.categoryStringValue ?? "N/A"
} else {
//For ERC75 tokens, display the contract's name as the "title". https://github.com/alpha-wallet/alpha-wallet-ios/issues/664
return tokenHolder.name
@ -200,36 +201,36 @@ struct Erc875NonFungibleRowViewModel: TokenCardRowViewModelProtocol {
if isMeetupContract && tokenHolder.values["expired"] != nil {
return ""
} else {
let countryA = tokenHolder.values["countryA"]?.stringValue ?? ""
let countryB = tokenHolder.values["countryB"]?.stringValue ?? ""
let countryA = tokenHolder.values.countryAStringValue ?? ""
let countryB = tokenHolder.values.countryBStringValue ?? ""
return R.string.localizable.aWalletTokenMatchVs(countryA, countryB)
}
}
var match: String {
if tokenHolder.values["section"] != nil {
if let section = tokenHolder.values["section"]?.stringValue {
if let section = tokenHolder.values.sectionStringValue {
return "S\(section)"
} else {
return "S0"
}
} else {
let value = tokenHolder.values["match"]?.intValue ?? 0
let value = tokenHolder.values.matchIntValue ?? 0
return "M\(value)"
}
}
var venue: String {
return tokenHolder.values["venue"]?.stringValue ?? "N/A"
return tokenHolder.values.venueStringValue ?? "N/A"
}
var date: String {
let value = tokenHolder.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let value = tokenHolder.values.timeGeneralisedTimeValue ?? GeneralisedTime()
return value.formatAsShortDateString()
}
var numero: String {
if let num = tokenHolder.values["numero"]?.intValue {
if let num = tokenHolder.values.numeroIntValue {
return String(num)
} else {
return "N/A"
@ -237,7 +238,7 @@ struct Erc875NonFungibleRowViewModel: TokenCardRowViewModelProtocol {
}
func subscribeBuilding(withBlock block: @escaping (String) -> Void) {
if case .some(.subscribable(let subscribable)) = tokenHolder.values["building"]?.value {
if let subscribable = tokenHolder.values.buildingSubscribableValue {
subscribable.subscribe { value in
if let value = value?.stringValue {
block(value)
@ -252,56 +253,56 @@ struct Erc875NonFungibleRowViewModel: TokenCardRowViewModelProtocol {
let string = values.joined(separator: ", ")
block(string)
}
if case .some(.subscribable(let subscribable)) = tokenHolder.values["street"]?.value {
if let subscribable = tokenHolder.values.streetSubscribableValue {
subscribable.subscribe { value in
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: value,
locality: self.tokenHolder.values["locality"]?.subscribableStringValue,
state: self.tokenHolder.values["state"]?.subscribableStringValue,
country: self.tokenHolder.values["country"]?.stringValue
locality: self.tokenHolder.values.localitySubscribableStringValue,
state: self.tokenHolder.values.stateSubscribableStringValue,
country: self.tokenHolder.values.countryStringValue
)
}
}
}
if case .some(.subscribable(let subscribable)) = tokenHolder.values["state"]?.value {
if let subscribable = tokenHolder.values.stateSubscribableValue {
subscribable.subscribe { value in
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: self.tokenHolder.values["street"]?.subscribableStringValue,
locality: self.tokenHolder.values["locality"]?.subscribableStringValue,
street: self.tokenHolder.values.streetSubscribableStringValue,
locality: self.tokenHolder.values.localitySubscribableStringValue,
state: value,
country: self.tokenHolder.values["country"]?.stringValue
country: self.tokenHolder.values.countryStringValue
)
}
}
}
if case .some(.subscribable(let subscribable)) = tokenHolder.values["locality"]?.value {
if let subscribable = tokenHolder.values.localitySubscribableValue {
subscribable.subscribe { value in
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: self.tokenHolder.values["street"]?.subscribableStringValue,
street: self.tokenHolder.values.streetSubscribableStringValue,
locality: value,
state: self.tokenHolder.values["state"]?.subscribableStringValue,
country: self.tokenHolder.values["country"]?.stringValue
state: self.tokenHolder.values.stateSubscribableStringValue,
country: self.tokenHolder.values.countryStringValue
)
}
}
}
if let country = tokenHolder.values["country"]?.stringValue {
if let country = tokenHolder.values.countryStringValue {
updateStreetLocalityStateCountry(
street: self.tokenHolder.values["street"]?.subscribableStringValue,
locality: self.tokenHolder.values["locality"]?.subscribableStringValue,
state: self.tokenHolder.values["state"]?.subscribableStringValue,
street: self.tokenHolder.values.streetSubscribableStringValue,
locality: self.tokenHolder.values.localitySubscribableStringValue,
state: self.tokenHolder.values.stateSubscribableStringValue,
country: country
)
}
}
var time: String {
let value = tokenHolder.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let value = tokenHolder.values.timeGeneralisedTimeValue ?? GeneralisedTime()
return value.format("h:mm a")
}
@ -362,7 +363,7 @@ struct NonFungibleRowViewModel {
}
var attributedDescriptionText: NSAttributedString {
return .init(string: R.string.localizable.semifungiblesAssetsCount(Int(tokenHolder.values["value"]?.intValue ?? 0)), attributes: [
return .init(string: R.string.localizable.semifungiblesAssetsCount(Int(tokenHolder.values.valueIntValue ?? 0)), attributes: [
.foregroundColor: Screen.TokenCard.Color.subtitle,
.font: Screen.TokenCard.Font.subtitle
])
@ -373,7 +374,7 @@ struct NonFungibleRowViewModel {
if displayHelper.imageHasBackgroundColor {
return .clear
} else {
if let color = tokenHolder.values["backgroundColor"]?.stringValue.nilIfEmpty {
if let color = tokenHolder.values.backgroundColorStringValue.nilIfEmpty {
return UIColor(hex: color)
} else {
return UIColor(red: 247, green: 197, blue: 196)
@ -414,8 +415,8 @@ struct NonFungibleRowViewModel {
}
var title: String {
let tokenId = tokenHolder.values["tokenId"]?.stringValue ?? ""
if let name = tokenHolder.values["name"]?.stringValue.nilIfEmpty {
let tokenId = tokenHolder.values.tokenIdStringValue ?? ""
if let name = tokenHolder.values.nameStringValue.nilIfEmpty {
return name
} else {
return displayHelper.title(fromTokenName: tokenHolder.name, tokenId: tokenId)
@ -483,7 +484,7 @@ struct NonFungibleRowViewModel {
}
var tokenId: String {
return tokenHolder.values["tokenId"]?.stringValue ?? ""
return tokenHolder.values.tokenIdStringValue ?? ""
}
var subtitle1: String? {
@ -520,18 +521,15 @@ struct NonFungibleRowViewModel {
}
var thumbnailImageUrl: URL? {
guard let url = tokenHolder.values["thumbnailUrl"]?.stringValue else { return nil }
return URL(string: url)
return tokenHolder.values.thumbnailUrlUrlValue
}
var imageUrl: URL? {
guard let url = tokenHolder.values["imageUrl"]?.stringValue else { return nil }
return URL(string: url)
return tokenHolder.values.imageUrlUrlValue
}
var externalLink: URL? {
guard let url = tokenHolder.values["externalLink"]?.stringValue else { return nil }
return URL(string: url)
return tokenHolder.values.externalLinkUrlValue
}
var externalLinkButtonHidden: Bool {
@ -577,7 +575,7 @@ struct NonFungibleRowViewModel {
}
private func convertDescriptionToAttributedString(asHTML: Bool) -> NSAttributedString {
let string = tokenHolder.values["description"]?.stringValue ?? ""
let string = tokenHolder.values.descriptionStringValue ?? ""
//.unicode, not .utf8, otherwise Chinese will turn garbage
let htmlData = string.data(using: .unicode)
let options: [NSAttributedString.DocumentReadingOptionKey: NSAttributedString.DocumentType]

@ -281,11 +281,7 @@ class TokensCardViewController: UIViewController, TokenVerifiableStatusViewContr
private func canPeek(at indexPath: IndexPath) -> Bool {
guard canPeekToken else { return false }
let tokenHolder = viewModel.item(for: indexPath)
if let url = tokenHolder.values["imageUrl"]?.stringValue, !url.isEmpty {
return true
} else {
return false
}
return tokenHolder.values.imageUrlUrlValue != nil
}
@objc private func longPressedTokenInstanceIconified(sender: UILongPressGestureRecognizer) {

@ -14,11 +14,12 @@ class OpenSeaNonFungibleTokenViewCellViewModel {
self.token = token
//We use the contract's image and fallback to the first token ID's image if the former is not available
if let tokenHolder = TokenAdaptor(token: token, assetDefinitionStore: assetDefinitionStore, eventsDataStore: eventsDataStore).getTokenHolders(forWallet: account).first {
var url = tokenHolder.values["contractImageUrl"]?.stringValue ?? ""
let url = tokenHolder.values.contractImageUrlStringValue ?? ""
if url.isEmpty {
url = tokenHolder.values["imageUrl"]?.stringValue ?? ""
self.imageUrl = tokenHolder.values.imageUrlUrlValue
} else {
self.imageUrl = URL(string: url)
}
self.imageUrl = URL(string: url)
} else {
self.imageUrl = nil
}

@ -29,7 +29,7 @@ struct OpenSeaNonFungibleTokenCardRowViewModel {
if displayHelper.imageHasBackgroundColor {
return .clear
} else {
if let color = tokenHolder.values["backgroundColor"]?.stringValue.nilIfEmpty {
if let color = tokenHolder.values.backgroundColorStringValue.nilIfEmpty {
return UIColor(hex: color)
} else {
return UIColor(red: 247, green: 197, blue: 196)
@ -70,8 +70,8 @@ struct OpenSeaNonFungibleTokenCardRowViewModel {
}
var title: String {
let tokenId = tokenHolder.values["tokenId"]?.stringValue ?? ""
if let name = tokenHolder.values["name"]?.stringValue.nilIfEmpty {
let tokenId = tokenHolder.values.tokenIdStringValue ?? ""
if let name = tokenHolder.values.nameStringValue.nilIfEmpty {
return name
} else {
return displayHelper.title(fromTokenName: tokenHolder.name, tokenId: tokenId)
@ -139,7 +139,7 @@ struct OpenSeaNonFungibleTokenCardRowViewModel {
}
var tokenId: String {
return tokenHolder.values["tokenId"]?.stringValue ?? ""
return tokenHolder.values.tokenIdStringValue ?? ""
}
var subtitle1: String? {
@ -176,18 +176,15 @@ struct OpenSeaNonFungibleTokenCardRowViewModel {
}
var thumbnailImageUrl: URL? {
guard let url = tokenHolder.values["thumbnailUrl"]?.stringValue else { return nil }
return URL(string: url)
return tokenHolder.values.thumbnailUrlUrlValue
}
var imageUrl: URL? {
guard let url = tokenHolder.values["imageUrl"]?.stringValue else { return nil }
return URL(string: url)
return tokenHolder.values.imageUrlUrlValue
}
var externalLink: URL? {
guard let url = tokenHolder.values["externalLink"]?.stringValue else { return nil }
return URL(string: url)
return tokenHolder.values.externalLinkUrlValue
}
var externalLinkButtonHidden: Bool {
@ -233,7 +230,7 @@ struct OpenSeaNonFungibleTokenCardRowViewModel {
}
private func convertDescriptionToAttributedString(asHTML: Bool) -> NSAttributedString {
let string = tokenHolder.values["description"]?.stringValue ?? ""
let string = tokenHolder.values.descriptionStringValue ?? ""
//.unicode, not .utf8, otherwise Chinese will turn garbage
let htmlData = string.data(using: .unicode)
let options: [NSAttributedString.DocumentReadingOptionKey: NSAttributedString.DocumentType]

@ -66,7 +66,7 @@ struct TokenListFormatRowViewModel {
}
var title: String {
let tokenId = tokenHolder.values["tokenId"]?.stringValue ?? ""
let tokenId = tokenHolder.values.tokenIdStringValue ?? ""
return "\(tokenHolder.name) #\(tokenId)"
}
@ -94,17 +94,15 @@ struct TokenListFormatRowViewModel {
}
var description: String {
return tokenHolder.values["description"]?.stringValue ?? ""
tokenHolder.values.descriptionStringValue ?? ""
}
var thumbnailImageUrl: URL? {
guard let url = tokenHolder.values["thumbnailUrl"]?.stringValue else { return nil }
return URL(string: url)
tokenHolder.values.thumbnailUrlUrlValue
}
var externalLink: URL? {
guard let url = tokenHolder.values["externalLink"]?.stringValue else { return nil }
return URL(string: url)
tokenHolder.values.externalLinkUrlValue
}
//TODO using CryptoKitty struct here, not good

@ -68,25 +68,25 @@ struct ActivityViewModel {
var subTitle: String {
switch activity.nativeViewType {
case .erc20Sent, .erc721Sent, .nativeCryptoSent:
if let address = cardAttributes["to"]?.addressValue?.truncateMiddle {
if let address = cardAttributes.toAddressValue?.truncateMiddle {
return R.string.localizable.activityTo(address)
} else {
return ""
}
case .erc20Received, .erc721Received, .nativeCryptoReceived:
if let address = cardAttributes["from"]?.addressValue?.truncateMiddle {
if let address = cardAttributes.fromAddressValue?.truncateMiddle {
return R.string.localizable.activityFrom(address)
} else {
return ""
}
case .erc20OwnerApproved, .erc721OwnerApproved:
if let address = cardAttributes["spender"]?.addressValue?.truncateMiddle {
if let address = cardAttributes.senderAddressValue?.truncateMiddle {
return R.string.localizable.activityTo(address)
} else {
return ""
}
case .erc20ApprovalObtained, .erc721ApprovalObtained:
if let address = cardAttributes["owner"]?.addressValue?.truncateMiddle {
if let address = cardAttributes.ownerAddressValue?.truncateMiddle {
return R.string.localizable.activityFrom(address)
} else {
return ""
@ -113,7 +113,7 @@ struct ActivityViewModel {
}
var timestamp: String {
if let date = cardAttributes["timestamp"]?.generalisedTimeValue?.date {
if let date = cardAttributes.timestampGeneralisedTimeValue?.date {
let value = Date.formatter(with: "h:mm:ss | dd MMM yyyy").string(from: date)
return "\(value)"
} else {

@ -189,7 +189,7 @@ class TransferTokenBatchCardsViaWalletAddressViewController: UIViewController, T
targetAddressTextField.label.attributedText = viewModel.targetAddressAttributedString
targetAddressTextField.configureOnce()
selectTokenCardAmountView.configure(viewModel: .init(availableAmount: Int(viewModel.tokenHolders[0].values["value"]?.intValue ?? 0), selectedAmount: 0))
selectTokenCardAmountView.configure(viewModel: .init(availableAmount: Int(viewModel.tokenHolders[0].values.valueIntValue ?? 0), selectedAmount: 0))
buttonsBar.configure()
let nextButton = buttonsBar.buttons[0]

@ -42,7 +42,7 @@ class TransferNFTCoordinator: Coordinator {
tokenId: tokenHolder.tokens[0].id,
indices: tokenHolder.indices
)
let tokenInstanceName = tokenHolder.values["name"]?.stringValue
let tokenInstanceName = tokenHolder.values.nameStringValue
let configuration: TransactionConfirmationConfiguration = .sendNftTransaction(confirmType: .signThenSend, keystore: keystore, ethPrice: ethPrice, tokenInstanceName: tokenInstanceName)
let coordinator = TransactionConfirmationCoordinator(presentingViewController: navigationController, session: session, transaction: transaction, configuration: configuration, analyticsCoordinator: analyticsCoordinator)
addCoordinator(coordinator)

@ -18,13 +18,13 @@ struct TokenCardRowViewModel: TokenCardRowViewModelProtocol {
}
var city: String {
let value = tokenHolder.values["locality"]?.stringValue ?? "N/A"
let value = tokenHolder.values.localityStringValue ?? "N/A"
return ", \(value)"
}
var category: String {
if tokenHolder.hasAssetDefinition {
return tokenHolder.values["category"]?.stringValue ?? "N/A"
return tokenHolder.values.categoryStringValue ?? "N/A"
} else {
//For ERC75 tokens, display the contract's name as the "title". https://github.com/alpha-wallet/alpha-wallet-ios/issues/664
return tokenHolder.name
@ -39,36 +39,36 @@ struct TokenCardRowViewModel: TokenCardRowViewModelProtocol {
if isMeetupContract && tokenHolder.values["expired"] != nil {
return ""
} else {
let countryA = tokenHolder.values["countryA"]?.stringValue ?? ""
let countryB = tokenHolder.values["countryB"]?.stringValue ?? ""
let countryA = tokenHolder.values.countryAStringValue ?? ""
let countryB = tokenHolder.values.countryBStringValue ?? ""
return R.string.localizable.aWalletTokenMatchVs(countryA, countryB)
}
}
var match: String {
if tokenHolder.values["section"] != nil {
if let section = tokenHolder.values["section"]?.stringValue {
if let section = tokenHolder.values.sectionStringValue {
return "S\(section)"
} else {
return "S0"
}
} else {
let value = tokenHolder.values["match"]?.intValue ?? 0
let value = tokenHolder.values.matchIntValue ?? 0
return "M\(value)"
}
}
var venue: String {
return tokenHolder.values["venue"]?.stringValue ?? "N/A"
return tokenHolder.values.venueStringValue ?? "N/A"
}
var date: String {
let value = tokenHolder.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let value = tokenHolder.values.timeGeneralisedTimeValue ?? GeneralisedTime()
return value.formatAsShortDateString()
}
var numero: String {
if let num = tokenHolder.values["numero"]?.intValue {
if let num = tokenHolder.values.numeroIntValue {
return String(num)
} else {
return "N/A"
@ -76,7 +76,7 @@ struct TokenCardRowViewModel: TokenCardRowViewModelProtocol {
}
func subscribeBuilding(withBlock block: @escaping (String) -> Void) {
if case .some(.subscribable(let subscribable)) = tokenHolder.values["building"]?.value {
if let subscribable = tokenHolder.values.buildingSubscribableValue {
subscribable.subscribe { value in
if let value = value?.stringValue {
block(value)
@ -91,56 +91,56 @@ struct TokenCardRowViewModel: TokenCardRowViewModelProtocol {
let string = values.joined(separator: ", ")
block(string)
}
if case .some(.subscribable(let subscribable)) = tokenHolder.values["street"]?.value {
if let subscribable = tokenHolder.values.streetSubscribableValue {
subscribable.subscribe { value in
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: value,
locality: self.tokenHolder.values["locality"]?.subscribableStringValue,
state: self.tokenHolder.values["state"]?.subscribableStringValue,
country: self.tokenHolder.values["country"]?.stringValue
locality: tokenHolder.values.localitySubscribableStringValue,
state: tokenHolder.values.stateSubscribableStringValue,
country: tokenHolder.values.countryStringValue
)
}
}
}
if case .some(.subscribable(let subscribable)) = tokenHolder.values["state"]?.value {
if let subscribable = tokenHolder.values.stateSubscribableValue {
subscribable.subscribe { value in
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: self.tokenHolder.values["street"]?.subscribableStringValue,
locality: self.tokenHolder.values["locality"]?.subscribableStringValue,
street: tokenHolder.values.streetSubscribableStringValue,
locality: tokenHolder.values.localitySubscribableStringValue,
state: value,
country: self.tokenHolder.values["country"]?.stringValue
country: tokenHolder.values.countryStringValue
)
}
}
}
if case .some(.subscribable(let subscribable)) = tokenHolder.values["locality"]?.value {
if let subscribable = tokenHolder.values.localitySubscribableValue {
subscribable.subscribe { value in
if let value = value?.stringValue {
updateStreetLocalityStateCountry(
street: self.tokenHolder.values["street"]?.subscribableStringValue,
street: tokenHolder.values.streetSubscribableStringValue,
locality: value,
state: self.tokenHolder.values["state"]?.subscribableStringValue,
country: self.tokenHolder.values["country"]?.stringValue
state: tokenHolder.values.stateSubscribableStringValue,
country: tokenHolder.values.countryStringValue
)
}
}
}
if let country = tokenHolder.values["country"]?.stringValue {
if let country = tokenHolder.values.countryStringValue {
updateStreetLocalityStateCountry(
street: self.tokenHolder.values["street"]?.subscribableStringValue,
locality: self.tokenHolder.values["locality"]?.subscribableStringValue,
state: self.tokenHolder.values["state"]?.subscribableStringValue,
street: tokenHolder.values.streetSubscribableStringValue,
locality: tokenHolder.values.localitySubscribableStringValue,
state: tokenHolder.values.stateSubscribableStringValue,
country: country
)
}
}
var time: String {
let value = tokenHolder.values["time"]?.generalisedTimeValue ?? GeneralisedTime()
let value = tokenHolder.values.timeGeneralisedTimeValue ?? GeneralisedTime()
return value.format("h:mm a")
}

Loading…
Cancel
Save