mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-11 13:24:51 +00:00
- Improve sorting balances flow
- Add initial add token from search bar flow
This commit is contained in:
parent
912caea068
commit
474abe15a7
6 changed files with 78 additions and 70 deletions
|
@ -1021,10 +1021,11 @@ Future setup({
|
||||||
getIt.registerFactoryParam<HomeSettingsViewModel, BalanceViewModel, void>(
|
getIt.registerFactoryParam<HomeSettingsViewModel, BalanceViewModel, void>(
|
||||||
(balanceViewModel, _) => HomeSettingsViewModel(getIt.get<SettingsStore>(), balanceViewModel));
|
(balanceViewModel, _) => HomeSettingsViewModel(getIt.get<SettingsStore>(), balanceViewModel));
|
||||||
|
|
||||||
getIt.registerFactoryParam<EditTokenPage, HomeSettingsViewModel, Erc20Token?>(
|
getIt.registerFactoryParam<EditTokenPage, HomeSettingsViewModel, Map<String, dynamic>>(
|
||||||
(homeSettingsViewModel, token) => EditTokenPage(
|
(homeSettingsViewModel, arguments) => EditTokenPage(
|
||||||
homeSettingsViewModel: homeSettingsViewModel,
|
homeSettingsViewModel: homeSettingsViewModel,
|
||||||
erc20token: token,
|
erc20token: arguments['token'] as Erc20Token?,
|
||||||
|
initialContractAddress: arguments['contractAddress'] as String?,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -590,7 +590,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
settings: RouteSettings(name: Routes.editToken),
|
settings: RouteSettings(name: Routes.editToken),
|
||||||
builder: (_) => getIt.get<EditTokenPage>(
|
builder: (_) => getIt.get<EditTokenPage>(
|
||||||
param1: args['homeSettingsViewModel'],
|
param1: args['homeSettingsViewModel'],
|
||||||
param2: args['token'],
|
param2: {
|
||||||
|
'token': args['token'],
|
||||||
|
'contractAddress': args['contractAddress'],
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cake_wallet/core/address_validator.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
||||||
|
@ -11,10 +12,16 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class EditTokenPage extends BasePage {
|
class EditTokenPage extends BasePage {
|
||||||
EditTokenPage({Key? key, required this.homeSettingsViewModel, this.erc20token});
|
EditTokenPage({
|
||||||
|
Key? key,
|
||||||
|
required this.homeSettingsViewModel,
|
||||||
|
this.erc20token,
|
||||||
|
this.initialContractAddress,
|
||||||
|
}) : assert(erc20token == null || initialContractAddress == null);
|
||||||
|
|
||||||
final HomeSettingsViewModel homeSettingsViewModel;
|
final HomeSettingsViewModel homeSettingsViewModel;
|
||||||
final Erc20Token? erc20token;
|
final Erc20Token? erc20token;
|
||||||
|
final String? initialContractAddress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? get title => S.current.edit_token;
|
String? get title => S.current.edit_token;
|
||||||
|
@ -29,11 +36,16 @@ class EditTokenPage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditTokenPageBody extends StatefulWidget {
|
class EditTokenPageBody extends StatefulWidget {
|
||||||
const EditTokenPageBody({Key? key, required this.homeSettingsViewModel, this.erc20token})
|
const EditTokenPageBody({
|
||||||
: super(key: key);
|
Key? key,
|
||||||
|
required this.homeSettingsViewModel,
|
||||||
|
this.erc20token,
|
||||||
|
this.initialContractAddress,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final HomeSettingsViewModel homeSettingsViewModel;
|
final HomeSettingsViewModel homeSettingsViewModel;
|
||||||
final Erc20Token? erc20token;
|
final Erc20Token? erc20token;
|
||||||
|
final String? initialContractAddress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<EditTokenPageBody> createState() => _EditTokenPageBodyState();
|
State<EditTokenPageBody> createState() => _EditTokenPageBodyState();
|
||||||
|
@ -66,9 +78,14 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||||
_tokenDecimalController.text = widget.erc20token!.decimal.toString();
|
_tokenDecimalController.text = widget.erc20token!.decimal.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (widget.initialContractAddress != null) {
|
||||||
|
_contractAddressController.text = widget.initialContractAddress!;
|
||||||
|
_getTokenInfo();
|
||||||
|
}
|
||||||
|
|
||||||
_contractAddressFocusNode.addListener(() {
|
_contractAddressFocusNode.addListener(() {
|
||||||
if (!_contractAddressFocusNode.hasFocus) {
|
if (!_contractAddressFocusNode.hasFocus) {
|
||||||
_getTokenInfo(_contractAddressController.text);
|
_getTokenInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
final contractAddress = _contractAddressController.text;
|
final contractAddress = _contractAddressController.text;
|
||||||
|
@ -191,9 +208,10 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getTokenInfo(String? address) async {
|
void _getTokenInfo() async {
|
||||||
if (address?.isNotEmpty ?? false) {
|
if (_contractAddressController.text.isNotEmpty) {
|
||||||
final token = await widget.homeSettingsViewModel.getErc20Token(address!);
|
final token =
|
||||||
|
await widget.homeSettingsViewModel.getErc20Token(_contractAddressController.text);
|
||||||
|
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
if (_tokenNameController.text.isEmpty) _tokenNameController.text = token.name;
|
if (_tokenNameController.text.isEmpty) _tokenNameController.text = token.name;
|
||||||
|
@ -210,7 +228,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||||
if (value?.text?.isNotEmpty ?? false) {
|
if (value?.text?.isNotEmpty ?? false) {
|
||||||
_contractAddressController.text = value!.text!;
|
_contractAddressController.text = value!.text!;
|
||||||
|
|
||||||
_getTokenInfo(_contractAddressController.text);
|
_getTokenInfo();
|
||||||
setState(() {
|
setState(() {
|
||||||
_showDisclaimer = true;
|
_showDisclaimer = true;
|
||||||
});
|
});
|
||||||
|
@ -230,13 +248,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
||||||
placeholder: S.of(context).token_contract_address,
|
placeholder: S.of(context).token_contract_address,
|
||||||
options: [AddressTextFieldOption.paste],
|
options: [AddressTextFieldOption.paste],
|
||||||
buttonColor: Theme.of(context).hintColor,
|
buttonColor: Theme.of(context).hintColor,
|
||||||
validator: (text) {
|
validator: AddressValidator(type: widget.homeSettingsViewModel.nativeToken),
|
||||||
if (text?.isNotEmpty ?? false) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S.of(context).field_required;
|
|
||||||
},
|
|
||||||
onPushPasteButton: (_) {
|
onPushPasteButton: (_) {
|
||||||
_pasteText();
|
_pasteText();
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:cake_wallet/core/address_validator.dart';
|
||||||
import 'package:cake_wallet/entities/sort_balance_types.dart';
|
import 'package:cake_wallet/entities/sort_balance_types.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
|
@ -36,7 +37,7 @@ class HomeSettingsPage extends BasePage {
|
||||||
Divider(color: Theme.of(context).primaryTextTheme.bodySmall!.decorationColor!),
|
Divider(color: Theme.of(context).primaryTextTheme.bodySmall!.decorationColor!),
|
||||||
Observer(
|
Observer(
|
||||||
builder: (_) => SettingsSwitcherCell(
|
builder: (_) => SettingsSwitcherCell(
|
||||||
title: S.of(context).pin_at_top(_homeSettingsViewModel.nativeToken),
|
title: S.of(context).pin_at_top(_homeSettingsViewModel.nativeToken.title),
|
||||||
value: _homeSettingsViewModel.pinNativeToken,
|
value: _homeSettingsViewModel.pinNativeToken,
|
||||||
onValueChange: (_, bool value) {
|
onValueChange: (_, bool value) {
|
||||||
_homeSettingsViewModel.setPinNativeToken(value);
|
_homeSettingsViewModel.setPinNativeToken(value);
|
||||||
|
@ -74,8 +75,12 @@ class HomeSettingsPage extends BasePage {
|
||||||
),
|
),
|
||||||
RawMaterialButton(
|
RawMaterialButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.pushNamed(context, Routes.editToken,
|
Navigator.pushNamed(context, Routes.editToken, arguments: {
|
||||||
arguments: {'homeSettingsViewModel': _homeSettingsViewModel});
|
'homeSettingsViewModel': _homeSettingsViewModel,
|
||||||
|
if (AddressValidator(type: _homeSettingsViewModel.nativeToken)
|
||||||
|
.isValid(_searchController.text))
|
||||||
|
'contractAddress': _searchController.text,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
fillColor: Theme.of(context).accentTextTheme.bodySmall!.color!,
|
fillColor: Theme.of(context).accentTextTheme.bodySmall!.color!,
|
||||||
|
|
|
@ -220,7 +220,7 @@ abstract class BalanceViewModelBase with Store {
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
Map<CryptoCurrency, BalanceRecord> get balances {
|
Map<CryptoCurrency, BalanceRecord> get balances {
|
||||||
return _sortedBalance.map((key, value) {
|
return wallet.balance.map((key, value) {
|
||||||
if (displayMode == BalanceDisplayMode.hiddenBalance) {
|
if (displayMode == BalanceDisplayMode.hiddenBalance) {
|
||||||
return MapEntry(key, BalanceRecord(
|
return MapEntry(key, BalanceRecord(
|
||||||
availableBalance: '---',
|
availableBalance: '---',
|
||||||
|
@ -278,27 +278,44 @@ abstract class BalanceViewModelBase with Store {
|
||||||
final balance = balances.values.toList();
|
final balance = balances.values.toList();
|
||||||
|
|
||||||
balance.sort((BalanceRecord a, BalanceRecord b) {
|
balance.sort((BalanceRecord a, BalanceRecord b) {
|
||||||
if (b.asset == CryptoCurrency.xhv) {
|
if (wallet.currency == CryptoCurrency.xhv) {
|
||||||
return 1;
|
if (b.asset == CryptoCurrency.xhv) {
|
||||||
}
|
return 1;
|
||||||
|
|
||||||
if (b.asset == CryptoCurrency.xusd) {
|
|
||||||
if (a.asset == CryptoCurrency.xhv) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
if (b.asset == CryptoCurrency.xusd) {
|
||||||
|
if (a.asset == CryptoCurrency.xhv) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.asset == CryptoCurrency.xbtc) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.asset == CryptoCurrency.xeur) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.asset == wallet.currency && pinNativeToken) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b.asset == CryptoCurrency.xbtc) {
|
switch (sortBalanceBy) {
|
||||||
return 1;
|
case SortBalanceBy.FiatBalance:
|
||||||
|
return double.parse(b.fiatAvailableBalance)
|
||||||
|
.compareTo(double.parse(a.fiatAvailableBalance));
|
||||||
|
case SortBalanceBy.GrossBalance:
|
||||||
|
return double.parse(b.availableBalance)
|
||||||
|
.compareTo(double.parse(a.availableBalance));
|
||||||
|
case SortBalanceBy.Alphabetical:
|
||||||
|
return a.asset.title.compareTo(b.asset.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b.asset == CryptoCurrency.xeur) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return balance;
|
return balance;
|
||||||
|
@ -369,35 +386,5 @@ abstract class BalanceViewModelBase with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
String getFormattedFrozenBalance(Balance walletBalance) => walletBalance.formattedFrozenBalance;
|
String getFormattedFrozenBalance(Balance walletBalance) => walletBalance.formattedFrozenBalance;
|
||||||
|
|
||||||
@computed
|
|
||||||
Map<CryptoCurrency, Balance> get _sortedBalance {
|
|
||||||
final Map<CryptoCurrency, Balance> sortedMap = {};
|
|
||||||
if (pinNativeToken) {
|
|
||||||
sortedMap[wallet.currency] = wallet.balance[wallet.currency]!;
|
|
||||||
}
|
|
||||||
switch (sortBalanceBy) {
|
|
||||||
case SortBalanceBy.FiatBalance:
|
|
||||||
sortedMap.addAll(Map.fromEntries(wallet.balance.entries.toList()
|
|
||||||
..sort((e1, e2) => double.parse(_getFiatBalance(
|
|
||||||
price: fiatConvertationStore.prices[e2.key]!,
|
|
||||||
cryptoAmount: e2.value.formattedAvailableBalance))
|
|
||||||
.compareTo(double.parse(_getFiatBalance(
|
|
||||||
price: fiatConvertationStore.prices[e1.key]!,
|
|
||||||
cryptoAmount: e1.value.formattedAvailableBalance))))));
|
|
||||||
break;
|
|
||||||
case SortBalanceBy.GrossBalance:
|
|
||||||
sortedMap.addAll(Map.fromEntries(wallet.balance.entries.toList()
|
|
||||||
..sort((e1, e2) => double.parse(e2.value.formattedAvailableBalance)
|
|
||||||
.compareTo(double.parse(e1.value.formattedAvailableBalance)))));
|
|
||||||
break;
|
|
||||||
case SortBalanceBy.Alphabetical:
|
|
||||||
sortedMap.addAll(Map.fromEntries(wallet.balance.entries.toList()
|
|
||||||
..sort((e1, e2) => e1.key.title.compareTo(e2.key.title))));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortedMap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ abstract class HomeSettingsViewModelBase with Store {
|
||||||
Future<Erc20Token?> getErc20Token(String contractAddress) async =>
|
Future<Erc20Token?> getErc20Token(String contractAddress) async =>
|
||||||
await ethereum!.getErc20Token(_balanceViewModel.wallet, contractAddress);
|
await ethereum!.getErc20Token(_balanceViewModel.wallet, contractAddress);
|
||||||
|
|
||||||
String get nativeToken => _balanceViewModel.wallet.currency.title;
|
CryptoCurrency get nativeToken => _balanceViewModel.wallet.currency;
|
||||||
|
|
||||||
void _updateFiatPrices(Erc20Token token) async {
|
void _updateFiatPrices(Erc20Token token) async {
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in a new issue