Set token icons loading priority order: `.alphaWallet`, `OpenSea`, `.thirdParty` #3828

pull/3860/head
Krypto Pank 3 years ago
parent f4ef1f0917
commit 17e5994a69
  1. 32
      AlphaWallet/Tokens/Views/OpenSea/OpenSeaNonFungibleTokenViewCell.swift
  2. 62
      AlphaWallet/UI/TokenObject+UI.swift

@ -5,11 +5,30 @@ import UIKit
class OpenSeaNonFungibleTokenView: UIView {
private let background = UIView()
private let imageView = TokenImageView(scale: .bestFill)
private let imageView: TokenImageView = {
let imageView: TokenImageView = TokenImageView(scale: .bestFill)
imageView.isRoundingEnabled = false
imageView.isChainOverlayHidden = true
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
//Holder so UIMotionEffect don't reveal the background behind the image
private let imageHolder = UIView()
private let label = UILabel()
private let countLabel = UILabel()
private let label: UILabel = {
let label = UILabel()
label.setContentHuggingPriority(.required, for: .vertical)
label.setContentCompressionResistancePriority(.required, for: .vertical)
return label
}()
private let countLabel: UILabel = {
let countLabel = UILabel()
countLabel.setContentHuggingPriority(.required, for: .vertical)
countLabel.setContentCompressionResistancePriority(.required, for: .vertical)
return countLabel
}()
private var tokenAddress: AlphaWallet.Address?
override init(frame: CGRect) {
@ -17,6 +36,7 @@ class OpenSeaNonFungibleTokenView: UIView {
background.translatesAutoresizingMaskIntoConstraints = false
addSubview(background)
let textsStackView = [
label,
countLabel,
@ -29,11 +49,8 @@ class OpenSeaNonFungibleTokenView: UIView {
.spacer(height: 8),
].asStackView(axis: .vertical, spacing: 0, alignment: .fill)
stackView.translatesAutoresizingMaskIntoConstraints = false
background.addSubview(stackView)
imageView.isRoundingEnabled = false
imageView.isChainOverlayHidden = true
imageView.translatesAutoresizingMaskIntoConstraints = false
background.addSubview(stackView)
imageHolder.addSubview(imageView)
NSLayoutConstraint.activate([
@ -42,6 +59,7 @@ class OpenSeaNonFungibleTokenView: UIView {
stackView.anchorsConstraint(to: background),
imageView.anchorsConstraint(to: imageHolder)
])
translatesAutoresizingMaskIntoConstraints = false
}

@ -152,14 +152,14 @@ class TokenImageFetcher {
let queue = self.queue
let subscribable: Subscribable<TokenImage>
let key = "\(contractAddress.eip55String)-\(server.chainID)"
if let sub = Self.subscribables[key] {
if let sub = TokenImageFetcher.subscribables[key] {
subscribable = sub
if let value = sub.value, value.isFinal {
return subscribable
}
} else {
let sub = Subscribable<TokenImage>(getDefaultOrGenerateIcon())
Self.subscribables[key] = sub
TokenImageFetcher.subscribables[key] = sub
subscribable = sub
}
@ -175,7 +175,7 @@ class TokenImageFetcher {
}
}
return Self.programmaticallyGenerateIcon(for: contractAddress, type: type, server: server, symbol: name)
return TokenImageFetcher.programmaticallyGenerateIcon(for: contractAddress, type: type, server: server, symbol: name)
}
if contractAddress.sameContract(as: Constants.nativeCryptoAddressInDatabase) {
@ -198,37 +198,51 @@ class TokenImageFetcher {
}
}
Self.fetchFromOpenSea(type, balance: balance, queue: queue).done(on: .main, {
subscribable.value = (image: $0, symbol: "", isFinal: true, overlayServerIcon: server.staticOverlayIcon)
}).catch(on: queue) { _ in
Self.fetchFromAssetGitHubRepo(contractAddress: contractAddress, queue: queue).done(on: .main, {
subscribable.value = (image: .image($0), symbol: "", isFinal: false, overlayServerIcon: server.staticOverlayIcon)
if let image = generatedImage, image.isFinal {
return
}
firstly {
TokenImageFetcher
.fetchFromAssetGitHubRepo(.alphaWallet, contractAddress: contractAddress, queue: queue)
.map(on: queue, { image -> TokenImage in
return (image: .image(image), symbol: "", isFinal: true, overlayServerIcon: server.staticOverlayIcon)
})
}.recover(on: queue, { _ -> Promise<TokenImage> in
return TokenImageFetcher
.fetchFromOpenSea(type, balance: balance, queue: queue)
.map(on: queue, { url -> TokenImage in
return (image: url, symbol: "", isFinal: true, overlayServerIcon: server.staticOverlayIcon)
})
}).recover(on: queue, { _ -> Promise<TokenImage> in
return TokenImageFetcher
.fetchFromAssetGitHubRepo(.thirdParty, contractAddress: contractAddress, queue: queue)
.map(on: queue, { image -> TokenImage in
return (image: .image(image), symbol: "", isFinal: false, overlayServerIcon: server.staticOverlayIcon)
})
}).done(on: .main, { value in
subscribable.value = value
}).catch(on: .main, { _ in
subscribable.value = generatedImage
})
}
}
return subscribable
}
private static func fetchFromOpenSea(_ type: TokenType, balance: String?, queue: DispatchQueue) -> Promise<WebImageViewImage> {
Promise { seal in
queue.async {
switch type {
case .erc721, .erc1155:
if let json = balance, let data = json.data(using: .utf8), let openSeaNonFungible = nonFungible(fromJsonData: data) {
guard let url = URL(string: openSeaNonFungible.contractImageUrl) ?? URL(string: openSeaNonFungible.thumbnailUrl) else {
return seal.reject(ImageAvailabilityError.notAvailable)
return .init(error: ImageAvailabilityError.notAvailable)
}
return seal.fulfill(.url(url))
return .value(.url(url))
} else {
seal.reject(ImageAvailabilityError.notAvailable)
return .init(error: ImageAvailabilityError.notAvailable)
}
case .nativeCryptocurrency, .erc20, .erc875, .erc721ForTickets:
seal.reject(ImageAvailabilityError.notAvailable)
}
}
return .init(error: ImageAvailabilityError.notAvailable)
}
}
@ -240,22 +254,14 @@ class TokenImageFetcher {
})
}
private static func fetchFromAssetGitHubRepo(contractAddress: AlphaWallet.Address, queue: DispatchQueue) -> Promise<UIImage> {
firstly {
fetchFromAssetGitHubRepo(.alphaWallet, contractAddress: contractAddress, queue: queue)
}.recover(on: queue, { _ -> Promise<UIImage> in
fetchFromAssetGitHubRepo(.thirdParty, contractAddress: contractAddress, queue: queue)
})
}
private static func fetch(request: URLRequest, queue: DispatchQueue) -> Promise<UIImage> {
Alamofire.request(request).responseData().map(on: queue) { response -> UIImage in
return Alamofire.request(request).responseData(queue: queue).map(on: queue, { response -> UIImage in
if let img = UIImage(data: response.data) {
return img
} else {
throw ImageAvailabilityError.notAvailable
}
}.recover { error -> Promise<UIImage> in
}).recover(on: queue, { error -> Promise<UIImage> in
//This is expected. Some tokens will not have icons
if let url = request.url?.absoluteString {
verboseLog("Loading token icon URL: \(url) error")
@ -263,7 +269,7 @@ class TokenImageFetcher {
verboseLog("Loading token icon URL: nil error")
}
throw error
}
})
}
}

Loading…
Cancel
Save