mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-23 06:38:35 +02:00
CW-555-Add-Solana-Wallet (#1272)
* chore: Create cw_solana package and clean up files * feat: Add Solana Wallet - Create, Restore form seed, restore from Key, Restore from QR, Send, Receive, transaction history, spl tokens * fix: Make transactions file specific to solana only for solana transactions * chore: Revert inject app details script * fix: Fix issue with node and switch current node to main beta instead of testnet * fix: Fix merge conflicts and adjust migration version * fix: Fetch spl token error Signed-off-by: Blazebrain <davidadegoke16@gmail.com> * fix: Diplay and activate spl tokens bug * fix: Review and fixes * fix: reverted formatting for cryptocurrency class * fix: Review comments, split sending flow into signing and sending separately, fix issues * fix: Revert throwing unimplenented error * chore: Fix comment * chore: Fix comment * fix: Errors in flow * Update provider_types.dart [skip ci] * fix: Issues with solana wallet * Update solana_wallet.dart [skip ci] * fix: Review comments * fix: Date time config * fix: Revert bash script for app details * fix: Error with balance, displaying fees, fixing sent or received identifier bug, displaying token symbol with token transaction item in transactions list * fix: Issues with address validation when sending spl tokens and walletconnect initial setup * fix: Issues with sending, fetching transactions history, almost wrapping up walletconnect * fix: Adjust imports that would affect monerocom building successfully * fix: Refine transaction direction and continue work on walletconnect * feat: Display SPL token transfers in the transaction history and finally settle the transaction direction * fix: Delay in transactions history dispaly, show native token transactions first, then process spl token transactions * feat: Switch node and revert solana chain id to previous id * fix: Remove print statement * fix: Remove await for transactions, fetch all transaction histories instantly and adjust solana send success message * chore: Code refactoring and streamlined wallet type check for solana send success message * fix: Make timeout error for node silent and add spl token images --------- Signed-off-by: Blazebrain <davidadegoke16@gmail.com> Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
co-authored by
Omar Hatem
parent
5a7ea87543
commit
109bba4301
@@ -37,6 +37,7 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
|
||||
final bitcoinCashIcon = Image.asset('assets/images/bch_icon.png', height: 24, width: 24);
|
||||
final nanoIcon = Image.asset('assets/images/nano_icon.png', height: 24, width: 24);
|
||||
final bananoIcon = Image.asset('assets/images/nano_icon.png', height: 24, width: 24);
|
||||
final solanaIcon = Image.asset('assets/images/sol_icon.png', height: 24, width: 24);
|
||||
final nonWalletTypeIcon = Image.asset('assets/images/close.png', height: 24, width: 24);
|
||||
|
||||
Image _newWalletImage(BuildContext context) => Image.asset(
|
||||
@@ -153,6 +154,8 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
|
||||
return bananoIcon;
|
||||
case WalletType.polygon:
|
||||
return polygonIcon;
|
||||
case WalletType.solana:
|
||||
return solanaIcon;
|
||||
default:
|
||||
return nonWalletTypeIcon;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/erc20_token.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -16,12 +17,12 @@ class EditTokenPage extends BasePage {
|
||||
EditTokenPage({
|
||||
Key? key,
|
||||
required this.homeSettingsViewModel,
|
||||
this.erc20token,
|
||||
this.token,
|
||||
this.initialContractAddress,
|
||||
}) : assert(erc20token == null || initialContractAddress == null);
|
||||
}) : assert(token == null || initialContractAddress == null);
|
||||
|
||||
final HomeSettingsViewModel homeSettingsViewModel;
|
||||
final Erc20Token? erc20token;
|
||||
final CryptoCurrency? token;
|
||||
final String? initialContractAddress;
|
||||
|
||||
@override
|
||||
@@ -31,7 +32,7 @@ class EditTokenPage extends BasePage {
|
||||
Widget body(BuildContext context) {
|
||||
return EditTokenPageBody(
|
||||
homeSettingsViewModel: homeSettingsViewModel,
|
||||
erc20token: erc20token,
|
||||
token: token,
|
||||
initialContractAddress: initialContractAddress,
|
||||
);
|
||||
}
|
||||
@@ -41,12 +42,12 @@ class EditTokenPageBody extends StatefulWidget {
|
||||
const EditTokenPageBody({
|
||||
Key? key,
|
||||
required this.homeSettingsViewModel,
|
||||
this.erc20token,
|
||||
this.token,
|
||||
this.initialContractAddress,
|
||||
}) : super(key: key);
|
||||
|
||||
final HomeSettingsViewModel homeSettingsViewModel;
|
||||
final Erc20Token? erc20token;
|
||||
final CryptoCurrency? token;
|
||||
final String? initialContractAddress;
|
||||
|
||||
@override
|
||||
@@ -73,11 +74,15 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (widget.erc20token != null) {
|
||||
_contractAddressController.text = widget.erc20token!.contractAddress;
|
||||
_tokenNameController.text = widget.erc20token!.name;
|
||||
_tokenSymbolController.text = widget.erc20token!.symbol;
|
||||
_tokenDecimalController.text = widget.erc20token!.decimal.toString();
|
||||
String? address;
|
||||
|
||||
if (widget.token != null) {
|
||||
address = widget.homeSettingsViewModel.getTokenAddressBasedOnWallet(widget.token!);
|
||||
|
||||
_contractAddressController.text = address ?? '';
|
||||
_tokenNameController.text = widget.token!.name;
|
||||
_tokenSymbolController.text = widget.token!.title;
|
||||
_tokenDecimalController.text = widget.token!.decimals.toString();
|
||||
}
|
||||
|
||||
if (widget.initialContractAddress != null) {
|
||||
@@ -91,7 +96,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||
}
|
||||
|
||||
final contractAddress = _contractAddressController.text;
|
||||
if (contractAddress.isNotEmpty && contractAddress != widget.erc20token?.contractAddress) {
|
||||
if (contractAddress.isNotEmpty && contractAddress != address) {
|
||||
setState(() {
|
||||
_showDisclaimer = true;
|
||||
});
|
||||
@@ -139,7 +144,9 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
|
||||
color: Theme.of(context)
|
||||
.extension<TransactionTradeTheme>()!
|
||||
.detailsTitlesColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -172,12 +179,12 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
onPressed: () async {
|
||||
if (widget.erc20token != null) {
|
||||
await widget.homeSettingsViewModel.deleteErc20Token(widget.erc20token!);
|
||||
if (widget.token != null) {
|
||||
await widget.homeSettingsViewModel.deleteToken(widget.token!);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
},
|
||||
text: widget.erc20token != null ? S.of(context).delete : S.of(context).cancel,
|
||||
text: widget.token != null ? S.of(context).delete : S.of(context).cancel,
|
||||
color: Colors.red,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
@@ -188,7 +195,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState!.validate() &&
|
||||
(!_showDisclaimer || _disclaimerChecked)) {
|
||||
await widget.homeSettingsViewModel.addErc20Token(Erc20Token(
|
||||
await widget.homeSettingsViewModel.addToken(Erc20Token(
|
||||
name: _tokenNameController.text,
|
||||
symbol: _tokenSymbolController.text,
|
||||
contractAddress: _contractAddressController.text,
|
||||
@@ -214,14 +221,13 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||
|
||||
void _getTokenInfo() async {
|
||||
if (_contractAddressController.text.isNotEmpty) {
|
||||
final token =
|
||||
await widget.homeSettingsViewModel.getErc20Token(_contractAddressController.text);
|
||||
final token = await widget.homeSettingsViewModel.getToken(_contractAddressController.text);
|
||||
|
||||
if (token != null) {
|
||||
if (_tokenNameController.text.isEmpty) _tokenNameController.text = token.name;
|
||||
if (_tokenSymbolController.text.isEmpty) _tokenSymbolController.text = token.symbol;
|
||||
if (_tokenSymbolController.text.isEmpty) _tokenSymbolController.text = token.title;
|
||||
if (_tokenDecimalController.text.isEmpty)
|
||||
_tokenDecimalController.text = token.decimal.toString();
|
||||
_tokenDecimalController.text = token.decimals.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:cake_wallet/entities/sort_balance_types.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.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/themes/extensions/address_theme.dart';
|
||||
@@ -117,7 +118,7 @@ class HomeSettingsPage extends BasePage {
|
||||
|
||||
return SettingsSwitcherCell(
|
||||
title: "${token.name} "
|
||||
"(${token.symbol})",
|
||||
"(${token.title})",
|
||||
value: token.enabled,
|
||||
onValueChange: (_, bool value) {
|
||||
_homeSettingsViewModel.changeTokenAvailability(token, value);
|
||||
@@ -128,20 +129,16 @@ class HomeSettingsPage extends BasePage {
|
||||
'token': token,
|
||||
});
|
||||
},
|
||||
leading: token.iconPath != null
|
||||
? Container(
|
||||
child: Image.asset(
|
||||
token.iconPath!,
|
||||
height: 30.0,
|
||||
width: 30.0,
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
leading: CakeImageWidget(
|
||||
imageUrl: token.iconPath,
|
||||
height: 40,
|
||||
width: 40,
|
||||
displayOnError: Container(
|
||||
height: 30.0,
|
||||
width: 30.0,
|
||||
child: Center(
|
||||
child: Text(
|
||||
token.symbol.substring(0, min(token.symbol.length, 2)),
|
||||
token.title.substring(0, min(token.title.length, 2)),
|
||||
style: TextStyle(fontSize: 11),
|
||||
),
|
||||
),
|
||||
@@ -149,7 +146,8 @@ class HomeSettingsPage extends BasePage {
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.grey.shade400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:cake_wallet/reactions/wallet_connect.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/pages/nft_listing_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/home_screen_account_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/introducing_card.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
@@ -333,15 +334,11 @@ class BalanceRowWidget extends StatelessWidget {
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
currency.iconPath != null
|
||||
? Container(
|
||||
child: Image.asset(
|
||||
currency.iconPath!,
|
||||
height: 40.0,
|
||||
width: 40.0,
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
CakeImageWidget(
|
||||
imageUrl: currency.iconPath,
|
||||
height: 40,
|
||||
width: 40,
|
||||
displayOnError: Container(
|
||||
height: 30.0,
|
||||
width: 30.0,
|
||||
child: Center(
|
||||
@@ -355,6 +352,7 @@ class BalanceRowWidget extends StatelessWidget {
|
||||
color: Colors.grey.shade400,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
currency.title,
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:cake_wallet/entities/wallet_nft_response.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/nft_image_tile_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
@@ -94,7 +94,7 @@ class NFTDetailsPage extends BasePage {
|
||||
.syncedBackgroundColor,
|
||||
|
||||
),
|
||||
child: NFTImageWidget(
|
||||
child: CakeImageWidget(
|
||||
imageUrl: nftAsset.normalizedMetadata?.imageUrl,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -18,23 +18,23 @@ class MenuWidget extends StatefulWidget {
|
||||
|
||||
class MenuWidgetState extends State<MenuWidget> {
|
||||
MenuWidgetState()
|
||||
: this.menuWidth = 0,
|
||||
this.screenWidth = 0,
|
||||
this.screenHeight = 0,
|
||||
this.headerHeight = 120,
|
||||
this.tileHeight = 60,
|
||||
this.fromTopEdge = 50,
|
||||
this.fromBottomEdge = 25,
|
||||
this.moneroIcon = Image.asset('assets/images/monero_menu.png'),
|
||||
this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'),
|
||||
this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'),
|
||||
this.havenIcon = Image.asset('assets/images/haven_menu.png'),
|
||||
this.ethereumIcon = Image.asset('assets/images/eth_icon.png'),
|
||||
this.nanoIcon = Image.asset('assets/images/nano_icon.png'),
|
||||
this.bananoIcon = Image.asset('assets/images/nano_icon.png'),
|
||||
: this.menuWidth = 0,
|
||||
this.screenWidth = 0,
|
||||
this.screenHeight = 0,
|
||||
this.headerHeight = 120,
|
||||
this.tileHeight = 60,
|
||||
this.fromTopEdge = 50,
|
||||
this.fromBottomEdge = 25,
|
||||
this.moneroIcon = Image.asset('assets/images/monero_menu.png'),
|
||||
this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'),
|
||||
this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'),
|
||||
this.havenIcon = Image.asset('assets/images/haven_menu.png'),
|
||||
this.ethereumIcon = Image.asset('assets/images/eth_icon.png'),
|
||||
this.nanoIcon = Image.asset('assets/images/nano_icon.png'),
|
||||
this.bananoIcon = Image.asset('assets/images/nano_icon.png'),
|
||||
this.bitcoinCashIcon = Image.asset('assets/images/bch_icon.png'),
|
||||
this.polygonIcon = Image.asset('assets/images/matic_icon.png');
|
||||
|
||||
this.polygonIcon = Image.asset('assets/images/matic_icon.png'),
|
||||
this.solanaIcon = Image.asset('assets/images/sol_icon.png');
|
||||
|
||||
final largeScreen = 731;
|
||||
|
||||
@@ -56,7 +56,7 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
Image nanoIcon;
|
||||
Image bananoIcon;
|
||||
Image polygonIcon;
|
||||
|
||||
Image solanaIcon;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -224,6 +224,8 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
return bananoIcon;
|
||||
case WalletType.polygon:
|
||||
return polygonIcon;
|
||||
case WalletType.solana:
|
||||
return solanaIcon;
|
||||
default:
|
||||
throw Exception('No icon for ${type.toString()}');
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import 'package:cake_wallet/entities/wallet_nft_response.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/nft_image_tile_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NFTTileWidget extends StatelessWidget {
|
||||
@@ -38,7 +37,7 @@ class NFTTileWidget extends StatelessWidget {
|
||||
),
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
||||
),
|
||||
child: NFTImageWidget(
|
||||
child: CakeImageWidget(
|
||||
imageUrl: nftAsset.normalizedMetadata?.imageUrl,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -14,6 +14,7 @@ import 'package:cake_wallet/utils/payment_request.dart';
|
||||
import 'package:cake_wallet/utils/request_review_handler.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
@@ -439,10 +440,17 @@ class SendPage extends BasePage {
|
||||
}
|
||||
|
||||
if (state is TransactionCommitted) {
|
||||
String alertContent;
|
||||
if (sendViewModel.walletType == WalletType.solana) {
|
||||
alertContent =
|
||||
'${S.of(_dialogContext).send_success(sendViewModel.selectedCryptoCurrency.toString())}. ${S.of(_dialogContext).waitFewSecondForTxUpdate}';
|
||||
} else {
|
||||
alertContent = S.of(_dialogContext).send_success(
|
||||
sendViewModel.selectedCryptoCurrency.toString());
|
||||
}
|
||||
return AlertWithOneAction(
|
||||
alertTitle: '',
|
||||
alertContent: S.of(_dialogContext).send_success(
|
||||
sendViewModel.selectedCryptoCurrency.toString()),
|
||||
alertContent: alertContent,
|
||||
buttonText: S.of(_dialogContext).ok,
|
||||
buttonAction: () {
|
||||
Navigator.of(_dialogContext).pop();
|
||||
|
||||
@@ -321,7 +321,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
|
||||
? sendViewModel.allAmountValidator
|
||||
: sendViewModel.amountValidator,
|
||||
),
|
||||
if (!sendViewModel.isBatchSending)
|
||||
if (!sendViewModel.isBatchSending && sendViewModel.shouldDisplaySendALL)
|
||||
Positioned(
|
||||
top: 2,
|
||||
right: 0,
|
||||
|
||||
@@ -107,7 +107,7 @@ class ConnectionSyncPage extends BasePage {
|
||||
);
|
||||
},
|
||||
),
|
||||
if (isEVMCompatibleChain(dashboardViewModel.wallet.type)) ...[
|
||||
if (isWalletConnectCompatibleChain(dashboardViewModel.wallet.type)) ...[
|
||||
WalletConnectTile(
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.walletConnectConnectionsListing),
|
||||
),
|
||||
|
||||
@@ -26,7 +26,7 @@ class OtherSettingsPage extends BasePage {
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
if (!_otherSettingsViewModel.changeRepresentativeEnabled)
|
||||
if (_otherSettingsViewModel.displayTransactionPriority)
|
||||
SettingsPickerCell(
|
||||
title: S.current.settings_fee_priority,
|
||||
items: priorityForWalletType(_otherSettingsViewModel.walletType),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -26,12 +27,11 @@ class PairingItemWidget extends StatelessWidget {
|
||||
'$year-${month.toString().padLeft(2, '0')}-${day.toString().padLeft(2, '0')}';
|
||||
|
||||
return ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage: (metadata.icons.isNotEmpty
|
||||
? NetworkImage(metadata.icons[0])
|
||||
: const AssetImage(
|
||||
'assets/images/default_icon.png',
|
||||
)) as ImageProvider<Object>,
|
||||
leading: CakeImageWidget(
|
||||
imageUrl: metadata.icons.isNotEmpty ? metadata.icons[0]: null,
|
||||
displayOnError: CircleAvatar(
|
||||
backgroundImage: AssetImage('assets/images/default_icon.png'),
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
metadata.name,
|
||||
|
||||
@@ -103,6 +103,7 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
final bitcoinCashIcon = Image.asset('assets/images/bch_icon.png', height: 24, width: 24);
|
||||
final nanoIcon = Image.asset('assets/images/nano_icon.png', height: 24, width: 24);
|
||||
final polygonIcon = Image.asset('assets/images/matic_icon.png', height: 24, width: 24);
|
||||
final solanaIcon = Image.asset('assets/images/sol_icon.png', height: 24, width: 24);
|
||||
final scrollController = ScrollController();
|
||||
final double tileHeight = 60;
|
||||
Flushbar<void>? _progressBar;
|
||||
@@ -313,6 +314,8 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
return nanoIcon;
|
||||
case WalletType.polygon:
|
||||
return polygonIcon;
|
||||
case WalletType.solana:
|
||||
return solanaIcon;
|
||||
default:
|
||||
return nonWalletTypeIcon;
|
||||
}
|
||||
|
||||
+26
-6
@@ -2,25 +2,45 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class NFTImageWidget extends StatelessWidget {
|
||||
const NFTImageWidget({
|
||||
class CakeImageWidget extends StatelessWidget {
|
||||
CakeImageWidget({
|
||||
required this.imageUrl,
|
||||
});
|
||||
Widget? displayOnError,
|
||||
this.height,
|
||||
this.width,
|
||||
}) : _displayOnError = displayOnError ?? Icon(Icons.error);
|
||||
|
||||
final String? imageUrl;
|
||||
final double? height;
|
||||
final double? width;
|
||||
final Widget? _displayOnError;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
try {
|
||||
if (imageUrl == null) return Icon(Icons.error);
|
||||
if (imageUrl == null) return _displayOnError!;
|
||||
|
||||
if (imageUrl!.contains('assets/images')) {
|
||||
return Image.asset(
|
||||
imageUrl!,
|
||||
height: height,
|
||||
width: width,
|
||||
);
|
||||
}
|
||||
|
||||
if (imageUrl!.contains('.svg')) {
|
||||
return SvgPicture.network(imageUrl!);
|
||||
return SvgPicture.network(
|
||||
imageUrl!,
|
||||
height: height,
|
||||
width: width,
|
||||
);
|
||||
}
|
||||
|
||||
return Image.network(
|
||||
imageUrl!,
|
||||
fit: BoxFit.cover,
|
||||
height: height,
|
||||
width: width,
|
||||
loadingBuilder: (BuildContext _, Widget child, ImageChunkEvent? loadingProgress) {
|
||||
if (loadingProgress == null) {
|
||||
return child;
|
||||
@@ -31,7 +51,7 @@ class NFTImageWidget extends StatelessWidget {
|
||||
errorBuilder: (_, __, ___) => Icon(Icons.error),
|
||||
);
|
||||
} catch (_) {
|
||||
return Icon(Icons.error);
|
||||
return _displayOnError!;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user