Changed restore wallet from seed screen. Added node.imonero.org:18081 to list of default nodes.

This commit is contained in:
M
2020-01-16 18:05:07 +02:00
parent b7e8abcb95
commit 6154c6dfa5
16 changed files with 312 additions and 164 deletions
@@ -6,7 +6,6 @@ import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/domain/services/wallet_list_service.dart';
import 'package:cake_wallet/src/domain/services/wallet_service.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
@@ -22,15 +21,27 @@ class RestoreWalletFromSeedPage extends BasePage {
final WalletListService walletsService;
final WalletService walletService;
final SharedPreferences sharedPreferences;
final formKey = GlobalKey<_RestoreFromSeedFormState>();
@override
String get title => S.current.restore_title_from_seed;
@override
Widget body(BuildContext context) => RestoreFromSeedForm();
Widget trailing(BuildContext context) => SizedBox(
width: 80,
height: 20,
child: FlatButton(
child: Text(S.of(context).clear),
padding: EdgeInsets.all(0),
onPressed: () => formKey?.currentState?.clear()));
@override
Widget body(BuildContext context) => RestoreFromSeedForm(key: formKey);
}
class RestoreFromSeedForm extends StatefulWidget {
RestoreFromSeedForm({Key key}) : super(key: key);
@override
_RestoreFromSeedFormState createState() => _RestoreFromSeedFormState();
}
@@ -39,6 +50,8 @@ class _RestoreFromSeedFormState extends State<RestoreFromSeedForm> {
final _seedKey = GlobalKey<SeedWidgetState>();
bool _reactionSet = false;
void clear() => _seedKey.currentState.clear();
@override
Widget build(BuildContext context) {
final walletRestorationStore = Provider.of<WalletRestorationStore>(context);
@@ -50,42 +63,13 @@ class _RestoreFromSeedFormState extends State<RestoreFromSeedForm> {
onTap: () =>
SystemChannels.textInput.invokeMethod<void>('TextInput.hide'),
child: Container(
padding: EdgeInsets.only(left: 20.0, right: 20.0, bottom: 20.0),
child: Column(
children: <Widget>[
Expanded(
child: SeedWidget(
key: _seedKey,
onMnemoticChange: (seed) => walletRestorationStore.setSeed(seed),
)),
Container(
alignment: Alignment.bottomCenter,
child: PrimaryButton(
onPressed: () {
walletRestorationStore.validateSeed(_seedKey.currentState.items);
_seedKey.currentState.setErrorMessage(walletRestorationStore.errorMessage);
if (!walletRestorationStore.isValid) {
_seedKey.currentState.invalidate();
return;
}
_seedKey.currentState.validated();
Navigator.of(context).pushNamed(
Routes.restoreWalletFromSeedDetails,
arguments: _seedKey.currentState.items);
},
text: S.of(context).restore_next,
color: Theme.of(context)
.primaryTextTheme
.button
.backgroundColor,
borderColor: Theme.of(context)
.primaryTextTheme
.button
.decorationColor))
],
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: SeedWidget(
key: _seedKey,
onMnemoticChange: (seed) => walletRestorationStore.setSeed(seed),
onFinish: () => Navigator.of(context).pushNamed(
Routes.restoreWalletFromSeedDetails,
arguments: _seedKey.currentState.items),
),
),
);
+7 -4
View File
@@ -7,12 +7,15 @@ class PrimaryButton extends StatelessWidget {
{@required this.onPressed,
@required this.text,
@required this.color,
@required this.borderColor});
@required this.borderColor,
this.isDisabled = false});
final VoidCallback onPressed;
final Color color;
final Color borderColor;
final String text;
final bool isDisabled;
@override
Widget build(BuildContext context) {
@@ -20,15 +23,15 @@ class PrimaryButton extends StatelessWidget {
minWidth: double.infinity,
height: 56.0,
child: FlatButton(
onPressed: onPressed,
color: color,
onPressed: isDisabled ? null : onPressed,
color: isDisabled ? Colors.grey : color,
shape: RoundedRectangleBorder(
side: BorderSide(color: borderColor),
borderRadius: BorderRadius.circular(10.0)),
child: Text(text,
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context).primaryTextTheme.button.color)),
color: isDisabled ? Palette.darkGrey : Theme.of(context).primaryTextTheme.button.color)),
));
}
}
+161 -111
View File
@@ -1,3 +1,4 @@
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -7,26 +8,35 @@ import 'package:cake_wallet/src/domain/common/mnemotic_item.dart';
import 'package:cake_wallet/generated/i18n.dart';
class SeedWidget extends StatefulWidget {
SeedWidget({Key key, this.onMnemoticChange}) : super(key: key);
SeedWidget({Key key, this.onMnemoticChange, this.onFinish}) : super(key: key);
final Function(List<MnemoticItem>) onMnemoticChange;
final Function() onFinish;
@override
SeedWidgetState createState() => SeedWidgetState();
}
class SeedWidgetState extends State<SeedWidget> {
static const maxLength = 25;
List<MnemoticItem> items = <MnemoticItem>[];
final _seedController = TextEditingController();
final _seedTextFieldKey = GlobalKey();
MnemoticItem selectedItem;
bool isValid;
String errorMessage;
MnemoticItem currentMnemotic;
bool isCurrentMnemoticValid;
@override
void initState() {
super.initState();
isValid = true;
_seedController.addListener(() => mnemoticFromText(_seedController.text));
isValid = false;
isCurrentMnemoticValid = false;
_seedController
.addListener(() => changeCurrentMnemotic(_seedController.text));
}
void addMnemotic(String text) {
@@ -66,10 +76,14 @@ class SeedWidgetState extends State<SeedWidget> {
}
void selectMnemotic(MnemoticItem item) {
setState(() => selectedItem = item);
_seedController
..text = item.text
..selection = TextSelection.collapsed(offset: item.text.length);
setState(() {
selectedItem = item;
currentMnemotic = item;
_seedController
..text = item.text
..selection = TextSelection.collapsed(offset: item.text.length);
});
}
void onMnemoticTap(MnemoticItem item) {
@@ -107,6 +121,7 @@ class SeedWidgetState extends State<SeedWidget> {
void clear() {
setState(() {
items = [];
selectedItem = null;
_seedController.text = '';
if (widget.onMnemoticChange != null) {
@@ -132,119 +147,154 @@ class SeedWidgetState extends State<SeedWidget> {
mnemoticFromText(text);
}
void changeCurrentMnemotic(String text) {
setState(() {
if (text == null) {
currentMnemotic = null;
isCurrentMnemoticValid = false;
return;
}
currentMnemotic = MnemoticItem(text: text, dic: EnglishMnemonics.words);
isCurrentMnemoticValid = currentMnemotic.isCorrect();
});
}
void saveCurrentMnemoticToItems() {
setState(() {
if (selectedItem != null) {
selectedItem.changeText(currentMnemotic.text);
selectedItem = null;
} else {
items.add(currentMnemotic);
}
currentMnemotic = null;
_seedController.text = '';
});
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(children: [
TextFormField(
onFieldSubmitted: (text) => onFieldSubmitted(text),
style: TextStyle(fontSize: 14.0),
controller: _seedController,
textInputAction: TextInputAction.done,
decoration: InputDecoration(
suffixIcon: GestureDetector(
behavior: HitTestBehavior.opaque,
child: SizedBox(
width: 65,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
onTap: () {
clear();
FocusScope.of(context).unfocus();
},
child: Container(
height: 20,
width: 20,
padding: EdgeInsets.all(3),
decoration: BoxDecoration(
color: Palette.wildDarkBlueWithOpacity,
borderRadius: BorderRadius.circular(10.0)),
child: Image.asset(
'assets/images/x.png',
color: Palette.wildDarkBlue,
),
),
),
InkWell(
onTap: () async => Clipboard.getData('text/plain')
.then((clipboard) => replaceText(clipboard.text)),
child: Container(
height: 35,
width: 35,
padding: EdgeInsets.all(7),
decoration: BoxDecoration(
color: Palette.wildDarkBlueWithOpacity,
borderRadius: BorderRadius.circular(10.0)),
child: Image.asset('assets/images/paste_button.png',
height: 5, width: 5, color: Palette.wildDarkBlue),
),
)
],
),
),
),
errorText: errorMessage,
hintStyle: TextStyle(color: Theme.of(context).hintColor),
hintText: S.of(context).widgets_seed,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Palette.cakeGreen, width: 2.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color:
isValid ? Theme.of(context).focusColor : Palette.red,
width: 1.0))),
),
SizedBox(height: 20),
Expanded(
child: GridView.count(
physics: NeverScrollableScrollPhysics(),
crossAxisCount: 3,
childAspectRatio: 3.3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(items.length, (index) {
final item = items[index];
final isValid = item.isCorrect();
final isSelected = selectedItem == item;
Flexible(
fit: FlexFit.tight,
flex: 6,
child: SingleChildScrollView(
child: Wrap(
children: items.map((item) {
final isValid = item.isCorrect();
final isSelected = selectedItem == item;
return InkWell(
onTap: () => onMnemoticTap(item),
child: Container(
decoration: BoxDecoration(
color: isValid ? Palette.brightBlue : Palette.red,
border: Border.all(
color:
isSelected ? Palette.violet : Colors.transparent),
borderRadius: BorderRadius.circular(15.0)),
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
return InkWell(
onTap: () => onMnemoticTap(item),
child: Container(
decoration: BoxDecoration(
color: isValid ? Colors.transparent : Palette.red),
margin: EdgeInsets.only(right: 7, bottom: 8),
child: Text(
item.toString(),
style: TextStyle(
color:
isValid ? Palette.blueGrey : Palette.lightGrey,
fontSize: 12,
fontWeight: FontWeight.w600),
),
InkWell(
onTap: () => deleteMnemotic(item),
child: Image.asset(
'assets/images/x.png',
height: 15,
width: 15,
color: Palette.wildDarkBlue,
))
],
),
),
);
}),
),
),
fontSize: 18,
fontWeight:
isSelected ? FontWeight.w900 : FontWeight.w400,
decoration: isSelected
? TextDecoration.underline
: TextDecoration.none),
)),
);
}).toList()),
)),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(children: <Widget>[
TextFormField(
key: _seedTextFieldKey,
onFieldSubmitted: (text) => isCurrentMnemoticValid
? saveCurrentMnemoticToItems()
: null,
style: TextStyle(fontSize: 14.0),
controller: _seedController,
textInputAction: TextInputAction.done,
decoration: InputDecoration(
suffixIcon: GestureDetector(
behavior: HitTestBehavior.opaque,
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 145),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
'${items.length}/${SeedWidgetState.maxLength}',
style: TextStyle(
color: Colors.grey, fontSize: 12)),
SizedBox(width: 10),
InkWell(
onTap: () async =>
Clipboard.getData('text/plain').then(
(clipboard) =>
replaceText(clipboard.text)),
child: Container(
height: 35,
padding: EdgeInsets.all(7),
decoration: BoxDecoration(
color:
Palette.wildDarkBlueWithOpacity,
borderRadius:
BorderRadius.circular(10.0)),
child: Text(S.of(context).paste)),
)
],
),
),
),
hintStyle:
TextStyle(color: Theme.of(context).hintColor),
hintText: S.of(context).restore_from_seed_placeholder,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Palette.cakeGreen, width: 2.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).focusColor,
width: 1.0))),
enableInteractiveSelection: false,
),
]),
Padding(
padding: EdgeInsets.only(bottom: 20),
child: (selectedItem == null && items.length == maxLength)
? PrimaryButton(
text: S.of(context).restore_next,
onPressed: () => widget.onFinish != null
? widget.onFinish()
: null,
color: Theme.of(context)
.primaryTextTheme
.button
.backgroundColor,
borderColor: Theme.of(context)
.primaryTextTheme
.button
.decorationColor)
: PrimaryButton(
text: selectedItem != null
? S.of(context).save
: S.of(context).add_new_word,
onPressed: () => isCurrentMnemoticValid
? saveCurrentMnemoticToItems()
: null,
isDisabled: !isCurrentMnemoticValid,
color: PaletteDark.darkThemeBlueButton,
borderColor: Palette.brightBlue))
]))
]),
);
}