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

View file

@ -19,3 +19,6 @@
-
uri: opennode.xmr-tw.org:18089
is_default: false
-
uri: node.imonero.org:18081
is_default: false

View file

@ -286,6 +286,9 @@ class S implements WidgetsLocalizations {
String wallet_list_failed_to_remove(String wallet_name, String error) => "Failed to remove ${wallet_name} wallet. ${error}";
String wallet_list_loading_wallet(String wallet_name) => "Loading ${wallet_name} wallet";
String wallet_list_removing_wallet(String wallet_name) => "Removing ${wallet_name} wallet";
String get paste => "Paste";
String get restore_from_seed_placeholder => "Please enter or paste your seed here";
String get add_new_word => "Add new word";
}
class $de extends S {
@ -824,6 +827,12 @@ class $de extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Laden fehlgeschlagen ${wallet_name} Wallet. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Entfernen ${wallet_name} Wallet";
@override
String get paste => "Einfügen";
@override
String get restore_from_seed_placeholder => "Bitte geben Sie hier Ihren Code ein";
@override
String get add_new_word => "Neues Wort hinzufügen";
}
class $hi extends S {
@ -1362,6 +1371,12 @@ class $hi extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "लोड करने में विफल ${wallet_name} बटुआ. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "निकाला जा रहा है ${wallet_name} बटुआ";
@override
String get paste => "पेस्ट करें";
@override
String get restore_from_seed_placeholder => "कृपया अपना कोड वाक्यांश यहां दर्ज करें या पेस्ट करें";
@override
String get add_new_word => "नया शब्द जोड़ें";
}
class $ru extends S {
@ -1900,6 +1915,12 @@ class $ru extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Ошибка при загрузке ${wallet_name} кошелька. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Удаление ${wallet_name} кошелька";
@override
String get paste => "Вставить";
@override
String get restore_from_seed_placeholder => "Введите или вставте код фразу вашего кошелька";
@override
String get add_new_word => "Добавить новое слово";
}
class $ko extends S {
@ -2438,6 +2459,12 @@ class $ko extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "불러 오지 못했습니다 ${wallet_name} 지갑. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "풀이 ${wallet_name} 지갑";
@override
String get paste => "";
@override
String get restore_from_seed_placeholder => "여기에 코드 문구를 입력하거나 붙여 넣으십시오.";
@override
String get add_new_word => "새로운 단어 추가";
}
class $pt extends S {
@ -2976,6 +3003,12 @@ class $pt extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Falha ao abrir a carteira ${wallet_name}. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Removendo a carteira ${wallet_name}";
@override
String get paste => "Colar";
@override
String get restore_from_seed_placeholder => "Digite ou cole sua frase de código aqui";
@override
String get add_new_word => "Adicionar nova palavra";
}
class $ja extends S {
@ -3514,6 +3547,12 @@ class $ja extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "読み込みに失敗しました ${wallet_name} 財布. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "取りはずし ${wallet_name} 財布";
@override
String get paste => "ペースト";
@override
String get restore_from_seed_placeholder => "ここにコードフレーズを入力または貼り付けてください";
@override
String get add_new_word => "新しい単語を追加";
}
class $en extends S {
@ -4056,6 +4095,12 @@ class $pl extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Nie udało się załadować ${wallet_name} portfel. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Usuwanie ${wallet_name} portfel";
@override
String get paste => "Pasta";
@override
String get restore_from_seed_placeholder => "Wpisz lub wklej tutaj swoją frazę kodową";
@override
String get add_new_word => "Dodaj nowe słowo";
}
class $es extends S {
@ -4594,6 +4639,12 @@ class $es extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "No se pudo cargar ${wallet_name} la billetera. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Retirar ${wallet_name} billetera";
@override
String get paste => "Pegar";
@override
String get restore_from_seed_placeholder => "Ingrese o pegue su frase de código aquí";
@override
String get add_new_word => "Agregar palabra nueva";
}
class $nl extends S {
@ -5132,6 +5183,12 @@ class $nl extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Laden mislukt ${wallet_name} portemonnee. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Verwijderen ${wallet_name} portemonnee";
@override
String get paste => "Plakken";
@override
String get restore_from_seed_placeholder => "Voer hier uw codefrase in of plak deze";
@override
String get add_new_word => "Nieuw woord toevoegen";
}
class $zh extends S {
@ -5670,6 +5727,12 @@ class $zh extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "加载失败 ${wallet_name} 钱包. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "拆下 ${wallet_name} 钱包";
@override
String get paste => "";
@override
String get restore_from_seed_placeholder => "请在此处输入或粘贴您的代码短语";
@override
String get add_new_word => "添加新词";
}
class GeneratedLocalizationsDelegate extends LocalizationsDelegate<S> {

View file

@ -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),
),
),
);

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)),
));
}
}

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))
]))
]),
);
}

View file

@ -331,4 +331,9 @@
"trade_state_finished" : "Fertig",
"change_language" : "Sprache ändern",
"change_language_to" : "Ändern Sie die Sprache in ${language}?"}
"change_language_to" : "Ändern Sie die Sprache in ${language}?",
"paste" : "Einfügen",
"restore_from_seed_placeholder" : "Bitte geben Sie hier Ihren Code ein",
"add_new_word" : "Neues Wort hinzufügen"
}

View file

@ -331,5 +331,9 @@
"trade_state_finished" : "Finished",
"change_language" : "Change language",
"change_language_to" : "Change language to ${language}?"
"change_language_to" : "Change language to ${language}?",
"paste" : ""paste"",
"restore_from_seed_placeholder" : "Please enter or "paste" your seed here",
"add_new_word" : "Add new word"
}

View file

@ -331,5 +331,9 @@
"trade_state_finished" : "Terminado",
"change_language" : "Cambiar idioma",
"change_language_to" : "Cambiar el idioma a ${language}?"
"change_language_to" : "Cambiar el idioma a ${language}?",
"paste" : "Pegar",
"restore_from_seed_placeholder" : "Ingrese o pegue su frase de código aquí",
"add_new_word" : "Agregar palabra nueva"
}

View file

@ -331,5 +331,9 @@
"trade_state_finished" : "ख़त्म होना",
"change_language" : "भाषा बदलो",
"change_language_to" : "को भाषा बदलें ${language}?"
"change_language_to" : "को भाषा बदलें ${language}?",
"paste" : "पेस्ट करें",
"restore_from_seed_placeholder" : "कृपया अपना कोड वाक्यांश यहां दर्ज करें या पेस्ट करें",
"add_new_word" : "नया शब्द जोड़ें"
}

View file

@ -331,5 +331,10 @@
"trade_state_finished" : "完成した",
"change_language" : "言語を変えてください",
"change_language_to" : "言語を変更 ${language}?"
"change_language_to" : "言語を変更 ${language}?",
"paste" : "ペースト",
"restore_from_seed_placeholder" : "ここにコードフレーズを入力または貼り付けてください",
"add_new_word" : "新しい単語を追加",
"add_new_word" : "새로운 단어 추가"
}

View file

@ -331,5 +331,8 @@
"trade_state_finished" : "끝마친",
"change_language" : "언어 변경",
"change_language_to" : "언어를로 변경 ${language}?"
"change_language_to" : "언어를로 변경 ${language}?",
"paste" : "풀",
"restore_from_seed_placeholder" : "여기에 코드 문구를 입력하거나 붙여 넣으십시오."
}

View file

@ -331,5 +331,9 @@
"trade_state_finished" : "Afgewerkt",
"change_language" : "Verander de taal",
"change_language_to" : "Verander de taal in ${language}?"
"change_language_to" : "Verander de taal in ${language}?",
"paste" : "Plakken",
"restore_from_seed_placeholder" : "Voer hier uw codefrase in of plak deze",
"add_new_word" : "Nieuw woord toevoegen"
}

View file

@ -331,5 +331,9 @@
"trade_state_finished" : "Skończone",
"change_language" : "Zmień język",
"change_language_to" : "Zmień język na ${language}?"
"change_language_to" : "Zmień język na ${language}?",
"paste" : "Pasta",
"restore_from_seed_placeholder" : "Wpisz lub wklej tutaj swoją frazę kodową",
"add_new_word" : "Dodaj nowe słowo"
}

View file

@ -331,5 +331,9 @@
"trade_state_finished" : "Finalizada",
"change_language" : "Mudar idioma",
"change_language_to" : "Alterar idioma para ${language}?"
"change_language_to" : "Alterar idioma para ${language}?",
"paste" : "Colar",
"restore_from_seed_placeholder" : "Digite ou cole sua frase de código aqui",
"add_new_word" : "Adicionar nova palavra"
}

View file

@ -331,5 +331,9 @@
"trade_state_finished" : "Окончено",
"change_language" : "Изменить язык",
"change_language_to" : "Изменить язык на ${language}?"
"change_language_to" : "Изменить язык на ${language}?",
"paste" : "Вставить",
"restore_from_seed_placeholder" : "Введите или вставте код фразу вашего кошелька",
"add_new_word" : "Добавить новое слово"
}

View file

@ -331,5 +331,9 @@
"trade_state_finished" : "已完成",
"change_language" : "改變語言",
"change_language_to" : "將語言更改為 ${language}?"
"change_language_to" : "將語言更改為 ${language}?",
"paste" : "糊",
"restore_from_seed_placeholder" : "请在此处输入或粘贴您的代码短语",
"add_new_word" : "添加新词"
}