From 915e76d4f97baf5ceef6bfc64ff14f378c966338 Mon Sep 17 00:00:00 2001 From: malik1004x Date: Wed, 1 Apr 2026 11:04:58 +0200 Subject: [PATCH] improve evm ui (#3129) * improve evm ui * fix model generation * add db schema * bugfixes * scrollable fav token modal * make combined balance the default * add crypto_full_icons to pubspec * optimize transaction duplication check * fix format issue * add chain icons to swap tiles * decrease asset tile font weight * show chain icon in swap currency selector * move chain icon for tokens * new trade history row * ui fix * fix padding on modal * remove vec --- cw_core/lib/crypto_currency.dart | 84 +++++++++--------- cw_core/lib/db/sqlite.dart | 13 ++- cw_core/lib/wallet_info.dart | 18 +++- cw_core/lib/wallet_info_legacy.dart | 4 +- lib/new-ui/pages/swap_page.dart | 61 ++++++++++--- .../assets_history/asset_details_modal.dart | 67 +++++++++------ .../coins_page/assets_history/asset_tile.dart | 80 ++++++++--------- .../assets_history/assets_section.dart | 19 +++- .../assets_history/history_section.dart | 13 +++ .../assets_history/history_tile.dart | 31 +++++++ .../assets_history/history_tile_base.dart | 50 +++++++---- .../assets_history/history_trade_tile.dart | 79 +++++++++++++++-- .../coins_page/cards/balance_card.dart | 34 +++++--- .../widgets/coins_page/cards/cards_view.dart | 18 ++-- .../widgets/receive_page/receive_top_bar.dart | 4 +- .../dashboard/favorite_token_modal.dart | 61 +++++++++++++ .../screens/dashboard/home_settings_page.dart | 86 ++++++++++++++++--- lib/utils/token_utilities.dart | 1 + .../dashboard/balance_view_model.dart | 70 ++++++++++++++- .../dashboard/dashboard_view_model.dart | 20 ++++- .../dashboard/home_settings_view_model.dart | 51 ++++++++++- pubspec_base.yaml | 1 + res/pictures/chain_badges/lightning.svg | 9 +- res/pictures/crypto_full_icons/arbitrum.svg | 1 + res/pictures/crypto_full_icons/avax.svg | 1 + res/pictures/crypto_full_icons/base_icon.svg | 1 + .../crypto_full_icons/bitcoin-cash.svg | 1 + res/pictures/crypto_full_icons/bitcoin.svg | 1 + res/pictures/crypto_full_icons/bnb.svg | 1 + res/pictures/crypto_full_icons/dai.svg | 1 + res/pictures/crypto_full_icons/decred.svg | 1 + res/pictures/crypto_full_icons/deuro.svg | 1 + res/pictures/crypto_full_icons/dogecoin.svg | 1 + res/pictures/crypto_full_icons/ethereum.svg | 1 + res/pictures/crypto_full_icons/lightning.svg | 1 + res/pictures/crypto_full_icons/litecoin.svg | 1 + res/pictures/crypto_full_icons/monero.svg | 1 + res/pictures/crypto_full_icons/nano.svg | 1 + res/pictures/crypto_full_icons/paxg.svg | 1 + res/pictures/crypto_full_icons/polygon.svg | 1 + res/pictures/crypto_full_icons/solana.svg | 1 + res/pictures/crypto_full_icons/ton.svg | 1 + res/pictures/crypto_full_icons/tron.svg | 1 + res/pictures/crypto_full_icons/usdc.svg | 1 + res/pictures/crypto_full_icons/usde.svg | 1 + res/pictures/crypto_full_icons/usdt.svg | 1 + res/pictures/crypto_full_icons/wbtc.svg | 1 + res/pictures/crypto_full_icons/xaut.svg | 1 + res/pictures/crypto_full_icons/zano.svg | 1 + res/pictures/crypto_full_icons/zcash.svg | 1 + res/values/strings_en.arb | 4 + 51 files changed, 710 insertions(+), 195 deletions(-) create mode 100644 lib/src/screens/dashboard/favorite_token_modal.dart create mode 100644 res/pictures/crypto_full_icons/arbitrum.svg create mode 100644 res/pictures/crypto_full_icons/avax.svg create mode 100644 res/pictures/crypto_full_icons/base_icon.svg create mode 100644 res/pictures/crypto_full_icons/bitcoin-cash.svg create mode 100644 res/pictures/crypto_full_icons/bitcoin.svg create mode 100644 res/pictures/crypto_full_icons/bnb.svg create mode 100644 res/pictures/crypto_full_icons/dai.svg create mode 100644 res/pictures/crypto_full_icons/decred.svg create mode 100644 res/pictures/crypto_full_icons/deuro.svg create mode 100644 res/pictures/crypto_full_icons/dogecoin.svg create mode 100644 res/pictures/crypto_full_icons/ethereum.svg create mode 100644 res/pictures/crypto_full_icons/lightning.svg create mode 100644 res/pictures/crypto_full_icons/litecoin.svg create mode 100644 res/pictures/crypto_full_icons/monero.svg create mode 100644 res/pictures/crypto_full_icons/nano.svg create mode 100644 res/pictures/crypto_full_icons/paxg.svg create mode 100644 res/pictures/crypto_full_icons/polygon.svg create mode 100644 res/pictures/crypto_full_icons/solana.svg create mode 100644 res/pictures/crypto_full_icons/ton.svg create mode 100644 res/pictures/crypto_full_icons/tron.svg create mode 100644 res/pictures/crypto_full_icons/usdc.svg create mode 100644 res/pictures/crypto_full_icons/usde.svg create mode 100644 res/pictures/crypto_full_icons/usdt.svg create mode 100644 res/pictures/crypto_full_icons/wbtc.svg create mode 100644 res/pictures/crypto_full_icons/xaut.svg create mode 100644 res/pictures/crypto_full_icons/zano.svg create mode 100644 res/pictures/crypto_full_icons/zcash.svg diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart index a88a67de6..f69748b4b 100644 --- a/cw_core/lib/crypto_currency.dart +++ b/cw_core/lib/crypto_currency.dart @@ -12,6 +12,7 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen required this.decimals, this.fullName, this.iconPath, + this.iconSvgPath, this.flatIconPath, this.tag, this.chainIconPath, @@ -23,6 +24,7 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen final String? tag; final String? fullName; final String? iconPath; + final String? iconSvgPath; final String? flatIconPath; final String? chainIconPath; @override @@ -149,20 +151,20 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen static const zcashCurrencies = [ zec, zaddr, tzec ]; // title, tag (if applicable), fullName (if unique), raw, name, iconPath - static const xmr = CryptoCurrency(title: 'XMR', fullName: 'Monero', raw: 0, name: 'xmr', iconPath: 'assets/images/crypto/monero.webp', decimals: 12,flatIconPath: "assets/new-ui/balance_card_icons/monero.svg"); + static const xmr = CryptoCurrency(title: 'XMR', fullName: 'Monero', raw: 0, name: 'xmr', iconPath: 'assets/images/crypto/monero.webp', iconSvgPath: "assets/new-ui/crypto_full_icons/monero.svg", decimals: 12,flatIconPath: "assets/new-ui/balance_card_icons/monero.svg"); static const ada = CryptoCurrency(title: 'ADA', fullName: 'Cardano', raw: 1, name: 'ada', iconPath: 'assets/images/ada_icon.png', decimals: 6); - static const bch = CryptoCurrency(title: 'BCH', fullName: 'Bitcoin Cash', raw: 2, name: 'bch', iconPath: 'assets/images/crypto/bitcoin-cash.webp', decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/bitcoin_cash.svg"); - static const bnb = CryptoCurrency(title: 'BNB', tag: 'BSC', fullName: 'BNB', raw: 3, name: 'bnb', iconPath: 'assets/images/crypto/BNB.webp', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/bnb.svg", chainIconPath: "assets/new-ui/chain_badges/bnb smart chain.svg"); - static const btc = CryptoCurrency(title: 'BTC', fullName: 'Bitcoin', raw: 4, name: 'btc', iconPath: 'assets/images/crypto/bitcoin.webp', decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/bitcoin.svg"); - static const dai = CryptoCurrency(title: 'DAI', tag: 'ETH', fullName: 'Dai', raw: 5, name: 'dai', iconPath: 'assets/images/crypto/dai.webp', decimals: 18); + static const bch = CryptoCurrency(title: 'BCH', fullName: 'Bitcoin Cash', raw: 2, name: 'bch', iconPath: 'assets/images/crypto/bitcoin-cash.webp', iconSvgPath: "assets/new-ui/crypto_full_icons/bitcoin-cash.svg",decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/bitcoin_cash.svg"); + static const bnb = CryptoCurrency(title: 'BNB', tag: 'BSC', fullName: 'BNB', raw: 3, name: 'bnb', iconPath: 'assets/images/crypto/BNB.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/bnb.svg", decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/bnb.svg", chainIconPath: "assets/new-ui/chain_badges/bnb smart chain.svg"); + static const btc = CryptoCurrency(title: 'BTC', fullName: 'Bitcoin', raw: 4, name: 'btc', iconPath: 'assets/images/crypto/bitcoin.webp', iconSvgPath: "assets/new-ui/crypto_full_icons/bitcoin.svg",decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/bitcoin.svg"); + static const dai = CryptoCurrency(title: 'DAI', tag: 'ETH', fullName: 'Dai', raw: 5, name: 'dai', iconPath: 'assets/images/crypto/dai.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/dai.svg", decimals: 18); static const dash = CryptoCurrency(title: 'DASH', fullName: 'Dash', raw: 6, name: 'dash', iconPath: 'assets/images/dash_icon.png', decimals: 8); static const eos = CryptoCurrency(title: 'EOS', fullName: 'EOS', raw: 7, name: 'eos', iconPath: 'assets/images/eos_icon.png', decimals: 4); static const eth = CryptoCurrency(title: 'ETH', fullName: 'Ethereum', raw: 8, name: 'eth', iconPath: 'assets/images/crypto/ethereum.webp', decimals: 18,flatIconPath: "assets/new-ui/balance_card_icons/ethereum.svg", chainIconPath: "assets/new-ui/chain_badges/ethereum.svg"); - static const ltc = CryptoCurrency(title: 'LTC', fullName: 'Litecoin', raw: 9, name: 'ltc', iconPath: 'assets/images/crypto/litecoin.webp', decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/litecoin.svg", chainIconPath: "assets/new-ui/chain_badges/mweb.svg"); - static const nano = CryptoCurrency(title: 'XNO', fullName: 'Nano', raw: 10, name: 'xno', iconPath: 'assets/images/crypto/nano.webp', decimals: 30,flatIconPath: "assets/new-ui/balance_card_icons/nano.svg"); - static const trx = CryptoCurrency(title: 'TRX', fullName: 'TRON', raw: 11, name: 'trx', iconPath: 'assets/images/crypto/tron.webp', decimals: 6,flatIconPath: "assets/new-ui/balance_card_icons/tron.svg", chainIconPath: "assets/new-ui/chain_badges/tron.svg"); - static const usdt = CryptoCurrency(title: 'USDT', tag: 'OMNI', fullName: 'Tether', raw: 12, name: 'usdt', iconPath: 'assets/images/crypto/tether.webp', decimals: 6); - static const usdterc20 = CryptoCurrency(title: 'USDT', tag: 'ETH', fullName: 'Tether', raw: 13, name: 'usdterc20', iconPath: 'assets/images/crypto/tether.webp', decimals: 6); + static const ltc = CryptoCurrency(title: 'LTC', fullName: 'Litecoin', raw: 9, name: 'ltc', iconPath: 'assets/images/crypto/litecoin.webp', iconSvgPath: "assets/new-ui/crypto_full_icons/litecoin.svg",decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/litecoin.svg", chainIconPath: "assets/new-ui/chain_badges/mweb.svg"); + static const nano = CryptoCurrency(title: 'XNO', fullName: 'Nano', raw: 10, name: 'xno', iconPath: 'assets/images/crypto/nano.webp', iconSvgPath: "assets/new-ui/crypto_full_icons/nano.svg",decimals: 30,flatIconPath: "assets/new-ui/balance_card_icons/nano.svg"); + static const trx = CryptoCurrency(title: 'TRX', fullName: 'TRON', raw: 11, name: 'trx', iconPath: 'assets/images/crypto/tron.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/tron.svg", decimals: 6,flatIconPath: "assets/new-ui/balance_card_icons/tron.svg", chainIconPath: "assets/new-ui/chain_badges/tron.svg"); + static const usdt = CryptoCurrency(title: 'USDT', tag: 'OMNI', fullName: 'Tether', raw: 12, name: 'usdt', iconPath: 'assets/images/crypto/tether.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdt.svg", decimals: 6); + static const usdterc20 = CryptoCurrency(title: 'USDT', tag: 'ETH', fullName: 'Tether', raw: 13, name: 'usdterc20', iconPath: 'assets/images/crypto/tether.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdt.svg", decimals: 6); static const xlm = CryptoCurrency(title: 'XLM', fullName: 'Stellar', raw: 14, name: 'xlm', iconPath: 'assets/images/xlm_icon.png', decimals: 7); static const xrp = CryptoCurrency(title: 'XRP', fullName: 'Ripple', raw: 15, name: 'xrp', iconPath: 'assets/images/xrp_icon.png', decimals: 6); static const xhv = CryptoCurrency(title: 'XHV', fullName: 'Haven Protocol', raw: 16, name: 'xhv', iconPath: 'assets/images/xhv_logo.png', decimals: 12); @@ -182,42 +184,42 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen static const xusd = CryptoCurrency(title: 'XUSD', tag: 'XHV', raw: 29, name: 'xusd', decimals: 12); static const ape = CryptoCurrency(title: 'APE', tag: 'ETH', fullName: 'ApeCoin', raw: 30, name: 'ape', iconPath: 'assets/images/ape_icon.png', decimals: 18); - static const avaxc = CryptoCurrency(title: 'AVAX', tag: 'AVAXC', fullName: 'Avalanche', raw: 31, name: 'avaxc', iconPath: 'assets/images/avaxc_icon.png', decimals: 9); + static const avaxc = CryptoCurrency(title: 'AVAX', tag: 'AVAXC', fullName: 'Avalanche', raw: 31, name: 'avaxc', iconPath: 'assets/images/avaxc_icon.png',iconSvgPath: "assets/new-ui/crypto_full_icons/avax.svg", decimals: 9); static const btt = CryptoCurrency(title: 'BTT', tag: 'ETH', fullName: 'BitTorrent', raw: 32, name: 'btt', iconPath: 'assets/images/btt_icon.png', decimals: 18); static const bttc = CryptoCurrency(title: 'BTTC', tag: 'TRX', fullName: 'BitTorrent-NEW', raw: 33, name: 'bttc', iconPath: 'assets/images/btt_icon.png', decimals: 18); - static const doge = CryptoCurrency(title: 'DOGE', fullName: 'Dogecoin', raw: 34, name: 'doge', iconPath: 'assets/images/crypto/dogecoin.webp', decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/dogecoin.svg"); + static const doge = CryptoCurrency(title: 'DOGE', fullName: 'Dogecoin', raw: 34, name: 'doge', iconPath: 'assets/images/crypto/dogecoin.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/dogecoin.svg", decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/dogecoin.svg"); static const firo = CryptoCurrency(title: 'FIRO', raw: 35, name: 'firo', iconPath: 'assets/images/firo_icon.png', decimals: 8); - static const usdttrc20 = CryptoCurrency(title: 'USDT', tag: 'TRX', fullName: 'Tether', raw: 36, name: 'usdttrc20', iconPath: 'assets/images/crypto/tether.webp', decimals: 6); + static const usdttrc20 = CryptoCurrency(title: 'USDT', tag: 'TRX', fullName: 'Tether', raw: 36, name: 'usdttrc20', iconPath: 'assets/images/crypto/tether.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdt.svg", decimals: 6); static const hbar = CryptoCurrency(title: 'HBAR', fullName: 'Hedera', raw: 37, name: 'hbar', iconPath: 'assets/images/hbar_icon.png', decimals: 8); static const sc = CryptoCurrency(title: 'SC', fullName: 'Siacoin', raw: 38, name: 'sc', iconPath: 'assets/images/sc_icon.png', decimals: 16); - static const sol = CryptoCurrency(title: 'SOL', fullName: 'Solana', raw: 39, name: 'sol', iconPath: 'assets/images/crypto/solana.webp', decimals: 9,flatIconPath: "assets/new-ui/balance_card_icons/solana.svg", chainIconPath: "assets/new-ui/chain_badges/solana.svg"); - static const usdc = CryptoCurrency(title: 'USDC', tag: 'ETH', fullName: 'USDC', raw: 40, name: 'usdc', iconPath: 'assets/images/crypto/usdc.webp', decimals: 6); - static const usdcsol = CryptoCurrency(title: 'USDC', tag: 'SOL', fullName: 'USDC Coin', raw: 41, name: 'usdcsol', iconPath: 'assets/images/crypto/usdc.webp', decimals: 6); + static const sol = CryptoCurrency(title: 'SOL', fullName: 'Solana', raw: 39, name: 'sol', iconPath: 'assets/images/crypto/solana.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/solana.svg", decimals: 9,flatIconPath: "assets/new-ui/balance_card_icons/solana.svg", chainIconPath: "assets/new-ui/chain_badges/solana.svg"); + static const usdc = CryptoCurrency(title: 'USDC', tag: 'ETH', fullName: 'USDC', raw: 40, name: 'usdc', iconPath: 'assets/images/crypto/usdc.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdc.svg", decimals: 6); + static const usdcsol = CryptoCurrency(title: 'USDC', tag: 'SOL', fullName: 'USDC Coin', raw: 41, name: 'usdcsol', iconPath: 'assets/images/crypto/usdc.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdc.svg", decimals: 6); static const zaddr = CryptoCurrency(title: 'ZZEC', tag: 'ZEC', fullName: 'Shielded Zcash', raw: 42, name: 'zaddr', iconPath: 'assets/images/zec_icon.png', decimals: 8); static const tzec = CryptoCurrency(title: 'tZEC', tag: 'ZEC', fullName: 'Transparent Zcash', raw: 43, name: 'zec', iconPath: 'assets/images/zec_icon.png', decimals: 8); static const zen = CryptoCurrency(title: 'ZEN', fullName: 'Horizen', raw: 44, name: 'zen', iconPath: 'assets/images/zen_icon.png', decimals: 8); static const xvg = CryptoCurrency(title: 'XVG', fullName: 'Verge', raw: 45, name: 'xvg', iconPath: 'assets/images/xvg_icon.png', decimals: 8); - static const usdcpoly = CryptoCurrency(title: 'USDC', tag: 'POL', fullName: 'USDC', raw: 46, name: 'usdcpoly', iconPath: 'assets/images/crypto/usdc.webp', decimals: 6); - static const dcr = CryptoCurrency(title: 'DCR', fullName: 'Decred', raw: 47, name: 'dcr', iconPath: 'assets/images/crypto/decred.webp', decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/decred.svg"); + static const usdcpoly = CryptoCurrency(title: 'USDC', tag: 'POL', fullName: 'USDC', raw: 46, name: 'usdcpoly', iconPath: 'assets/images/crypto/usdc.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdc.svg", decimals: 6); + static const dcr = CryptoCurrency(title: 'DCR', fullName: 'Decred', raw: 47, name: 'dcr', iconPath: 'assets/images/crypto/decred.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/decred.svg", decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/decred.svg"); static const kmd = CryptoCurrency(title: 'KMD', fullName: 'Komodo', raw: 48, name: 'kmd', iconPath: 'assets/images/kmd_icon.png', decimals: 8); static const mana = CryptoCurrency(title: 'MANA', tag: 'ETH', fullName: 'Decentraland', raw: 49, name: 'mana', iconPath: 'assets/images/mana_icon.png', decimals: 18); - static const maticpoly = CryptoCurrency(title: 'POL', tag: 'POL', fullName: 'Polygon', raw: 50, name: 'maticpoly', iconPath: 'assets/images/crypto/polygon.webp', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/polygon.svg", chainIconPath: "assets/new-ui/chain_badges/polygon.svg"); - static const matic = CryptoCurrency(title: 'MATIC', tag: 'ETH', fullName: 'Polygon', raw: 51, name: 'matic', iconPath: 'assets/images/crypto/polygon.webp', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/polygon.svg"); + static const maticpoly = CryptoCurrency(title: 'POL', tag: 'POL', fullName: 'Polygon', raw: 50, name: 'maticpoly', iconPath: 'assets/images/crypto/polygon.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/polygon.svg", decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/polygon.svg", chainIconPath: "assets/new-ui/chain_badges/polygon.svg"); + static const matic = CryptoCurrency(title: 'MATIC', tag: 'ETH', fullName: 'Polygon', raw: 51, name: 'matic', iconPath: 'assets/images/crypto/polygon.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/polygon.svg", decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/polygon.svg"); static const mkr = CryptoCurrency(title: 'MKR', tag: 'ETH', fullName: 'Maker', raw: 52, name: 'mkr', iconPath: 'assets/images/mkr_icon.png', decimals: 18); static const near = CryptoCurrency(title: 'NEAR', fullName: 'NEAR Protocol', raw: 53, name: 'near', iconPath: 'assets/images/near_icon.png', decimals: 24); static const oxt = CryptoCurrency(title: 'OXT', tag: 'ETH', fullName: 'Orchid', raw: 54, name: 'oxt', iconPath: 'assets/images/oxt_icon.png', decimals: 18); - static const paxg = CryptoCurrency(title: 'PAXG', tag: 'ETH', fullName: 'Pax Gold', raw: 55, name: 'paxg', iconPath: 'assets/images/paxg.webp', decimals: 18); + static const paxg = CryptoCurrency(title: 'PAXG', tag: 'ETH', fullName: 'Pax Gold', raw: 55, name: 'paxg', iconPath: 'assets/images/paxg.webp', iconSvgPath: "assets/new-ui/crypto_full_icons/paxg.svg",decimals: 18); static const pivx = CryptoCurrency(title: 'PIVX', raw: 56, name: 'pivx', iconPath: 'assets/images/pivx_icon.png', decimals: 8); static const rune = CryptoCurrency(title: 'RUNE', fullName: 'Thorchain', raw: 57, name: 'rune', iconPath: 'assets/images/rune_icon.png', decimals: 18); static const rvn = CryptoCurrency(title: 'RVN', fullName: 'Ravencoin', raw: 58, name: 'rvn', iconPath: 'assets/images/rvn_icon.png', decimals: 8); static const scrt = CryptoCurrency(title: 'SCRT', fullName: 'Secret Network', raw: 59, name: 'scrt', iconPath: 'assets/images/scrt_icon.png', decimals: 6); static const uni = CryptoCurrency(title: 'UNI', tag: 'ETH', fullName: 'Uniswap', raw: 60, name: 'uni', iconPath: 'assets/images/uni_icon.png', decimals: 18); static const stx = CryptoCurrency(title: 'STX', fullName: 'Stacks', raw: 61, name: 'stx', iconPath: 'assets/images/stx_icon.png', decimals: 8); - static const btcln = CryptoCurrency(title: 'BTC', tag: 'LN', fullName: 'Bitcoin Lightning Network', raw: 62, name: 'btcln', iconPath: 'assets/images/crypto/lightning.webp', decimals: 8); + static const btcln = CryptoCurrency(title: 'BTC', tag: 'LN', fullName: 'Bitcoin Lightning Network', raw: 62, name: 'btcln', iconPath: 'assets/images/crypto/lightning.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/lightning.svg", chainIconPath: "assets/new-ui/chain_badges/lightning.svg", decimals: 8); static const shib = CryptoCurrency(title: 'SHIB', tag: 'ETH', fullName: 'Shiba Inu', raw: 63, name: 'shib', iconPath: 'assets/images/shib_icon.png', decimals: 18); static const aave = CryptoCurrency(title: 'AAVE', tag: 'ETH', fullName: 'Aave', raw: 64, name: 'aave', iconPath: 'assets/images/aave_icon.png', decimals: 18); - static const arb = CryptoCurrency(title: 'ARB', fullName: 'Arbitrum', raw: 65, name: 'arb', iconPath: 'assets/images/crypto/arbitrum.webp', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/arbitrum.svg", chainIconPath: "assets/new-ui/chain_badges/arbitrum.svg"); + static const arb = CryptoCurrency(title: 'ARB', fullName: 'Arbitrum', raw: 65, name: 'arb', iconPath: 'assets/images/crypto/arbitrum.webp', iconSvgPath: "assets/new-ui/crypto_full_icons/arbitrum.svg", decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/arbitrum.svg", chainIconPath: "assets/new-ui/chain_badges/arbitrum.svg"); static const bat = CryptoCurrency(title: 'BAT', tag: 'ETH', fullName: 'Basic Attention Token', raw: 66, name: 'bat', iconPath: 'assets/images/bat_icon.png', decimals: 18); static const comp = CryptoCurrency(title: 'COMP', tag: 'ETH', fullName: 'Compound', raw: 67, name: 'comp', iconPath: 'assets/images/comp_icon.png', decimals: 18); static const cro = CryptoCurrency(title: 'CRO', tag: 'ETH', fullName: 'Crypto.com Cronos', raw: 68, name: 'cro', iconPath: 'assets/images/cro_icon.png', decimals: 8); @@ -233,36 +235,36 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen static const pepe = CryptoCurrency(title: 'PEPE', tag: 'ETH', fullName: 'Pepe', raw: 78, name: 'pepe', iconPath: 'assets/images/pepe_icon.png', decimals: 18); static const storj = CryptoCurrency(title: 'STORJ', tag: 'ETH', fullName: 'Storj', raw: 79, name: 'storj', iconPath: 'assets/images/storj_icon.png', decimals: 8); static const tusd = CryptoCurrency(title: 'TUSD', tag: 'ETH', fullName: 'TrueUSD', raw: 80, name: 'tusd', iconPath: 'assets/images/tusd_icon.png', decimals: 18); - static const wbtc = CryptoCurrency(title: 'WBTC', tag: 'ETH', fullName: 'Wrapped Bitcoin', raw: 81, name: 'wbtc', iconPath: 'assets/images/crypto/wbtc.webp', decimals: 8); - static const weth = CryptoCurrency(title: 'WETH', tag: 'ETH', fullName: 'Wrapped Ethereum', raw: 82, name: 'weth', iconPath: 'assets/images/crypto/ethereum.webp', decimals: 18); + static const wbtc = CryptoCurrency(title: 'WBTC', tag: 'ETH', fullName: 'Wrapped Bitcoin', raw: 81, name: 'wbtc', iconPath: 'assets/images/crypto/wbtc.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/wbtc.svg", decimals: 8); + static const weth = CryptoCurrency(title: 'WETH', tag: 'ETH', fullName: 'Wrapped Ethereum', raw: 82, name: 'weth', iconPath: 'assets/images/crypto/ethereum.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/ethereum.svg", decimals: 18); static const zrx = CryptoCurrency(title: 'ZRX', tag: 'ETH', fullName: '0x Protocol', raw: 83, name: 'zrx', iconPath: 'assets/images/zrx_icon.png', decimals: 18); static const dydx = CryptoCurrency(title: 'DYDX', tag: 'ETH', fullName: 'dYdX', raw: 84, name: 'dydx', iconPath: 'assets/images/dydx_icon.png', decimals: 18); - static const steth = CryptoCurrency(title: 'STETH', tag: 'ETH', fullName: 'Lido Staked Ethereum', raw: 85, name: 'steth', iconPath: 'assets/images/crypto/ethereum.webp', decimals: 18); + static const steth = CryptoCurrency(title: 'STETH', tag: 'ETH', fullName: 'Lido Staked Ethereum', raw: 85, name: 'steth', iconPath: 'assets/images/crypto/ethereum.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/ethereum.svg", decimals: 18); static const banano = CryptoCurrency(title: 'BAN', fullName: 'Banano', raw: 86, name: 'banano', iconPath: 'assets/images/nano_icon.png', decimals: 29,flatIconPath: "assets/new-ui/balance_card_icons/nano.svg"); - static const usdtPoly = CryptoCurrency(title: 'USDT', tag: 'POL', fullName: 'Tether (PoS)', raw: 87, name: 'usdtpoly', iconPath: 'assets/images/crypto/tether.webp', decimals: 6); - static const usdcEPoly = CryptoCurrency(title: 'USDC.E', tag: 'POL', fullName: 'USDC (PoS)', raw: 88, name: 'usdcepoly', iconPath: 'assets/images/crypto/usdc.webp', decimals: 6); + static const usdtPoly = CryptoCurrency(title: 'USDT', tag: 'POL', fullName: 'Tether (PoS)', raw: 87, name: 'usdtpoly', iconPath: 'assets/images/crypto/tether.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdt.svg", decimals: 6); + static const usdcEPoly = CryptoCurrency(title: 'USDC.E', tag: 'POL', fullName: 'USDC (PoS)', raw: 88, name: 'usdcepoly', iconPath: 'assets/images/crypto/usdc.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdc.svg", decimals: 6); static const kaspa = CryptoCurrency(title: 'KAS', fullName: 'Kaspa', raw: 89, name: 'kas', iconPath: 'assets/images/kaspa_icon.png', decimals: 8); static const digibyte = CryptoCurrency(title: 'DGB', fullName: 'DigiByte', raw: 90, name: 'dgb', iconPath: 'assets/images/digibyte.png', decimals: 8); - static const usdtSol = CryptoCurrency(title: 'USDT', tag: 'SOL', fullName: 'Tether', raw: 91, name: 'usdtsol', iconPath: 'assets/images/crypto/tether.webp', decimals: 6); - static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/images/crypto/usdc.webp', decimals: 6); + static const usdtSol = CryptoCurrency(title: 'USDT', tag: 'SOL', fullName: 'Tether', raw: 91, name: 'usdtsol', iconPath: 'assets/images/crypto/tether.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdt.svg", decimals: 6); + static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/images/crypto/usdc.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdc.svg", decimals: 6); static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 93, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8); static const wow = CryptoCurrency(title: 'WOW', fullName: 'Wownero', raw: 94, name: 'wow', iconPath: 'assets/images/crypto/wownero.webp', decimals: 11); - static const ton = CryptoCurrency(title: 'TON', fullName: 'Toncoin', raw: 95, name: 'ton', iconPath: 'assets/images/ton_icon.png', decimals: 8); - static const zano = CryptoCurrency(title: 'ZANO', tag: 'ZANO', fullName: 'Zano', raw: 96, name: 'zano', iconPath: 'assets/images/crypto/zano.webp', decimals: 12,flatIconPath: "assets/new-ui/balance_card_icons/zano.svg", chainIconPath: "assets/new-ui/chain_badges/zano.svg"); + static const ton = CryptoCurrency(title: 'TON', fullName: 'Toncoin', raw: 95, name: 'ton', iconPath: 'assets/images/ton_icon.png', iconSvgPath: "assets/new-ui/crypto_full_icons/ton.svg",decimals: 8); + static const zano = CryptoCurrency(title: 'ZANO', tag: 'ZANO', fullName: 'Zano', raw: 96, name: 'zano', iconPath: 'assets/images/crypto/zano.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/zano.svg", decimals: 12,flatIconPath: "assets/new-ui/balance_card_icons/zano.svg", chainIconPath: "assets/new-ui/chain_badges/zano.svg"); static const flip = CryptoCurrency(title: 'FLIP', tag: 'ETH', fullName: 'Chainflip', raw: 97, name: 'flip', iconPath: 'assets/images/flip_icon.png', decimals: 18); - static const deuro = CryptoCurrency(title: 'DEURO', tag: 'ETH', fullName: 'Decentralized Euro', raw: 98, name: 'deuro', iconPath: 'assets/images/deuro_icon.png', decimals: 18); - static const usdtbsc = CryptoCurrency(title: 'USDT', tag: 'BSC', fullName: 'USDT Binance coin', raw: 99, name: 'usdtbsc', iconPath: 'assets/images/crypto/tether.webp', decimals: 18); + static const deuro = CryptoCurrency(title: 'DEURO', tag: 'ETH', fullName: 'Decentralized Euro', raw: 98, name: 'deuro', iconPath: 'assets/images/deuro_icon.png', iconSvgPath: "assets/new-ui/crypto_full_icons/deuro.svg",decimals: 18); + static const usdtbsc = CryptoCurrency(title: 'USDT', tag: 'BSC', fullName: 'USDT Binance coin', raw: 99, name: 'usdtbsc', iconPath: 'assets/images/crypto/tether.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdt.svg", decimals: 18); static const ndeps = CryptoCurrency(title: 'NDEPS', tag: 'ETH', fullName: 'Native Decentralized Euro Protocol Share', raw: 100, name: 'ndeps', iconPath: 'assets/images/ndeps_icon.png', decimals: 18); static const deps = CryptoCurrency(title: 'DEPS', tag: 'ETH', fullName: 'Decentralized Euro Protocol Share', raw: 101, name: 'deps', iconPath: 'assets/images/deps_icon.png', decimals: 18); static const kbtc = CryptoCurrency(title: 'KBTC', tag: 'ETH', fullName: 'Kraken Wrapped Bitcoin', raw: 102, name: 'kbtc', iconPath: 'assets/images/kbtc_icon.png', decimals: 8); static const cbbtc = CryptoCurrency(title: 'CBBTC', tag: 'ETH', fullName: 'Coinbase Wrapped BTC', raw: 103, name: 'cbbtc', iconPath: 'assets/images/cbbtc_icon.png', decimals: 8); - static const baseEth = CryptoCurrency(title: 'ETH', tag: 'BASE', fullName: 'Ethereum', raw: 104, name: 'baseth', iconPath: 'assets/images/crypto/ethereum.webp', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/base.svg", chainIconPath: "assets/new-ui/chain_badges/base.svg"); - static const usde = CryptoCurrency(title: 'USDE', tag: 'BASE', fullName: 'Ethena USDE', raw: 105, name: 'usde', iconPath: 'assets/images/crypto/ethena-usde-logo.png', decimals: 18); - static const arbEth = CryptoCurrency(title: 'ETH', tag: 'ARB', fullName: 'Ethereum', raw: 106, name: 'arbeth', iconPath: 'assets/images/crypto/ethereum.webp', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/arbitrum.svg"); - static const zec = CryptoCurrency(title: 'ZEC', fullName: 'Zcash', raw: 107, name: 'zec', iconPath: 'assets/images/zec_icon.png', decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/zcash.svg"); - static const usdcArb = CryptoCurrency(title: 'USDC', tag: 'ARB', fullName: 'USDC Coin', raw: 108, name: 'usdcarb', iconPath: 'assets/images/crypto/usdc.webp', decimals: 6); - static const usdtArb = CryptoCurrency(title: 'USDT', tag: 'ARB', fullName: 'USDT Tether', raw: 109, name: 'usdtarb', iconPath: 'assets/images/crypto/tether.webp', decimals: 6); - static const ltcmweb = CryptoCurrency(title: 'LTC', fullName: 'Litecoin MWeb', raw: 110, name: 'ltcmweb', iconPath: 'assets/images/crypto/litecoin.webp', decimals: 8); + static const baseEth = CryptoCurrency(title: 'ETH', tag: 'BASE', fullName: 'Ethereum', raw: 104, name: 'baseth', iconPath: 'assets/images/crypto/ethereum.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/ethereum.svg", decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/base.svg", chainIconPath: "assets/new-ui/chain_badges/base.svg"); + static const usde = CryptoCurrency(title: 'USDE', tag: 'BASE', fullName: 'Ethena USDE', raw: 105, name: 'usde', iconPath: 'assets/images/crypto/ethena-usde-logo.png',iconSvgPath: "assets/new-ui/crypto_full_icons/usde.svg", decimals: 18); + static const arbEth = CryptoCurrency(title: 'ETH', tag: 'ARB', fullName: 'Ethereum', raw: 106, name: 'arbeth', iconPath: 'assets/images/crypto/ethereum.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/ethereum.svg", decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/arbitrum.svg"); + static const zec = CryptoCurrency(title: 'ZEC', fullName: 'Zcash', raw: 107, name: 'zec', iconPath: 'assets/images/zec_icon.png',iconSvgPath: "assets/new-ui/crypto_full_icons/zcash.svg", decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/zcash.svg"); + static const usdcArb = CryptoCurrency(title: 'USDC', tag: 'ARB', fullName: 'USDC Coin', raw: 108, name: 'usdcarb', iconPath: 'assets/images/crypto/usdc.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdc.svg", decimals: 6); + static const usdtArb = CryptoCurrency(title: 'USDT', tag: 'ARB', fullName: 'USDT Tether', raw: 109, name: 'usdtarb', iconPath: 'assets/images/crypto/tether.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/usdt.svg", decimals: 6); + static const ltcmweb = CryptoCurrency(title: 'LTC', fullName: 'Litecoin MWeb', raw: 110, name: 'ltcmweb', iconPath: 'assets/images/crypto/litecoin.webp',iconSvgPath: "assets/new-ui/crypto_full_icons/litecoin.svg", decimals: 8); static final Map _rawCurrencyMap = [...all, ...havenCurrencies, ...zcashCurrencies].fold>({}, (acc, item) { diff --git a/cw_core/lib/db/sqlite.dart b/cw_core/lib/db/sqlite.dart index 15601c6f9..b32c1e82b 100644 --- a/cw_core/lib/db/sqlite.dart +++ b/cw_core/lib/db/sqlite.dart @@ -39,7 +39,7 @@ Future initDb({String? pathOverride}) async { } } await db?.close(); - db = await openDatabase(dbFile.path, version: 3, + db = await openDatabase(dbFile.path, version: 4, onUpgrade: (Database db, int oldVersion, int newVersion) async { printV("migrating: $oldVersion, $newVersion"); if (oldVersion <= 1) { @@ -81,6 +81,13 @@ CREATE TABLE IF NOT EXISTS BalanceCardStyleSettings ( definition: 'INTEGER DEFAULT 0', ); } + if (oldVersion <= 3) { + await _addColumnIfNotExists(db, table: "WalletInfo", column: "showCombinedBalance", definition: "BOOLEAN DEFAULT TRUE"); + // null - primary token (eth, sol etc) + // not null - address of fav token + // if address doesn't correspond to a valid token, fallback to primary token + await _addColumnIfNotExists(db, table: "WalletInfo", column: "favoriteTokenAddress", definition: "TEXT DEFAULT NULL"); + } }, onCreate: (Database db, int version) async { await db.execute( @@ -107,7 +114,9 @@ CREATE TABLE WalletInfo ( hashedWalletIdentifier TEXT, isNonSeedWallet INTEGER DEFAULT (0) NOT NULL, sortOrder INTEGER DEFAULT (0) NOT NULL, - receiveInfoboxDismissed BOOLEAN DEFAULT FALSE + receiveInfoboxDismissed BOOLEAN DEFAULT FALSE, + showCombinedBalance BOOLEAN DEFAULT TRUE, + favoriteTokenAddress TEXT DEFAULT NULL ); '''); diff --git a/cw_core/lib/wallet_info.dart b/cw_core/lib/wallet_info.dart index c42f6856a..90be1b32f 100644 --- a/cw_core/lib/wallet_info.dart +++ b/cw_core/lib/wallet_info.dart @@ -347,8 +347,9 @@ class WalletInfo { this.isNonSeedWallet, this.sortOrder, this.addressPageType, - this.receiveInfoboxDismissed - + this.receiveInfoboxDismissed, + this.showCombinedBalance, + this.favoriteTokenAddress ) : _yatLastUsedAddressController = StreamController.broadcast(); factory WalletInfo.external({ @@ -371,6 +372,8 @@ class WalletInfo { bool? isNonSeedWallet, int? sortOrder, bool? receiveInfoboxDismissed, + bool? showCombinedBalance, + String? favoriteTokenAddress }) { return WalletInfo( 0, @@ -393,7 +396,9 @@ class WalletInfo { isNonSeedWallet ?? false, sortOrder ?? 0, null, - receiveInfoboxDismissed ?? false + receiveInfoboxDismissed ?? false, + showCombinedBalance ?? true, + favoriteTokenAddress ); } @@ -413,6 +418,8 @@ class WalletInfo { String path; String address; bool receiveInfoboxDismissed; + bool showCombinedBalance; + String? favoriteTokenAddress; Future> getAddresses() async { final list = await WalletInfoAddressMap.selectList(internalId); @@ -578,7 +585,8 @@ class WalletInfo { "sortOrder": sortOrder, "addressPageType": addressPageType, "receiveInfoboxDismissed": receiveInfoboxDismissed ? 1 : 0, - + "showCombinedBalance": showCombinedBalance ? 1 : 0, + "favoriteTokenAddress": favoriteTokenAddress }; factory WalletInfo.fromJson(Map json) { @@ -606,6 +614,8 @@ class WalletInfo { json['sortOrder'] as int? ?? 0, json['addressPageType'] as String? ?? null, json['receiveInfoboxDismissed'] != 0, + json["showCombinedBalance"] != 0, + json["favoriteTokenAddress"] as String? ?? null ); } diff --git a/cw_core/lib/wallet_info_legacy.dart b/cw_core/lib/wallet_info_legacy.dart index 3b8a78a0a..a7e6bc31f 100644 --- a/cw_core/lib/wallet_info_legacy.dart +++ b/cw_core/lib/wallet_info_legacy.dart @@ -271,7 +271,9 @@ class WalletInfo extends HiveObject { isNonSeedWallet, 0, addressPageType, - false + false, + true, + null ); final wiId = await walletInfo.save(); for (final address in usedAddresses ?? []) { diff --git a/lib/new-ui/pages/swap_page.dart b/lib/new-ui/pages/swap_page.dart index 42d7463ef..c3b88bfd8 100644 --- a/lib/new-ui/pages/swap_page.dart +++ b/lib/new-ui/pages/swap_page.dart @@ -854,6 +854,9 @@ class SwapAmountBoxState extends State { .getCryptoSymbol(_selectedCurrency as CryptoCurrency) : _selectedCurrency.name.toUpperCase(); + + final chainIconPath = (_selectedCurrency is CryptoCurrency) ? _getCurrencyChainIconPath(_selectedCurrency as CryptoCurrency) : null; + return Column( spacing: 12, crossAxisAlignment: CrossAxisAlignment.start, @@ -939,16 +942,38 @@ class SwapAmountBoxState extends State { currencyToShow, textAlign: TextAlign.center, ), - SizedBox(width:10), - RotatedBox( - quarterTurns: 2, - child: CakeImageWidget(imageUrl: - "assets/new-ui/dropdown_arrow.svg", - width: 4, - height: 4, - colorFilter: ColorFilter.mode( - Theme.of(context).colorScheme.primary, BlendMode.srcIn), - )), + if (chainIconPath != null && chainIconPath.isNotEmpty) ...[ + SizedBox(width: 4), + CakeImageWidget( + imageUrl: chainIconPath, + width: 12, + height: 12, + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.onSurfaceVariant, + BlendMode.srcIn), + ), + SizedBox(width: 6) + ] else + SizedBox(width: 10), + Container( + width:16,height:16, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(9999999999), + color: Theme.of(context).colorScheme.surfaceContainerHigh + ), + child: Padding( + padding: const EdgeInsets.all(4.0), + child: RotatedBox( + quarterTurns: 2, + child: CakeImageWidget(imageUrl: + "assets/new-ui/dropdown_arrow.svg", + width: 4, + height: 4, + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.primary, BlendMode.srcIn), + )), + ), + ), SizedBox(width:4), ], ), @@ -1255,4 +1280,20 @@ class SwapAmountBoxState extends State { if (s.length <= head + tail + 3) return s; return s.substring(0, head) + '...' + s.substring(s.length - tail); } + + String? _getCurrencyChainIconPath(CryptoCurrency curr) { + try{ + + if(curr.chainIconPath != null) return curr.chainIconPath!; + + + if(curr.tag != null) { + final currencyFromTag = CryptoCurrency.fromString(curr.tag!); + if(currencyFromTag.chainIconPath != null) { + return currencyFromTag.chainIconPath!; + } + } + }catch(_){} + return null; + } } diff --git a/lib/new-ui/widgets/coins_page/assets_history/asset_details_modal.dart b/lib/new-ui/widgets/coins_page/assets_history/asset_details_modal.dart index 8bdf7571c..77fca71fe 100644 --- a/lib/new-ui/widgets/coins_page/assets_history/asset_details_modal.dart +++ b/lib/new-ui/widgets/coins_page/assets_history/asset_details_modal.dart @@ -13,7 +13,6 @@ import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/unspent_coin_type.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; enum AssetDetailsModalModes { normal, ltcTransparent, ltcPrivate } @@ -60,6 +59,7 @@ class AssetDetailsModal extends StatelessWidget { title: "", trailingIcon: Icon(Icons.close), onTrailingPressed: Navigator.of(context).pop, + padding: EdgeInsets.only(top:12,right:18), ), SafeArea( child: Column( @@ -89,25 +89,25 @@ class AssetDetailsModal extends StatelessWidget { fontSize: 28, color: Theme.of(context).colorScheme.onPrimary), )), ), - if (chainIconPath.isNotEmpty) - Align( - alignment: Alignment.bottomRight, - child: Container( - decoration: ShapeDecoration( - shape: RoundedSuperellipseBorder( - borderRadius: BorderRadius.circular(8), - side: BorderSide(color: Colors.black)), - color: Colors.white), - child: Padding( - padding: const EdgeInsets.all(4.0), - child: CakeImageWidget(imageUrl: - chainIconPath, - width: 18, - height: 18, - colorFilter: - ColorFilter.mode(Colors.black, BlendMode.srcIn), - ), - ))) + // if (chainIconPath.isNotEmpty) + // Align( + // alignment: Alignment.bottomRight, + // child: Container( + // decoration: ShapeDecoration( + // shape: RoundedSuperellipseBorder( + // borderRadius: BorderRadius.circular(8), + // side: BorderSide(color: Colors.black)), + // color: Colors.white), + // child: Padding( + // padding: const EdgeInsets.all(4.0), + // child: CakeImageWidget(imageUrl: + // chainIconPath, + // width: 18, + // height: 18, + // colorFilter: + // ColorFilter.mode(Colors.black, BlendMode.srcIn), + // ), + // ))) ], ), ), @@ -125,14 +125,16 @@ class AssetDetailsModal extends StatelessWidget { fontWeight: FontWeight.w500, color: Theme.of(context).colorScheme.onSurface), ), + if(asset != null) Container( decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainerHigh, + color: Theme.of(context).colorScheme.surfaceContainer, borderRadius: BorderRadius.circular(999999999)), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4), + child: Text( - chainTitle, + asset?.title??"", style: TextStyle( color: Theme.of(context).colorScheme.onSurfaceVariant), ), @@ -141,11 +143,22 @@ class AssetDetailsModal extends StatelessWidget { ], ), if (subtitle.isNotEmpty) - Text( - subtitle, - style: TextStyle( - fontSize: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant), + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + if(chainIconPath.isNotEmpty) + CakeImageWidget( + imageUrl: chainIconPath, + width:16,height:16,colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant,BlendMode.srcIn), + ), + Text( + subtitle, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurfaceVariant), + ), + ], ), ], ) diff --git a/lib/new-ui/widgets/coins_page/assets_history/asset_tile.dart b/lib/new-ui/widgets/coins_page/assets_history/asset_tile.dart index 9eb4d7539..170672c7b 100644 --- a/lib/new-ui/widgets/coins_page/assets_history/asset_tile.dart +++ b/lib/new-ui/widgets/coins_page/assets_history/asset_tile.dart @@ -17,7 +17,7 @@ class AssetTile extends StatelessWidget { this.title, this.trailingText, this.modalMode = AssetDetailsModalModes.normal, - required this.wallet, required this.showSwap}); + required this.wallet, required this.showSwap, required this.isFirst, required this.isLast}); final BalanceRecord balance; final bool showSecondary; @@ -27,6 +27,8 @@ class AssetTile extends StatelessWidget { final String? trailingText; final AssetDetailsModalModes modalMode; final WalletBase wallet; + final bool isFirst; + final bool isLast; @override Widget build(BuildContext context) { @@ -42,8 +44,8 @@ class AssetTile extends StatelessWidget { showSwap: showSwap, asset: balance.asset, title: title ?? balance.asset.fullName ?? balance.asset.name, - chainTitle: _getChainTitle(), - subtitle: trailingText ?? "", + chainTitle: "", + subtitle: trailingText ?? _getChainTitle(), amount: showSecondary ? balance.secondAvailableBalance : balance.availableBalance, currencyTitle: balance.asset.title, fiatAmount: showSecondary @@ -57,23 +59,15 @@ class AssetTile extends StatelessWidget { }); }, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 6.0), + padding: const EdgeInsets.symmetric(horizontal: 18.0), child: Container( width: double.infinity, - height: 80, + height: 72, decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - Theme.of(context).colorScheme.surfaceContainerHigh, - Theme.of(context).colorScheme.surfaceContainer, - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - borderRadius: BorderRadius.all(Radius.circular(20)), - border: Border.all( - color: Theme.of(context).colorScheme.surfaceContainerHighest, - width: 1, + color: Theme.of(context).colorScheme.surfaceContainer, + borderRadius: BorderRadius.vertical( + top: isFirst ? Radius.circular(18) : Radius.zero, + bottom: isLast ? Radius.circular(18) : Radius.zero, ), ), child: Padding( @@ -87,16 +81,16 @@ class AssetTile extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Container( - width: 45, - height: 45, + width: 36, + height: 36, child: Stack( children: [ if((iconPath).isNotEmpty) CakeImageWidget(imageUrl: iconPath) else Container( - width: 45, - height: 45, + width: 36, + height: 36, decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary, borderRadius: BorderRadius.circular(99999)), @@ -107,27 +101,27 @@ class AssetTile extends StatelessWidget { fontSize: 20, color: Theme.of(context).colorScheme.onPrimary), )), ), - if (chainIconPath.isNotEmpty) - Align( - alignment: Alignment.bottomRight, - child: Container( - decoration: ShapeDecoration( - shape: RoundedSuperellipseBorder( - borderRadius: BorderRadius.circular(5),side: BorderSide(color: Colors.black)), - color: Colors.white), - child: Padding( - padding: const EdgeInsets.all(2.0), - child: CakeImageWidget( - imageUrl: chainIconPath, - width: 12, - height: 12, - colorFilter: - ColorFilter.mode(Colors.black, BlendMode.srcIn), - ), - ))) + // if (chainIconPath.isNotEmpty) + // Align( + // alignment: Alignment.bottomRight, + // child: Container( + // decoration: ShapeDecoration( + // shape: RoundedSuperellipseBorder( + // borderRadius: BorderRadius.circular(5),side: BorderSide(color: Colors.black)), + // color: Colors.white), + // child: Padding( + // padding: const EdgeInsets.all(2.0), + // child: CakeImageWidget( + // imageUrl: chainIconPath, + // width: 12, + // height: 12, + // colorFilter: + // ColorFilter.mode(Colors.black, BlendMode.srcIn), + // ), + // ))) ], )), - SizedBox(width: 8.0), + SizedBox(width: 12.0), Expanded( child: Column( spacing: 4.0, @@ -139,7 +133,7 @@ class AssetTile extends StatelessWidget { children: [ Text( title ?? balance.asset.fullName ?? balance.asset.name, - style: TextStyle(fontWeight: FontWeight.bold), + style: TextStyle(fontWeight: FontWeight.w500), ), if(trailingText != null) Text( @@ -184,9 +178,9 @@ class AssetTile extends StatelessWidget { String _getChainTitle() { try { - return CryptoCurrency.fromString(wallet.currency.tag ??wallet.currency.title).title; + return CryptoCurrency.fromString(wallet.currency.tag ??wallet.currency.title).fullName ?? ""; } catch(e) { - return wallet.currency.title; + return wallet.currency.fullName ?? ""; } } diff --git a/lib/new-ui/widgets/coins_page/assets_history/assets_section.dart b/lib/new-ui/widgets/coins_page/assets_history/assets_section.dart index 74990e294..6bd2661b0 100644 --- a/lib/new-ui/widgets/coins_page/assets_history/assets_section.dart +++ b/lib/new-ui/widgets/coins_page/assets_history/assets_section.dart @@ -21,11 +21,22 @@ class AssetsSection extends StatelessWidget { child: Observer( builder: (context) { final hasMweb = dashboardViewModel.hasMweb && dashboardViewModel.mwebEnabled; - return ListView.builder( + return ListView.separated( shrinkWrap: true, - padding: EdgeInsets.zero, + padding: EdgeInsets.symmetric(vertical: 18), physics: NeverScrollableScrollPhysics(), itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length + (hasMweb ? 1 : 0), + separatorBuilder: (context, index) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 18.0), + child: Container( + color: Theme.of(context).colorScheme.surfaceContainer, + height:1, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Container(color: Theme.of(context).colorScheme.surfaceContainerHigh,), + ), + ), + ), itemBuilder: (context, index) { return Observer(builder: (context) { if (hasMweb) { @@ -39,6 +50,8 @@ class AssetsSection extends StatelessWidget { modalMode: index > 0 ? AssetDetailsModalModes.ltcPrivate : AssetDetailsModalModes.ltcTransparent, + isFirst: index == 0, + isLast: index != 0, title: index > 0 ? "Litecoin Private" : null, ); } @@ -48,6 +61,8 @@ class AssetsSection extends StatelessWidget { showSwap: dashboardViewModel.isEnabledSwapAction, balance: balance, wallet: dashboardViewModel.wallet, + isFirst: index == 0, + isLast: index == dashboardViewModel.balanceViewModel.formattedBalances.length-1, chainIconPath: _getChainIconPath(), ); }); diff --git a/lib/new-ui/widgets/coins_page/assets_history/history_section.dart b/lib/new-ui/widgets/coins_page/assets_history/history_section.dart index a205ce0e0..497373d33 100644 --- a/lib/new-ui/widgets/coins_page/assets_history/history_section.dart +++ b/lib/new-ui/widgets/coins_page/assets_history/history_section.dart @@ -69,6 +69,8 @@ class HistorySection extends StatelessWidget { CryptoCurrency? asset; if (transaction.additionalInfo["isLightning"] == true) asset = CryptoCurrency.btcln; + else + asset = item.assetOfTransaction; return GestureDetector( onTap: () { @@ -80,6 +82,8 @@ class HistorySection extends StatelessWidget { date: DateFormat('HH:mm').format(transaction.date), amount: item.formattedCryptoAmount, amountFiat: item.formattedFiatAmount, + hasTokens: item.hasTokens, + chainIconPath: _getChainIconPath(), roundedBottom: roundedBottom, roundedTop: roundedTop, bottomSeparator: !roundedBottom, @@ -101,6 +105,7 @@ class HistorySection extends StatelessWidget { child: HistoryTradeTile( from: tradeFrom!, to: tradeTo!, + provider: trade.provider, date: DateFormat('HH:mm').format(item.trade.createdAt!), amount: trade.amountFormatted(), receiveAmount: trade.receiveAmountFormatted(), @@ -171,4 +176,12 @@ class HistorySection extends StatelessWidget { ), )); } + + String _getChainIconPath() { + try { + return CryptoCurrency.fromString(dashboardViewModel.wallet.currency.tag ??dashboardViewModel.wallet.currency.title).chainIconPath!; + } catch(e) { + return dashboardViewModel.wallet.currency.chainIconPath ?? ""; + } + } } diff --git a/lib/new-ui/widgets/coins_page/assets_history/history_tile.dart b/lib/new-ui/widgets/coins_page/assets_history/history_tile.dart index 3fcbc8dd8..16e51e809 100644 --- a/lib/new-ui/widgets/coins_page/assets_history/history_tile.dart +++ b/lib/new-ui/widgets/coins_page/assets_history/history_tile.dart @@ -17,6 +17,8 @@ class HistoryTile extends StatelessWidget { required this.direction, required this.pending, required this.bottomSeparator, + required this.hasTokens, + this.chainIconPath, this.asset, }); @@ -27,6 +29,8 @@ class HistoryTile extends StatelessWidget { final bool roundedTop; final bool roundedBottom; final bool bottomSeparator; + final bool hasTokens; + final String? chainIconPath; final TransactionDirection direction; final bool pending; final CryptoCurrency? asset; @@ -93,6 +97,33 @@ class HistoryTile extends StatelessWidget { ); } + if(hasTokens) { + return Stack(children: [ + Opacity( + opacity: pending ? 0.5 : 1, + child: CakeImageWidget(imageUrl: asset?.iconSvgPath ?? asset?.iconPath ??"", width: 34, + height: 34,), + ), + Align( + alignment: Alignment.bottomRight, + child: Container( + decoration: ShapeDecoration( + shape: RoundedSuperellipseBorder( + borderRadius: BorderRadius.circular(5),side: BorderSide(color: Colors.black)), + color: Colors.white), + child: Padding( + padding: const EdgeInsets.all(2.0), + child: CakeImageWidget( + imageUrl: chainIconPath, + width: 12, + height: 12, + colorFilter: + ColorFilter.mode(Colors.black, BlendMode.srcIn), + ), + ))) + ],); + } + return CakeImageWidget(imageUrl:_getDirectionIcon(), colorFilter: ColorFilter.mode( direction == TransactionDirection.outgoing diff --git a/lib/new-ui/widgets/coins_page/assets_history/history_tile_base.dart b/lib/new-ui/widgets/coins_page/assets_history/history_tile_base.dart index e2a42f0bd..44fe3882f 100644 --- a/lib/new-ui/widgets/coins_page/assets_history/history_tile_base.dart +++ b/lib/new-ui/widgets/coins_page/assets_history/history_tile_base.dart @@ -4,22 +4,32 @@ import 'package:flutter/material.dart'; class HistoryTileBase extends StatelessWidget { const HistoryTileBase({ super.key, - required this.title, + this.title, + this.titleWidget, required this.date, - required this.amount, + this.amount, required this.leadingIcon, - required this.amountFiat, + this.amountFiat, required this.roundedTop, required this.roundedBottom, required this.bottomSeparator, this.primaryTextColor, this.asset, - }); + this.amountWidget, + this.amountFiatWidget, + }) : assert((title != null || titleWidget != null) && (title == null || titleWidget == null)), + assert( + (amountWidget != null || amount != null) && (amountWidget == null || amount == null)), + assert((amountFiatWidget != null || amountFiat != null) && + (amountFiatWidget == null || amountFiat == null)); - final String title; + final String? title; + final Widget? titleWidget; final String date; - final String amount; - final String amountFiat; + final String? amount; + final Widget? amountWidget; + final String? amountFiat; + final Widget? amountFiatWidget; final Widget leadingIcon; final bool roundedTop; final bool roundedBottom; @@ -105,8 +115,10 @@ class HistoryTileBase extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(title, - style: TextStyle(color: Theme.of(context).colorScheme.onSurface)), + if(title != null) + Text(title!, + style: TextStyle(color: Theme.of(context).colorScheme.onSurface)) + else if(titleWidget != null) titleWidget!, Text(date, style: TextStyle( color: Theme.of(context).colorScheme.onSurfaceVariant)), @@ -115,12 +127,20 @@ class HistoryTileBase extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ - Text(amount, - style: TextStyle( - color: primaryTextColor ?? - Theme.of(context).colorScheme.onSurface)), - Text(amountFiat, style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)), - ], + if (amount != null) + Text(amount!, + style: TextStyle( + color: primaryTextColor ?? + Theme.of(context).colorScheme.onSurface)) + else if (amountWidget != null) + amountWidget!, + if (amountFiat != null) + Text(amountFiat!, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant)) + else if (amountFiatWidget != null) + amountFiatWidget! + ], ), ], ), diff --git a/lib/new-ui/widgets/coins_page/assets_history/history_trade_tile.dart b/lib/new-ui/widgets/coins_page/assets_history/history_trade_tile.dart index b3d6dc7e7..8a13bbb2b 100644 --- a/lib/new-ui/widgets/coins_page/assets_history/history_trade_tile.dart +++ b/lib/new-ui/widgets/coins_page/assets_history/history_trade_tile.dart @@ -1,5 +1,8 @@ +import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/exchange/trade_state.dart'; import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/history_tile_base.dart'; +import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; +import 'package:cw_core/crypto_amount_format.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:flutter/material.dart'; @@ -14,10 +17,12 @@ class HistoryTradeTile extends StatelessWidget { required this.bottomSeparator, required this.from, required this.to, - required this.swapState}); + required this.swapState, + required this.provider}); final CryptoCurrency from; final CryptoCurrency to; + final ExchangeProviderDescription provider; final String date; final String amount; final String receiveAmount; @@ -34,7 +39,7 @@ class HistoryTradeTile extends StatelessWidget { width: 50, child: Stack( children: [ - Image.asset(_getIconPath(from), + CakeImageWidget(imageUrl: _getIconPath(from), width: currencyIconSize, height: currencyIconSize), Positioned( top: currencyIconSize / 2, @@ -45,7 +50,7 @@ class HistoryTradeTile extends StatelessWidget { width: 2, color: Theme.of(context).colorScheme.surfaceContainer), shape: BoxShape.circle), - child: Image.asset(_getIconPath(to), + child: CakeImageWidget(imageUrl: _getIconPath(to), width: currencyIconSize, height: currencyIconSize))), ], ), @@ -56,12 +61,55 @@ class HistoryTradeTile extends StatelessWidget { @override Widget build(BuildContext context) { + final fromChainIcon = _getChainIcon(from); + final toChainIcon = _getChainIcon(to); + return HistoryTileBase( - title: - "${from.toString()}${from == CryptoCurrency.btcln ? "-LN" : ""} → ${to.toString()}${to == CryptoCurrency.btcln ? "-LN" : ""}", + // title: + // "${from.toString()}${from == CryptoCurrency.btcln ? "-LN" : ""} → ${to.toString()}${to == CryptoCurrency.btcln ? "-LN" : ""}", + titleWidget: Row( + spacing: 4, + children: [ + Text(swapState.title), + CakeImageWidget(imageUrl: provider.image, width: 14, height: 14) + ], + ), date: date, - amount: amount, - amountFiat: receiveAmount, + amountFiatWidget: Row( + spacing: 4, + children: [ + Text("-", style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)), + Text(amount.withMaxDecimals(8), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant, + fontWeight: FontWeight.w500)), + Text(from.title, style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)), + if (fromChainIcon.isNotEmpty) + CakeImageWidget( + imageUrl: fromChainIcon, + width: 12, + height: 12, + colorFilter: + ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn), + ) + ], + ), + amountWidget: Row( + spacing: 4, + children: [ + Text( + "+", + ), + Text( + receiveAmount.withMaxDecimals(8), + style: TextStyle(fontWeight: FontWeight.w500), + ), + Text( + to.title, + ), + if (toChainIcon.isNotEmpty) CakeImageWidget(imageUrl: toChainIcon, width: 12, height: 12) + ], + ), leadingIcon: _getLeadingStack(context), roundedTop: roundedTop, roundedBottom: roundedBottom, @@ -93,4 +141,21 @@ class HistoryTradeTile extends StatelessWidget { //TODO approporiate fallback return ""; } + + String _getChainIcon(CryptoCurrency currency) { + try { + if (currency.chainIconPath != null) { + return currency.chainIconPath!; + } + + if ((currency.tag ?? "").isNotEmpty) { + final currencyFromTag = CryptoCurrency.fromString(currency.tag!); + if (currencyFromTag.chainIconPath != null) { + return currencyFromTag.chainIconPath!; + } + } + } catch (_) {} + + return ""; + } } diff --git a/lib/new-ui/widgets/coins_page/cards/balance_card.dart b/lib/new-ui/widgets/coins_page/cards/balance_card.dart index b39b3f481..714fc5cc3 100644 --- a/lib/new-ui/widgets/coins_page/cards/balance_card.dart +++ b/lib/new-ui/widgets/coins_page/cards/balance_card.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; import 'package:cw_core/card_design.dart'; import 'package:flutter/material.dart'; @@ -25,11 +26,13 @@ class BalanceCard extends StatelessWidget { this.balance = "", this.fiatBalance = "", this.assetName = "", + this.fiatCurrencyTitle = "", this.designSwitchDuration = const Duration(), this.actions = const [], this.capitalizeAssetName = true, this.onCustomizeTapped, - this.accountIndex + this.accountIndex, + this.fiatFirst = false }); final double width; @@ -39,6 +42,8 @@ class BalanceCard extends StatelessWidget { final String accountName; final String balance; final String fiatBalance; + final String fiatCurrencyTitle; + final bool fiatFirst; final int? accountIndex; final bool capitalizeAssetName; final String assetName; @@ -53,14 +58,21 @@ class BalanceCard extends StatelessWidget { final Duration textFadeDuration = Duration(milliseconds: 80); final double iconWidth = width * 0.15; + final name = fiatFirst ? fiatCurrencyTitle : assetName; + final resolvedAssetName = capitalizeAssetName ? name.toUpperCase() : name.toLowerCase(); + + final leadText = fiatFirst ? S.of(context).wallet_balance : accountName; + final bool showText = accountBalance.isNotEmpty || - accountName.isNotEmpty || + leadText.isNotEmpty || balance.isNotEmpty || fiatBalance.isNotEmpty || - assetName.isNotEmpty; + resolvedAssetName.isNotEmpty; final height = width * 0.62; + + return AnimatedContainer( duration: designSwitchDuration, width: width, @@ -105,7 +117,7 @@ class BalanceCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ - if(accountName.isNotEmpty || accountBalance.isNotEmpty) + if(leadText.isNotEmpty || accountBalance.isNotEmpty) Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -127,8 +139,8 @@ class BalanceCard extends StatelessWidget { AnimatedDefaultTextStyle( duration: designSwitchDuration, style: Theme.of(context).textTheme.titleMedium!.copyWith( - fontWeight: FontWeight.w500, color: design.colors.textColor), - child: Text(accountName), + fontWeight: FontWeight.w500, color: design.colors.textColor.withAlpha(leadText == accountName ? 255 : 128)), + child: Text(leadText), ), ], ), @@ -157,7 +169,7 @@ class BalanceCard extends StatelessWidget { ); }, child: Row( - key: ValueKey("$balance ${assetName.toUpperCase()}"), + key: ValueKey("$balance ${resolvedAssetName.toUpperCase()}"), spacing: 8.0, children: [ AnimatedDefaultTextStyle( @@ -165,14 +177,14 @@ class BalanceCard extends StatelessWidget { style: DefaultTextStyle.of(context) .style .copyWith(color: design.colors.textColor, fontSize: 28, fontWeight: FontWeight.w500, letterSpacing: -0.4), - child: Text(balance), + child: Text(fiatFirst ? fiatBalance : balance), ), AnimatedDefaultTextStyle( duration: designSwitchDuration, style: DefaultTextStyle.of(context) .style .copyWith(color: design.colors.textColorSecondary, fontSize: 28, fontWeight: FontWeight.w400, letterSpacing: -0.4), - child: Text(capitalizeAssetName ? assetName.toUpperCase() : assetName.toLowerCase()), + child: Text(resolvedAssetName), ), ], ), @@ -196,8 +208,8 @@ class BalanceCard extends StatelessWidget { ); }, child: Text( - key: ValueKey(fiatBalance), - fiatBalance, + key: ValueKey(fiatFirst ? balance : fiatBalance), + fiatFirst ? "$assetName $balance" : "$fiatCurrencyTitle $fiatBalance", ), ), ), diff --git a/lib/new-ui/widgets/coins_page/cards/cards_view.dart b/lib/new-ui/widgets/coins_page/cards/cards_view.dart index 67066b41b..2c36d635a 100644 --- a/lib/new-ui/widgets/coins_page/cards/cards_view.dart +++ b/lib/new-ui/widgets/coins_page/cards/cards_view.dart @@ -115,8 +115,7 @@ class _CardsViewState extends State { // The second balance should always be the lightning balance // printV(widget.dashboardViewModel.balanceViewModel.formattedBalances.first.availableBalance); - final walletBalanceRecord = widget.dashboardViewModel.balanceViewModel.formattedBalances - .elementAtOrNull(widget.lightningMode ? 1 : 0); + final walletBalanceRecord = widget.dashboardViewModel.balanceViewModel.getMainBalanceRecord(widget.lightningMode); late final String walletBalance; late final String walletFiatBalance; @@ -128,11 +127,16 @@ class _CardsViewState extends State { walletBalance = walletBalanceRecord?.combinedAvailableBalance ?? "0"; walletFiatBalance = walletBalanceRecord?.combinedFiatAvailableBalance ?? "0.00"; } - } else { + } else if(widget.dashboardViewModel.balanceViewModel.showCombinedBalance){ + walletBalance = ""; + walletFiatBalance = widget.dashboardViewModel.balanceViewModel.combinedFiatBalance; + + }else { walletBalance = walletBalanceRecord?.availableBalance ?? "0"; - walletFiatBalance = walletBalanceRecord?.fiatAvailableBalance ?? "${widget.dashboardViewModel.appStore.settingsStore.fiatCurrency.title} 0.00"; + walletFiatBalance = walletBalanceRecord?.fiatAvailableBalanceRaw ?? "0.00"; } + // the card designs is empty if widget gets built before it loads. // should get populated before user sees anything final CardDesign cardDesign; @@ -154,6 +158,8 @@ class _CardsViewState extends State { accountBalance = account.balance ?? "0.00"; } + final assetName = widget.dashboardViewModel.balanceViewModel.showCombinedBalance ? "" : walletBalanceRecord?.formattedAssetTitle ?? assetTitleFallback; + final List actions = widget.lightningMode ? [ BalanceCardAction( @@ -183,9 +189,11 @@ class _CardsViewState extends State { accountName: accountName, accountBalance: accountBalance, designSwitchDuration: Duration(milliseconds: 150), - assetName: walletBalanceRecord?.formattedAssetTitle ?? assetTitleFallback, + assetName: assetName, capitalizeAssetName: _shouldCapitalizeAssetName(), balance: walletBalance, + fiatCurrencyTitle: walletBalanceRecord?.fiatCurrencyTicker ?? widget.dashboardViewModel.settingsStore.fiatCurrency.title, + fiatFirst: widget.dashboardViewModel.balanceViewModel.showCombinedBalance, fiatBalance: walletFiatBalance, selected: _selectedIndex == visualIndex, onCustomizeTapped: _selectedIndex == visualIndex ? widget.onCustomizeTapped : null, diff --git a/lib/new-ui/widgets/receive_page/receive_top_bar.dart b/lib/new-ui/widgets/receive_page/receive_top_bar.dart index 9de76d6e1..b41eb9c20 100644 --- a/lib/new-ui/widgets/receive_page/receive_top_bar.dart +++ b/lib/new-ui/widgets/receive_page/receive_top_bar.dart @@ -12,6 +12,7 @@ class ModalTopBar extends StatelessWidget { this.onTrailingPressed=nothing, this.leadingIcon, this.trailingIcon, + this.padding, this.leadingWidget, this.trailingWidget}) { if(leadingIcon != null && leadingWidget != null) { @@ -27,6 +28,7 @@ class ModalTopBar extends StatelessWidget { final VoidCallback onLeadingPressed; final VoidCallback onTrailingPressed; final Widget? leadingIcon; + final EdgeInsets? padding; final Widget? trailingIcon; final Widget? leadingWidget; final Widget? trailingWidget; @@ -36,7 +38,7 @@ class ModalTopBar extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.all(18), + padding: padding??EdgeInsets.all(18), child: Stack( alignment: Alignment.topCenter, children: [ diff --git a/lib/src/screens/dashboard/favorite_token_modal.dart b/lib/src/screens/dashboard/favorite_token_modal.dart new file mode 100644 index 000000000..c884c6bbc --- /dev/null +++ b/lib/src/screens/dashboard/favorite_token_modal.dart @@ -0,0 +1,61 @@ +import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; +import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart'; +import 'package:cw_core/crypto_currency.dart'; +import 'package:flutter/material.dart'; + +class FavoriteTokenModal extends StatelessWidget { + const FavoriteTokenModal({super.key, required this.tokens}); + + final List tokens; + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: BorderRadius.vertical(top: Radius.circular(18)) + ), + child: SafeArea( + child: Column( + children: [ + ModalTopBar( + title: S.of(context).favorite_token, + leadingIcon: Icon(Icons.close), + onLeadingPressed: Navigator.of(context).pop, + ), + Expanded( + child: Column( + children: [ + Text( + S.of(context).favorite_token_desc, + style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(12.0), + child: SingleChildScrollView( + child: NewListSections( + sections: { + "": tokens + .map((item) => ListItemRegularRow( + keyValue: item.title, + label: "${item.fullName} (${item.title})", + iconPath: item.iconPath, + onTap: () => Navigator.of(context).pop(item))) + .toList() + }, + ), + ), + ), + ) + ], + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/src/screens/dashboard/home_settings_page.dart b/lib/src/screens/dashboard/home_settings_page.dart index d1067ceff..767423f48 100644 --- a/lib/src/screens/dashboard/home_settings_page.dart +++ b/lib/src/screens/dashboard/home_settings_page.dart @@ -1,14 +1,23 @@ import 'dart:math'; import 'package:cake_wallet/core/address_validator.dart'; +import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart'; +import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_toggle.dart'; import 'package:cake_wallet/entities/sort_balance_types.dart'; import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/new-ui/pages/settings_page.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:cake_wallet/src/screens/dashboard/favorite_token_modal.dart'; +import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; +import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart'; +import 'package:cake_wallet/src/widgets/picker.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; +import 'package:cw_core/crypto_currency.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart'; @@ -28,24 +37,79 @@ class HomeSettingsPage extends BasePage { return SingleChildScrollView( child: Column( children: [ - Observer( - builder: (_) => SettingsPickerCell( - title: S.current.sort_by, - items: SortBalanceBy.values, - selectedItem: _homeSettingsViewModel.sortBalanceBy, - onItemSelected: _homeSettingsViewModel.setSortBalanceBy, - ), - ), + // Observer( + // builder: (_) => SettingsPickerCell( + // title: S.current.sort_by, + // items: SortBalanceBy.values, + // selectedItem: _homeSettingsViewModel.sortBalanceBy, + // onItemSelected: _homeSettingsViewModel.setSortBalanceBy, + // ), + // ), // Divider(color: Theme.of(context).colorScheme.outlineVariant), // Observer( // builder: (_) => SettingsSwitcherCell( - // title: S.of(context).pin_at_top(_homeSettingsViewModel.nativeToken.title), - // value: _homeSettingsViewModel.pinNativeToken, + // title: S.of(context).show_combined_balance, + // value: _homeSettingsViewModel.showCombinedBalance, // onValueChange: (_, bool value) { - // _homeSettingsViewModel.setPinNativeToken(value); + // _homeSettingsViewModel.setShowCombinedBalance(value); // }, // ), // ), + // Observer( + // builder: (_) => _homeSettingsViewModel.showCombinedBalance + // ? SizedBox.shrink() + // : SettingsCellWithArrow( + // title: S.of(context).favorite_token, + // handler: (context) async { + // + // }, + // )), + Padding( + padding: const EdgeInsets.all(12.0), + child: Observer( + builder: (_) => NewListSections(sections: { + "": [ + ListItemRegularRow( + keyValue: "sort balance by", + label: S.of(context).sort_by, + trailingText: _homeSettingsViewModel.sortBalanceBy.toString(), + onTap: () { + showPopUp( + context: context, + builder: (context) => Picker( + items: SortBalanceBy.values, + selectedAtIndex: + SortBalanceBy.values.indexOf(_homeSettingsViewModel.sortBalanceBy), + mainAxisAlignment: MainAxisAlignment.start, + onItemSelected: _homeSettingsViewModel.setSortBalanceBy, + isSeparated: false, + ), + ); + }), + ListItemToggle( + keyValue: "show combined", + label: S.of(context).show_combined_balance, + value: _homeSettingsViewModel.showCombinedBalance, + onChanged: (val) => _homeSettingsViewModel.setShowCombinedBalance(val)), + if (!_homeSettingsViewModel.showCombinedBalance) + ListItemRegularRow( + keyValue: "fav token", + label: S.of(context).favorite_token, + trailingText: _homeSettingsViewModel.favoriteToken.title, + showArrow: true, + onTap: () async { + final res = await showModalBottomSheet( + context: context, + builder: (context) => + FavoriteTokenModal(tokens: _homeSettingsViewModel.enabledTokens)); + if (res != null && res is CryptoCurrency) { + _homeSettingsViewModel.setFavoriteToken(res); + } + }) + ] + }), + ), + ), Divider(color: Theme.of(context).colorScheme.outlineVariant), const SizedBox(height: 20), Row( diff --git a/lib/utils/token_utilities.dart b/lib/utils/token_utilities.dart index 32ef710fd..4cda4a728 100644 --- a/lib/utils/token_utilities.dart +++ b/lib/utils/token_utilities.dart @@ -152,6 +152,7 @@ class TokenUtilities { required WalletType walletType, required String address, }) async { + if(address.isEmpty) return null; final lower = address.toLowerCase(); switch (walletType) { case WalletType.ethereum: diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart index b51a0bc15..0e9d72be8 100644 --- a/lib/view_model/dashboard/balance_view_model.dart +++ b/lib/view_model/dashboard/balance_view_model.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart'; +import 'package:cake_wallet/core/utilities.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/calculate_fiat_amount.dart'; import 'package:cake_wallet/entities/fiat_api_mode.dart'; @@ -6,8 +7,12 @@ import 'package:cake_wallet/entities/sort_balance_types.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/reactions/wallet_connect.dart'; import 'package:cake_wallet/evm/evm.dart'; +import 'package:cake_wallet/solana/solana.dart'; +import 'package:cake_wallet/tron/tron.dart'; +import 'package:cake_wallet/zano/zano.dart'; import 'package:cw_core/crypto_amount_format.dart'; import 'package:cw_core/transaction_history.dart'; +import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart'; @@ -57,11 +62,16 @@ class BalanceRecord { .toString().withMaxDecimals(8); String get combinedFiatAvailableBalance => - fiatAvailableBalance.split(" ").first + + fiatCurrencyTicker + " " + - ((double.tryParse(fiatAvailableBalance.split(" ").last) ?? 0) + - (double.tryParse(fiatSecondAvailableBalance.split(" ").last) ?? 0)) - .toString().withMaxDecimals(8); + ((double.tryParse(fiatAvailableBalanceRaw) ?? 0) + + (double.tryParse(fiatSecondAvailableBalanceRaw) ?? 0)) + .toString() + .withMaxDecimals(8); + + String get fiatAvailableBalanceRaw => fiatAvailableBalance.split(" ").last; + String get fiatSecondAvailableBalanceRaw => fiatSecondAvailableBalance.split(" ").last; + String get fiatCurrencyTicker => fiatAvailableBalance.split(" ").first; } class BalanceViewModel = BalanceViewModelBase with _$BalanceViewModel; @@ -410,6 +420,58 @@ abstract class BalanceViewModelBase with Store { return balance; } + BalanceRecord? getMainBalanceRecord(bool lightningMode) { + if (lightningMode) { + return formattedBalances.elementAtOrNull(1); + } + + if (wallet.walletInfo.favoriteTokenAddress != null) { + return formattedBalances.firstWhereOrNull((item) => (getTokenAddressBasedOnWallet(item.asset) == + wallet.walletInfo.favoriteTokenAddress)) ?? + formattedBalances.elementAt(0); + } + + return formattedBalances.elementAt(0); + } + + String? getTokenAddressBasedOnWallet(CryptoCurrency asset) { + if (wallet.type == WalletType.tron) { + return tron!.getTokenAddress(asset); + } + + if (wallet.type == WalletType.solana) { + return solana!.getTokenAddress(asset); + } + + if (isEVMCompatibleChain(wallet.type) && asset is Erc20Token) { + return evm!.getTokenAddress(asset); + } + + if (wallet.type == WalletType.zano) { + return zano!.getZanoAssetAddress(asset); + } + + return null; + } + + @computed + bool get showCombinedBalance { + if(wallet.type == WalletType.bitcoin) return false; + if(balances.values.length == 1) return false; + + return wallet.walletInfo.showCombinedBalance; + } + + @computed + String get combinedFiatBalance { + double ret = 0.0; + for(final record in balances.values) { + ret += double.tryParse(record.fiatAvailableBalanceRaw) ?? 0; + } + return ret.toStringAsFixed(2); + } + + Balance _currencyBalance(CryptoCurrency cryptoCurrency) { final balance = wallet.balance[cryptoCurrency]; diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 9a3d1f54a..07146a8aa 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -23,6 +23,7 @@ import 'package:cake_wallet/store/dashboard/order_filter_store.dart'; import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/zcash/zcash.dart'; +import 'package:cw_core/transaction_direction.dart'; import 'package:cw_core/utils/proxy_wrapper.dart'; import 'package:cake_wallet/utils/tor.dart'; import 'package:cake_wallet/wownero/wownero.dart' as wow; @@ -481,18 +482,29 @@ abstract class DashboardViewModelBase with Store { } // printV("Transaction disposer callback (relevantTxs: ${relevantTxs.length} current: ${transactions.length})"); + String _txIdentityString(String txHash, TransactionDirection direction) => '${txHash}_$direction'; + + final existingKeys = transactions + .map((item) => _txIdentityString(item.transaction.txHash, item.transaction.direction)) + .toSet(); + final newTransactions = relevantTxs + .where((tx) => !existingKeys.contains(_txIdentityString(tx.txHash, tx.direction))) .map((tx) => TransactionListItem( transaction: tx, balanceViewModel: balanceViewModel, appStore: appStore, key: ValueKey('${wallet.type.name}_transaction_history_item_${tx.id}_key'), )) - .where((item) => !transactions.contains(item)); + .toList(); - transactions.removeWhere((item) => newTransactions.any((tx) => - tx.transaction.txHash == item.transaction.txHash && - tx.transaction.direction == item.transaction.direction)); + final newKeys = newTransactions + .map((item) => _txIdentityString(item.transaction.txHash, item.transaction.direction)) + .toSet(); + + transactions.removeWhere( + (item) => newKeys.contains(_txIdentityString(item.transaction.txHash, item.transaction.direction)), + ); transactions.addAll(newTransactions); // transactions.clear(); diff --git a/lib/view_model/dashboard/home_settings_view_model.dart b/lib/view_model/dashboard/home_settings_view_model.dart index 1192bbba9..4fdbec112 100644 --- a/lib/view_model/dashboard/home_settings_view_model.dart +++ b/lib/view_model/dashboard/home_settings_view_model.dart @@ -9,6 +9,7 @@ import 'package:cake_wallet/reactions/wallet_connect.dart'; import 'package:cake_wallet/solana/solana.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/tron/tron.dart'; +import 'package:cake_wallet/utils/token_utilities.dart'; import 'package:cw_core/utils/proxy_wrapper.dart'; import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; import 'package:cake_wallet/zano/zano.dart'; @@ -29,10 +30,14 @@ abstract class HomeSettingsViewModelBase with Store { : tokens = ObservableSet(), isAddingToken = false, isDeletingToken = false, - isValidatingContractAddress = false { + isValidatingContractAddress = false, + showCombinedBalance = _balanceViewModel.wallet.walletInfo.showCombinedBalance, + favoriteToken = _balanceViewModel.wallet.currency { _updateTokensList(); + _updateLocalFavoriteToken(); - // React to wallet changes + + // React to wallet changes reaction((_) => _balanceViewModel.wallet, (_) { _updateTokensList(); }); @@ -55,6 +60,9 @@ abstract class HomeSettingsViewModelBase with Store { final ObservableSet tokens; + @computed + List get enabledTokens => [_balanceViewModel.wallet.currency, ...tokens.where((item)=>item.enabled).toList()]; + WalletType get walletType => _balanceViewModel.wallet.type; @observable @@ -491,6 +499,45 @@ abstract class HomeSettingsViewModelBase with Store { } } + + // FIXME these two observables cause duplicated state and are needed because mobx. remove them as part of the refactor and replace with proper getters + @observable + bool showCombinedBalance; + + @observable + CryptoCurrency favoriteToken; + + @action + void setShowCombinedBalance(bool value) { + _balanceViewModel.wallet.walletInfo.showCombinedBalance = value; + showCombinedBalance = value; + _balanceViewModel.wallet.updateBalance(); + _balanceViewModel.wallet.walletInfo.save(); + } + + @action + Future setFavoriteToken(CryptoCurrency token) async { + final String? address; + + if(token == _balanceViewModel.wallet.currency) { + address = null; + } else { + address = getTokenAddressBasedOnWallet(token); + } + + _balanceViewModel.wallet.walletInfo.favoriteTokenAddress = address; + _balanceViewModel.wallet.walletInfo.save(); + _updateLocalFavoriteToken(); + } + + @action + Future _updateLocalFavoriteToken() async { + favoriteToken = await TokenUtilities.findTokenByAddress( + walletType: _balanceViewModel.wallet.type, address: _balanceViewModel.wallet.walletInfo.favoriteTokenAddress ?? "") ?? + _balanceViewModel.wallet.currency; + } + + @action void _refreshTokensList() { final _tokens = Set.of(tokens); diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 23e6d4079..ff54ecaaf 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -282,6 +282,7 @@ flutter: - assets/new-ui/navbar/ - assets/new-ui/changelog/icons/ - assets/new-ui/changelog/text/ + - assets/new-ui/crypto_full_icons/ fonts: - family: Lato diff --git a/res/pictures/chain_badges/lightning.svg b/res/pictures/chain_badges/lightning.svg index 85430ad66..9fd26ddef 100644 --- a/res/pictures/chain_badges/lightning.svg +++ b/res/pictures/chain_badges/lightning.svg @@ -1,6 +1,5 @@ - - - - - + + diff --git a/res/pictures/crypto_full_icons/arbitrum.svg b/res/pictures/crypto_full_icons/arbitrum.svg new file mode 100644 index 000000000..50369b820 --- /dev/null +++ b/res/pictures/crypto_full_icons/arbitrum.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/avax.svg b/res/pictures/crypto_full_icons/avax.svg new file mode 100644 index 000000000..e1c31f266 --- /dev/null +++ b/res/pictures/crypto_full_icons/avax.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/base_icon.svg b/res/pictures/crypto_full_icons/base_icon.svg new file mode 100644 index 000000000..54525f8ae --- /dev/null +++ b/res/pictures/crypto_full_icons/base_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/bitcoin-cash.svg b/res/pictures/crypto_full_icons/bitcoin-cash.svg new file mode 100644 index 000000000..77ec1bcf7 --- /dev/null +++ b/res/pictures/crypto_full_icons/bitcoin-cash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/bitcoin.svg b/res/pictures/crypto_full_icons/bitcoin.svg new file mode 100644 index 000000000..3525691c1 --- /dev/null +++ b/res/pictures/crypto_full_icons/bitcoin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/bnb.svg b/res/pictures/crypto_full_icons/bnb.svg new file mode 100644 index 000000000..eb8fcbf7b --- /dev/null +++ b/res/pictures/crypto_full_icons/bnb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/dai.svg b/res/pictures/crypto_full_icons/dai.svg new file mode 100644 index 000000000..c5f1de167 --- /dev/null +++ b/res/pictures/crypto_full_icons/dai.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/decred.svg b/res/pictures/crypto_full_icons/decred.svg new file mode 100644 index 000000000..08650d39c --- /dev/null +++ b/res/pictures/crypto_full_icons/decred.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/deuro.svg b/res/pictures/crypto_full_icons/deuro.svg new file mode 100644 index 000000000..6e95b9c42 --- /dev/null +++ b/res/pictures/crypto_full_icons/deuro.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/dogecoin.svg b/res/pictures/crypto_full_icons/dogecoin.svg new file mode 100644 index 000000000..071773786 --- /dev/null +++ b/res/pictures/crypto_full_icons/dogecoin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/ethereum.svg b/res/pictures/crypto_full_icons/ethereum.svg new file mode 100644 index 000000000..0ccdd39f8 --- /dev/null +++ b/res/pictures/crypto_full_icons/ethereum.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/lightning.svg b/res/pictures/crypto_full_icons/lightning.svg new file mode 100644 index 000000000..e2f67659e --- /dev/null +++ b/res/pictures/crypto_full_icons/lightning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/litecoin.svg b/res/pictures/crypto_full_icons/litecoin.svg new file mode 100644 index 000000000..57b9513e3 --- /dev/null +++ b/res/pictures/crypto_full_icons/litecoin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/monero.svg b/res/pictures/crypto_full_icons/monero.svg new file mode 100644 index 000000000..aae410fed --- /dev/null +++ b/res/pictures/crypto_full_icons/monero.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/nano.svg b/res/pictures/crypto_full_icons/nano.svg new file mode 100644 index 000000000..fd18e659f --- /dev/null +++ b/res/pictures/crypto_full_icons/nano.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/paxg.svg b/res/pictures/crypto_full_icons/paxg.svg new file mode 100644 index 000000000..366be7a3f --- /dev/null +++ b/res/pictures/crypto_full_icons/paxg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/polygon.svg b/res/pictures/crypto_full_icons/polygon.svg new file mode 100644 index 000000000..37ac15c25 --- /dev/null +++ b/res/pictures/crypto_full_icons/polygon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/solana.svg b/res/pictures/crypto_full_icons/solana.svg new file mode 100644 index 000000000..bee3fc724 --- /dev/null +++ b/res/pictures/crypto_full_icons/solana.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/ton.svg b/res/pictures/crypto_full_icons/ton.svg new file mode 100644 index 000000000..f682c3e2d --- /dev/null +++ b/res/pictures/crypto_full_icons/ton.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/tron.svg b/res/pictures/crypto_full_icons/tron.svg new file mode 100644 index 000000000..c743d33bf --- /dev/null +++ b/res/pictures/crypto_full_icons/tron.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/usdc.svg b/res/pictures/crypto_full_icons/usdc.svg new file mode 100644 index 000000000..9642b6b0f --- /dev/null +++ b/res/pictures/crypto_full_icons/usdc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/usde.svg b/res/pictures/crypto_full_icons/usde.svg new file mode 100644 index 000000000..ecf6bf000 --- /dev/null +++ b/res/pictures/crypto_full_icons/usde.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/usdt.svg b/res/pictures/crypto_full_icons/usdt.svg new file mode 100644 index 000000000..4905c601d --- /dev/null +++ b/res/pictures/crypto_full_icons/usdt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/wbtc.svg b/res/pictures/crypto_full_icons/wbtc.svg new file mode 100644 index 000000000..010401aed --- /dev/null +++ b/res/pictures/crypto_full_icons/wbtc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/xaut.svg b/res/pictures/crypto_full_icons/xaut.svg new file mode 100644 index 000000000..f107cfa47 --- /dev/null +++ b/res/pictures/crypto_full_icons/xaut.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/zano.svg b/res/pictures/crypto_full_icons/zano.svg new file mode 100644 index 000000000..cdc405de7 --- /dev/null +++ b/res/pictures/crypto_full_icons/zano.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/pictures/crypto_full_icons/zcash.svg b/res/pictures/crypto_full_icons/zcash.svg new file mode 100644 index 000000000..cb33117b0 --- /dev/null +++ b/res/pictures/crypto_full_icons/zcash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index ab36e1046..781e09745 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -465,6 +465,8 @@ "extracted_address_content": "You will be sending funds to\n${recipient_name}", "failed_authentication": "Failed authentication. ${state_error}", "faq": "FAQ", + "favorite_token": "Favorite token", + "favorite_token_desc": "The favorite token's balance will show on the balance card.", "features": "Features", "fee": "Fee", "fee_less_than_min": "Selected Fee is less than the minimum, please increase the fees to be able to send the transaction", @@ -1023,6 +1025,7 @@ "show_balance": "Long Press to Show Balance", "show_balance_send_page": "Tap to reveal", "show_balance_toast": "Long press to hide or show balance", + "show_combined_balance": "Show combined balance", "show_details": "Show Details", "show_hidden_addresses": "Show hidden addresses", "show_keys": "Show seed/keys", @@ -1292,6 +1295,7 @@ "waitFewSecondForTxUpdate": "Kindly wait for a few seconds for transaction to reflect in transactions history", "wallet": "Wallet", "wallet_accounts": "Wallet Accounts", + "wallet_balance": "Wallet Balance", "wallet_group": "Wallet Group", "wallet_group_description_existing_seed": "You’ve chosen to use an existing seed for this wallet. You may verify the seed again if you need to confirm or write it down.", "wallet_group_description_four": "to create a wallet with an entirely new seed.",