mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 17:57:40 +00:00
WIP custom token addition
This commit is contained in:
parent
70335286be
commit
0e4b664e63
4 changed files with 224 additions and 6 deletions
|
@ -0,0 +1,189 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
||||||
|
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
||||||
|
import 'package:stackwallet/utilities/show_loading.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||||
|
|
||||||
|
class AddCustomTokenView extends ConsumerStatefulWidget {
|
||||||
|
const AddCustomTokenView({
|
||||||
|
Key? key,
|
||||||
|
required this.walletId,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
static const routeName = "/addCustomToken";
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<AddCustomTokenView> createState() => _AddCustomTokenViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddCustomTokenViewState extends ConsumerState<AddCustomTokenView> {
|
||||||
|
final isDesktop = Util.isDesktop;
|
||||||
|
|
||||||
|
final contractController = TextEditingController();
|
||||||
|
final nameController = TextEditingController();
|
||||||
|
final symbolController = TextEditingController();
|
||||||
|
final decimalsController = TextEditingController();
|
||||||
|
|
||||||
|
bool enableSubFields = false;
|
||||||
|
bool addTokenButtonEnabled = false;
|
||||||
|
|
||||||
|
EthToken? currentToken;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Background(
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: AppBarBackButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 10,
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
bottom: 16,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Add custom ETH token",
|
||||||
|
style: STextStyles.pageTitleH1(context),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
Text("Add custom ETH token"),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
autocorrect: !isDesktop,
|
||||||
|
enableSuggestions: !isDesktop,
|
||||||
|
controller: contractController,
|
||||||
|
style: STextStyles.field(context),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Contract address",
|
||||||
|
hintStyle: STextStyles.fieldLabel(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
PrimaryButton(
|
||||||
|
label: "Search",
|
||||||
|
onPressed: () async {
|
||||||
|
final response = await showLoading(
|
||||||
|
whileFuture: EthereumAPI.getTokenByContractAddress(
|
||||||
|
contractController.text),
|
||||||
|
context: context,
|
||||||
|
message: "Looking up contract",
|
||||||
|
);
|
||||||
|
currentToken = response.value;
|
||||||
|
if (currentToken != null) {
|
||||||
|
nameController.text = currentToken!.name;
|
||||||
|
symbolController.text = currentToken!.symbol;
|
||||||
|
decimalsController.text = currentToken!.decimals.toString();
|
||||||
|
} else {
|
||||||
|
nameController.text = "";
|
||||||
|
symbolController.text = "";
|
||||||
|
decimalsController.text = "";
|
||||||
|
unawaited(
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => StackOkDialog(
|
||||||
|
title: "Failed to look up token",
|
||||||
|
message: response.exception?.message,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
addTokenButtonEnabled = currentToken != null;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
enabled: enableSubFields,
|
||||||
|
autocorrect: !isDesktop,
|
||||||
|
enableSuggestions: !isDesktop,
|
||||||
|
controller: nameController,
|
||||||
|
style: STextStyles.field(context),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Token name",
|
||||||
|
hintStyle: STextStyles.fieldLabel(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
enabled: enableSubFields,
|
||||||
|
autocorrect: !isDesktop,
|
||||||
|
enableSuggestions: !isDesktop,
|
||||||
|
controller: symbolController,
|
||||||
|
style: STextStyles.field(context),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Ticker",
|
||||||
|
hintStyle: STextStyles.fieldLabel(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
enabled: enableSubFields,
|
||||||
|
autocorrect: !isDesktop,
|
||||||
|
enableSuggestions: !isDesktop,
|
||||||
|
controller: decimalsController,
|
||||||
|
style: STextStyles.field(context),
|
||||||
|
inputFormatters: [
|
||||||
|
TextInputFormatter.withFunction((oldValue, newValue) =>
|
||||||
|
RegExp(r'^([0-9]*)$').hasMatch(newValue.text)
|
||||||
|
? newValue
|
||||||
|
: oldValue),
|
||||||
|
],
|
||||||
|
keyboardType: const TextInputType.numberWithOptions(
|
||||||
|
signed: false,
|
||||||
|
decimal: false,
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Decimals",
|
||||||
|
hintStyle: STextStyles.fieldLabel(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
PrimaryButton(
|
||||||
|
label: "Add token",
|
||||||
|
enabled: addTokenButtonEnabled,
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_custom_token_view.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list_element.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list_element.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_text.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_text.dart';
|
||||||
|
@ -70,6 +71,13 @@ class _AddTokenViewState extends ConsumerState<AddTokenView> {
|
||||||
print("SELECTED TOKENS: $selectedTokens");
|
print("SELECTED TOKENS: $selectedTokens");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onAddCustomTokenPressed() {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
AddCustomTokenView.routeName,
|
||||||
|
arguments: widget.walletId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_searchFieldController = TextEditingController();
|
_searchFieldController = TextEditingController();
|
||||||
|
@ -196,6 +204,7 @@ class _AddTokenViewState extends ConsumerState<AddTokenView> {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: AddTokenList(
|
child: AddTokenList(
|
||||||
|
walletId: widget.walletId,
|
||||||
items: filter(_searchTerm, tokenEntities),
|
items: filter(_searchTerm, tokenEntities),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -244,9 +253,7 @@ class _AddTokenViewState extends ConsumerState<AddTokenView> {
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.topNavIconPrimary,
|
.topNavIconPrimary,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: onAddCustomTokenPressed,
|
||||||
// todo add custom token
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -323,6 +330,7 @@ class _AddTokenViewState extends ConsumerState<AddTokenView> {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: AddTokenList(
|
child: AddTokenList(
|
||||||
|
walletId: widget.walletId,
|
||||||
items: filter(_searchTerm, tokenEntities),
|
items: filter(_searchTerm, tokenEntities),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_custom_token_view.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list_element.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list_element.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
@ -10,9 +11,11 @@ import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
class AddTokenList extends StatelessWidget {
|
class AddTokenList extends StatelessWidget {
|
||||||
const AddTokenList({
|
const AddTokenList({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
required this.walletId,
|
||||||
required this.items,
|
required this.items,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
final List<AddTokenListElementData> items;
|
final List<AddTokenListElementData> items;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -29,7 +32,7 @@ class AddTokenList extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
child,
|
child,
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
child: RawMaterialButton(
|
child: RawMaterialButton(
|
||||||
fillColor:
|
fillColor:
|
||||||
Theme.of(context).extension<StackColors>()!.popupBG,
|
Theme.of(context).extension<StackColors>()!.popupBG,
|
||||||
|
@ -44,7 +47,10 @@ class AddTokenList extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// todo add custom token
|
Navigator.of(context).pushNamed(
|
||||||
|
AddCustomTokenView.routeName,
|
||||||
|
arguments: walletId,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
|
@ -73,7 +79,7 @@ class AddTokenList extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
child: AddTokenListElement(
|
child: AddTokenListElement(
|
||||||
data: items[index],
|
data: items[index],
|
||||||
),
|
),
|
||||||
|
|
|
@ -12,6 +12,7 @@ import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
|
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
|
||||||
import 'package:stackwallet/models/send_view_auto_fill_data.dart';
|
import 'package:stackwallet/models/send_view_auto_fill_data.dart';
|
||||||
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_custom_token_view.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_token_view.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_token_view.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart';
|
import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart';
|
||||||
|
@ -218,6 +219,20 @@ class RouteGenerator {
|
||||||
}
|
}
|
||||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
|
case AddCustomTokenView.routeName:
|
||||||
|
if (args is String) {
|
||||||
|
return getRoute(
|
||||||
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
|
builder: (_) => AddCustomTokenView(
|
||||||
|
walletId: args,
|
||||||
|
),
|
||||||
|
settings: RouteSettings(
|
||||||
|
name: settings.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case PaynymClaimView.routeName:
|
case PaynymClaimView.routeName:
|
||||||
if (args is String) {
|
if (args is String) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
|
|
Loading…
Reference in a new issue