Below "Hidden Tokens" add another section called "Popular Tokens" #2845
parent
d4445040ae
commit
e25872a67e
@ -0,0 +1,130 @@ |
|||||||
|
// |
||||||
|
// PopularTokensCollection.swift |
||||||
|
// AlphaWallet |
||||||
|
// |
||||||
|
// Created by Vladyslav Shepitko on 04.06.2021. |
||||||
|
// |
||||||
|
|
||||||
|
import UIKit |
||||||
|
import PromiseKit |
||||||
|
|
||||||
|
struct JSONCodingKeys: CodingKey { |
||||||
|
var stringValue: String |
||||||
|
var intValue: Int? |
||||||
|
|
||||||
|
init(stringValue: String) { |
||||||
|
self.stringValue = stringValue |
||||||
|
} |
||||||
|
|
||||||
|
init?(intValue: Int) { |
||||||
|
self.init(stringValue: "\(intValue)") |
||||||
|
self.intValue = intValue |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
struct PopularToken: Decodable { |
||||||
|
private enum AnyError: Error { |
||||||
|
case invalid |
||||||
|
} |
||||||
|
|
||||||
|
var contractAddress: AlphaWallet.Address |
||||||
|
var server: RPCServer |
||||||
|
var name: String |
||||||
|
|
||||||
|
var iconImage: Subscribable<TokenImage> { |
||||||
|
return TokenImageFetcher.instance.image(contractAddress: contractAddress, server: server, name: name) |
||||||
|
} |
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey { |
||||||
|
case address |
||||||
|
case server = "network" |
||||||
|
case name |
||||||
|
} |
||||||
|
|
||||||
|
init(from decoder: Decoder) throws { |
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self) |
||||||
|
|
||||||
|
if let address = AlphaWallet.Address(uncheckedAgainstNullAddress: try container.decode(String.self, forKey: .address)) { |
||||||
|
contractAddress = address |
||||||
|
} else { |
||||||
|
throw AnyError.invalid |
||||||
|
} |
||||||
|
name = container.decode(String.self, forKey: .name, defaultValue: "") |
||||||
|
server = RPCServer(chainID: try container.decode(Int.self, forKey: .server)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
enum WalletOrPopularToken { |
||||||
|
case walletToken(TokenObject) |
||||||
|
case popularToken(PopularToken) |
||||||
|
} |
||||||
|
|
||||||
|
protocol PopularTokensCollectionType: class { |
||||||
|
func fetchTokens() -> Promise<[PopularToken]> |
||||||
|
} |
||||||
|
|
||||||
|
class PopularTokensCollection: NSObject, PopularTokensCollectionType { |
||||||
|
private let tokensURL: URL = URL(string: "https://raw.githubusercontent.com/AlphaWallet/alpha-wallet-android/fa86b477586929f61e7fefefc6a9c70de91de1f0/app/src/main/assets/known_contract.json")! |
||||||
|
private let queue = DispatchQueue.global() |
||||||
|
private static var cache: [PopularToken]? = .none |
||||||
|
|
||||||
|
func fetchTokens() -> Promise<[PopularToken]> { |
||||||
|
if let cache = Self.cache { |
||||||
|
return .value(cache) |
||||||
|
} else { |
||||||
|
return Promise { seal in |
||||||
|
queue.async { |
||||||
|
do { |
||||||
|
let data = try Data(contentsOf: self.tokensURL, options: .alwaysMapped) |
||||||
|
let respose = try JSONDecoder().decode(PopularTokenList.self, from: data) |
||||||
|
|
||||||
|
Self.cache = respose.tokens |
||||||
|
|
||||||
|
seal.fulfill(respose.tokens) |
||||||
|
} catch { |
||||||
|
seal.reject(error) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class LocalPopularTokensCollection: NSObject, PopularTokensCollectionType { |
||||||
|
private let tokensURL: URL = URL(fileURLWithPath: Bundle.main.path(forResource: "known_contract", ofType: "json")!) |
||||||
|
private let queue = DispatchQueue.global() |
||||||
|
private static var cache: [PopularToken]? = .none |
||||||
|
|
||||||
|
func fetchTokens() -> Promise<[PopularToken]> { |
||||||
|
if let cache = Self.cache { |
||||||
|
return .value(cache) |
||||||
|
} else { |
||||||
|
return Promise { seal in |
||||||
|
queue.async { |
||||||
|
do { |
||||||
|
let data = try Data(contentsOf: self.tokensURL, options: .alwaysMapped) |
||||||
|
let respose = try JSONDecoder().decode(PopularTokenList.self, from: data) |
||||||
|
|
||||||
|
Self.cache = respose.tokens |
||||||
|
|
||||||
|
seal.fulfill(respose.tokens) |
||||||
|
} catch { |
||||||
|
seal.reject(error) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private struct PopularTokenList: Decodable { |
||||||
|
var tokens: [PopularToken] = [] |
||||||
|
|
||||||
|
init(from decoder: Decoder) throws { |
||||||
|
let container = try decoder.container(keyedBy: JSONCodingKeys.self) |
||||||
|
|
||||||
|
for key in container.allKeys { |
||||||
|
tokens.append(contentsOf: try container.decode([PopularToken].self, forKey: key)) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,111 @@ |
|||||||
|
{ |
||||||
|
"MainNet": |
||||||
|
[ |
||||||
|
{"address": "0x056fd409e1d7a124bd7017459dfea2f387b6d5cd", "name": "Gemini dollar", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x8e870d67f660d95d5be530380d0ec0bd388289e1", "name": "Paxos Standard", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x0000000000085d4780B73119b644AE5ecd22b376", "name": "TrueUSD", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "name": "USD Coin", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xa74476443119A942dE498590Fe1f2454d7D4aC0d", "name": "Golem Network Token", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x98f2ab72198f2e64527bdb28931f60c0f77ac2fc", "name": "USDO", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", "name": "Dai Stablecoin v1.0", "isPopular": true, "network": 1}, |
||||||
|
|
||||||
|
{"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "name": "USDT", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x514910771AF9Ca656af840dff83E8264EcF986CA", "name": "LINK", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52", "name": "BNB", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "name": "WETH", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xB6eD7644C69416d67B522e20bC294A9a9B405B31", "name": "0xBTC", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xc11d0D5b9e8d7741289e78a52b9D2eFBCEC14478", "name": "aDAI", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x737F98AC8cA59f2C68aD658E3C3d8C8963E40a4c", "name": "AMN", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xD46bA6D942050d489DBd938a2C909A5d5039A161", "name": "AMPL", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xcD62b1C403fa761BAadFC74C525ce2B51780b184", "name": "ANJ", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x960b236A07cf122663c4303350609A66A7B288C0", "name": "ANT", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x27054b13b1B798B345b591a4d22e6562d47eA75a", "name": "AST", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xba100000625a3754423978a60c9317c58a424e3D", "name": "BAL", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xBA11D00c5f74255f56a5E366F4F77f5A186d7f55", "name": "BAND", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF", "name": "BAT", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e", "name": "BLT", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C", "name": "BNT", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x0327112423F3A68efdF1fcF402F6c5CB9f7C33fd", "name": "BTC++", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x56d811088235F11C8920698a204A5010a788f4b3", "name": "BZRX", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643", "name": "cDAI", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xaaAEBE6Fe48E54f431b0C390CfaF0b017d09D42d", "name": "CEL", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x4F9254C83EB525f9FCf346490bbb3ed28a81C667", "name": "CELR", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x06AF07097C9Eeb7fD685c692751D5C66dB49c215", "name": "CHAI", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x39AA39c021dfbaE8faC545936693aC917d5E7563", "name": "cUSDC", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "name": "DAI", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x1B5f21ee98eed48d292e8e2d3Ed82b40a9728A22", "name": "DATA", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A", "name": "DGD", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF", "name": "DGX", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x97af10D3fc7C70F67711Bf715d8397C6Da79C1Ab", "name": "DIP", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xC03238A3cb7CA6580f3a89B32AFaC1bcFF87CaE4", "name": "DONUT", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xa689DCEA8f7ad59fb213be4bc624ba5500458dC6", "name": "EBASE", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c", "name": "ENJ", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x493C57C4763932315A328269E1ADaD09653B9081", "name": "iDAI", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x6fB3e0A217407EFFf7Ca062D46c26E5d60a14d69", "name": "IOTX", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x14094949152EDDBFcd073717200DA82fEd8dC960", "name": "iSAI", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x4CC19356f2D37338b9802aa8E8fc58B0373296E7", "name": "KEY", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xdd974D5C2e2928deA5F71b9825b8b646686BD200", "name": "KNC", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x80fB784B7eD66730e8b1DBd9820aFD29931aab03", "name": "LEND", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x514910771AF9Ca656af840dff83E8264EcF986CA", "name": "LINK", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xa3d58c4E56fedCae3a7c43A725aeE9A71F0ece4e", "name": "MET", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x1B941DEd58267a06f4Ab028b446933e578389DAF", "name": "MGN", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2", "name": "MKR", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xec67005c4E498Ec7f55E092bd1d35cbC47C91892", "name": "MLN", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x957c30aB0426e0C93CD8241E2c60392d08c6aC8e", "name": "MOD", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xa3BeD4E1c75D00fa6f4E5E6922DB7261B5E9AcD2", "name": "MTA", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xe2f2a5C287993345a840Db3B0845fbC70f5935a5", "name": "mUSD", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xB62132e35a6c13ee1EE0f84dC5d40bad8d815206", "name": "NEXO", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671", "name": "NMR", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xF970b8E36e23F7fC3FD752EeA86f8Be8D83375A6", "name": "RCN", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6", "name": "RDN", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x408e41876cCCDC0F92210600ef50372656052a38", "name": "REN", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x459086F2376525BdCebA5bDDA135e4E9d3FeF5bf", "name": "renBCH", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D", "name": "renBTC", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x1C5db575E2Ff833E46a2E9864C22F4B22E0B37C2", "name": "renZEC", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xE94327D07Fc17907b4DB788E5aDf2ed424adDff6", "name": "REP", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x221657776846890989a759BA2973e427DfF5C9bB", "name": "REPv2", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x9469D013805bFfB7D3DEBe5E7839237e535ec483", "name": "RING", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xeEAE80e1790c63E390cFB176536D734c28828192", "name": "SOCKS", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x42d6622deCe394b54999Fbd73D108123806f6a18", "name": "SPANK", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x476c5E26a75bd202a9683ffD34359C0CC15be0fF", "name": "SRM", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x0Ae055097C6d159879521C384F1D2123D1f195e6", "name": "STAKE", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC", "name": "STORJ", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x57Ab1ec28D129707052df4dF418D58a2D46d5f51", "name": "sUSD", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x261EfCdD24CeA98652B9700800a13DfBca4103fF", "name": "sXAU", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "name": "USDC", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x098fEEd90F28493e02f6e745a2767120E7B79A1B", "name": "USDS", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "name": "USDT", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xeb269732ab75A6fD61Ea60b06fE994cD32a83549", "name": "USDx", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x8f3470A7388c05eE4e7AF3d01D8C722b0FF52374", "name": "VERI", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "name": "WBTC", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xb69EfF754380AC7C68ffeE174b881A39dae2f58C", "name": "WCK", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08", "name": "XCHF", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xa45Eaf6d2Ce4d1a67381d5588B865457023c23A0", "name": "XIO", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xE41d2489571d322189246DaFA5ebDe1F4699F498", "name": "ZRX", "isPopular": true, "network": 1}, |
||||||
|
|
||||||
|
{"address": "0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0", "name": "", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xf230b790e05390fc8295f4d3f60332c93bed42e2", "name": "Tronix", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xd850942ef8811f2a866692a623011bde52a462c1", "name": "VeChain Token", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xb5a5f22694352c15b00323844ad545abb2b11028", "name": "", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07", "name": "OMGToken", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x05f4a42e251f2d52b8ed15e9fedaacfcef1fad27", "name": "Zilliqa", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xcb97e65f07da24d46bcdd078ebebd7c6e6e3d750", "name": "Bytom", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xd4fa1460f537bb9085d22c7bccb5dd450ef28e3a", "name": "Populous Platform", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x168296bb09e24a88805cb9c33356536b980d3fc5", "name": "RHOC", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x744d70fdbe2ba4cf95131626614a1763df805b9e", "name": "Status Network Token", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x4CEdA7906a5Ed2179785Cd3A40A69ee8bc99C466", "name": "AION", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0xEF68e7C694F40c8202821eDF525dE3782458639f", "name": "", "isPopular": true, "network": 1}, |
||||||
|
{"address": "0x5ca9a71b1d01849c0a95490cc00559717fcf0d1d", "name": "Aeternity", "isPopular": true, "network": 1} |
||||||
|
], |
||||||
|
"xDAI": |
||||||
|
[ |
||||||
|
{"address": "0x6a814843de5967cf94d7720ce15cba8b0da81967", "name": "BuffiDai", "isPopular": false, "network": 100}, |
||||||
|
{"address": "0x94819805310cf736198df0de856b0ff5584f0903", "name": "Burner", "isPopular": false, "network": 100}, |
||||||
|
{"address": "0xdec31651bec1fbbff392aa7de956d6ee4559498b", "name": "Burner", "isPopular": false, "network": 100}, |
||||||
|
{"address": "0xa95d505e6933cb790ed3431805871efe4e6bbafd", "name": "Burner", "isPopular": false, "network": 100}, |
||||||
|
{"address": "0xbdc3df563a3959a373916b724c683d69ba4097f7", "name": "DenDai", "isPopular": false, "network": 100}, |
||||||
|
{"address": "0x6e251ee9cadf0145babfd3b64664a9d7f941fcc3", "name": "DenDai", "isPopular": false, "network": 100}, |
||||||
|
{"address": "0x3e50bf6703fc132a94e4baff068db2055655f11b", "name": "buffiDai", "isPopular": false, "network": 100}, |
||||||
|
{"address": "0xa16b70e8fad839e62abba2d962e4ca5a28af9e76", "name": "ETHDenver 2019", "isPopular": false, "network": 100} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
// |
||||||
|
// ThreadSafeDictionary.swift |
||||||
|
// AlphaWallet |
||||||
|
// |
||||||
|
// Created by Vladyslav Shepitko on 27.05.2021. |
||||||
|
// |
||||||
|
|
||||||
|
import UIKit |
||||||
|
|
||||||
|
class ThreadSafeDictionary<Key: Hashable, Value> { |
||||||
|
fileprivate var cache = [Key: Value]() |
||||||
|
private let queue = DispatchQueue(label: "SynchronizedArrayAccess", attributes: .concurrent) |
||||||
|
|
||||||
|
subscript(server: Key) -> Value? { |
||||||
|
get { |
||||||
|
var element: Value? |
||||||
|
queue.sync { |
||||||
|
element = cache[server] |
||||||
|
} |
||||||
|
return element |
||||||
|
} |
||||||
|
set { |
||||||
|
queue.async(flags: .barrier) { |
||||||
|
self.cache[server] = newValue |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func removeAll() { |
||||||
|
queue.async(flags: .barrier) { |
||||||
|
self.cache.removeAll() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var value: [Key: Value] { |
||||||
|
return cache |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
// |
||||||
|
// FungibleTokenViewCellViewModel3.swift |
||||||
|
// AlphaWallet |
||||||
|
// |
||||||
|
// Created by Vladyslav Shepitko on 07.06.2021. |
||||||
|
// |
||||||
|
|
||||||
|
import UIKit |
||||||
|
|
||||||
|
struct PopularTokenViewCellViewModel { |
||||||
|
private let token: PopularToken |
||||||
|
private let isVisible: Bool |
||||||
|
|
||||||
|
init(token: PopularToken, isVisible: Bool = true) { |
||||||
|
self.token = token |
||||||
|
self.isVisible = isVisible |
||||||
|
} |
||||||
|
|
||||||
|
private var title: String { |
||||||
|
return token.name |
||||||
|
} |
||||||
|
|
||||||
|
var backgroundColor: UIColor { |
||||||
|
return Screen.TokenCard.Color.background |
||||||
|
} |
||||||
|
|
||||||
|
var contentsBackgroundColor: UIColor { |
||||||
|
return Screen.TokenCard.Color.background |
||||||
|
} |
||||||
|
|
||||||
|
var titleAttributedString: NSAttributedString { |
||||||
|
return NSAttributedString(string: title, attributes: [ |
||||||
|
.foregroundColor: Screen.TokenCard.Color.title, |
||||||
|
.font: Screen.TokenCard.Font.title |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
|
var alpha: CGFloat { |
||||||
|
return isVisible ? 1.0 : 0.4 |
||||||
|
} |
||||||
|
|
||||||
|
var iconImage: Subscribable<TokenImage> { |
||||||
|
token.iconImage |
||||||
|
} |
||||||
|
|
||||||
|
var blockChainTagViewModel: BlockchainTagLabelViewModel { |
||||||
|
return .init(server: token.server) |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,63 @@ |
|||||||
|
// |
||||||
|
// WalletTokenViewCellViewModel.swift |
||||||
|
// AlphaWallet |
||||||
|
// |
||||||
|
// Created by Vladyslav Shepitko on 07.06.2021. |
||||||
|
// |
||||||
|
|
||||||
|
import UIKit |
||||||
|
import BigInt |
||||||
|
struct WalletTokenViewCellViewModel { |
||||||
|
private let shortFormatter = EtherNumberFormatter.short |
||||||
|
private let token: TokenObject |
||||||
|
private let assetDefinitionStore: AssetDefinitionStore |
||||||
|
private let isVisible: Bool |
||||||
|
|
||||||
|
init(token: TokenObject, assetDefinitionStore: AssetDefinitionStore, isVisible: Bool = true) { |
||||||
|
self.token = token |
||||||
|
self.assetDefinitionStore = assetDefinitionStore |
||||||
|
self.isVisible = isVisible |
||||||
|
} |
||||||
|
|
||||||
|
private var title: String { |
||||||
|
return token.titleInPluralForm(withAssetDefinitionStore: assetDefinitionStore) |
||||||
|
} |
||||||
|
|
||||||
|
private var amount: String { |
||||||
|
return shortFormatter.string(from: token.valueBigInt, decimals: token.decimals) |
||||||
|
} |
||||||
|
|
||||||
|
var cryptoValueAttributedString: NSAttributedString { |
||||||
|
return NSAttributedString(string: isVisible ? amount : String(), attributes: [ |
||||||
|
.foregroundColor: Screen.TokenCard.Color.title, |
||||||
|
.font: Screen.TokenCard.Font.title |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
|
var backgroundColor: UIColor { |
||||||
|
return Screen.TokenCard.Color.background |
||||||
|
} |
||||||
|
|
||||||
|
var contentsBackgroundColor: UIColor { |
||||||
|
return Screen.TokenCard.Color.background |
||||||
|
} |
||||||
|
|
||||||
|
var titleAttributedString: NSAttributedString { |
||||||
|
return NSAttributedString(string: title, attributes: [ |
||||||
|
.foregroundColor: Screen.TokenCard.Color.title, |
||||||
|
.font: Screen.TokenCard.Font.title |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
|
var alpha: CGFloat { |
||||||
|
return isVisible ? 1.0 : 0.4 |
||||||
|
} |
||||||
|
|
||||||
|
var iconImage: Subscribable<TokenImage> { |
||||||
|
token.icon |
||||||
|
} |
||||||
|
|
||||||
|
var blockChainTagViewModel: BlockchainTagLabelViewModel { |
||||||
|
return .init(server: token.server) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
// |
||||||
|
// PopularTokenViewCell.swift |
||||||
|
// AlphaWallet |
||||||
|
// |
||||||
|
// Created by Vladyslav Shepitko on 07.06.2021. |
||||||
|
// |
||||||
|
|
||||||
|
import UIKit |
||||||
|
|
||||||
|
class PopularTokenViewCell: UITableViewCell { |
||||||
|
private let background = UIView() |
||||||
|
private let titleLabel = UILabel() |
||||||
|
|
||||||
|
private var viewsWithContent: [UIView] { |
||||||
|
[titleLabel] |
||||||
|
} |
||||||
|
|
||||||
|
private var tokenIconImageView: TokenImageView = { |
||||||
|
let imageView = TokenImageView() |
||||||
|
imageView.translatesAutoresizingMaskIntoConstraints = false |
||||||
|
return imageView |
||||||
|
}() |
||||||
|
|
||||||
|
private var blockChainTagLabel = BlockchainTagLabel() |
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier) |
||||||
|
|
||||||
|
contentView.addSubview(background) |
||||||
|
background.translatesAutoresizingMaskIntoConstraints = false |
||||||
|
|
||||||
|
let col0 = tokenIconImageView |
||||||
|
let col1 = [ |
||||||
|
[titleLabel, UIView.spacerWidth(flexible: true)].asStackView(spacing: 5) |
||||||
|
].asStackView(axis: .vertical, spacing: 2) |
||||||
|
let stackView = [col0, col1].asStackView(spacing: 12, alignment: .center) |
||||||
|
stackView.translatesAutoresizingMaskIntoConstraints = false |
||||||
|
background.addSubview(stackView) |
||||||
|
|
||||||
|
NSLayoutConstraint.activate([ |
||||||
|
tokenIconImageView.heightAnchor.constraint(equalToConstant: 40), |
||||||
|
tokenIconImageView.widthAnchor.constraint(equalToConstant: 40), |
||||||
|
stackView.anchorsConstraint(to: background, edgeInsets: .init(top: 16, left: 20, bottom: 16, right: 16)), |
||||||
|
background.anchorsConstraint(to: contentView) |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) { |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func configure(viewModel: PopularTokenViewCellViewModel) { |
||||||
|
selectionStyle = .none |
||||||
|
|
||||||
|
backgroundColor = viewModel.backgroundColor |
||||||
|
background.backgroundColor = viewModel.contentsBackgroundColor |
||||||
|
contentView.backgroundColor = GroupedTable.Color.background |
||||||
|
|
||||||
|
titleLabel.attributedText = viewModel.titleAttributedString |
||||||
|
titleLabel.baselineAdjustment = .alignCenters |
||||||
|
|
||||||
|
viewsWithContent.forEach { |
||||||
|
$0.alpha = viewModel.alpha |
||||||
|
} |
||||||
|
tokenIconImageView.subscribable = viewModel.iconImage |
||||||
|
|
||||||
|
blockChainTagLabel.configure(viewModel: viewModel.blockChainTagViewModel) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,73 @@ |
|||||||
|
// |
||||||
|
// WalletTokenViewCell.swift |
||||||
|
// AlphaWallet |
||||||
|
// |
||||||
|
// Created by Vladyslav Shepitko on 07.06.2021. |
||||||
|
// |
||||||
|
|
||||||
|
import UIKit |
||||||
|
|
||||||
|
class WalletTokenViewCell: UITableViewCell { |
||||||
|
private let background = UIView() |
||||||
|
private let titleLabel = UILabel() |
||||||
|
private let cryptoValueLabel = UILabel() |
||||||
|
private var viewsWithContent: [UIView] { |
||||||
|
[titleLabel, cryptoValueLabel] |
||||||
|
} |
||||||
|
|
||||||
|
private var tokenIconImageView: TokenImageView = { |
||||||
|
let imageView = TokenImageView() |
||||||
|
imageView.translatesAutoresizingMaskIntoConstraints = false |
||||||
|
return imageView |
||||||
|
}() |
||||||
|
|
||||||
|
private var blockChainTagLabel = BlockchainTagLabel() |
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier) |
||||||
|
|
||||||
|
contentView.addSubview(background) |
||||||
|
background.translatesAutoresizingMaskIntoConstraints = false |
||||||
|
cryptoValueLabel.setContentCompressionResistancePriority(.required, for: .horizontal) |
||||||
|
cryptoValueLabel.setContentHuggingPriority(.required, for: .horizontal) |
||||||
|
|
||||||
|
let col0 = tokenIconImageView |
||||||
|
let col1 = [ |
||||||
|
[cryptoValueLabel, titleLabel, UIView.spacerWidth(flexible: true)].asStackView(spacing: 5) |
||||||
|
].asStackView(axis: .vertical, spacing: 2) |
||||||
|
let stackView = [col0, col1].asStackView(spacing: 12, alignment: .center) |
||||||
|
stackView.translatesAutoresizingMaskIntoConstraints = false |
||||||
|
background.addSubview(stackView) |
||||||
|
|
||||||
|
NSLayoutConstraint.activate([ |
||||||
|
tokenIconImageView.heightAnchor.constraint(equalToConstant: 40), |
||||||
|
tokenIconImageView.widthAnchor.constraint(equalToConstant: 40), |
||||||
|
stackView.anchorsConstraint(to: background, edgeInsets: .init(top: 16, left: 20, bottom: 16, right: 16)), |
||||||
|
background.anchorsConstraint(to: contentView) |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) { |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func configure(viewModel: WalletTokenViewCellViewModel) { |
||||||
|
selectionStyle = .none |
||||||
|
|
||||||
|
backgroundColor = viewModel.backgroundColor |
||||||
|
background.backgroundColor = viewModel.contentsBackgroundColor |
||||||
|
contentView.backgroundColor = GroupedTable.Color.background |
||||||
|
|
||||||
|
titleLabel.attributedText = viewModel.titleAttributedString |
||||||
|
titleLabel.baselineAdjustment = .alignCenters |
||||||
|
|
||||||
|
cryptoValueLabel.attributedText = viewModel.cryptoValueAttributedString |
||||||
|
|
||||||
|
viewsWithContent.forEach { |
||||||
|
$0.alpha = viewModel.alpha |
||||||
|
} |
||||||
|
tokenIconImageView.subscribable = viewModel.iconImage |
||||||
|
|
||||||
|
blockChainTagLabel.configure(viewModel: viewModel.blockChainTagViewModel) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue