Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update UX for single address wallets #310

Merged
merged 2 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Map<WitUnit, String> WIT_UNIT = {

enum EstimatedFeeOptions { Stinky, Low, Medium, High, Opulent, Custom }

enum ImportOrigin { fromSheikah, fromMyWitWallet, fromNode }

// ignore: non_constant_identifier_names
Map<EstimatedFeeOptions, String?> DEFAULT_MINER_FEE_OPTIONS = {
EstimatedFeeOptions.Stinky: '0',
Expand All @@ -46,16 +48,23 @@ Map<EstimatedFeeOptions, String?> DEFAULT_MINER_FEE_OPTIONS = {
};
Map<WalletType, String> walletTypeToLabel = {
WalletType.hd: 'HD wallet',
WalletType.single: 'Single address',
WalletType.single: 'Node',
};

Map<ImportOrigin, String> importOriginToLabel = {
ImportOrigin.fromMyWitWallet: 'myWitWallet',
ImportOrigin.fromSheikah: 'Sheikah',
ImportOrigin.fromNode: 'Node'
};
Map<ImportOrigin, CreateWalletType> importOriginToXprvType = {
ImportOrigin.fromMyWitWallet: CreateWalletType.encryptedXprv,
ImportOrigin.fromSheikah: CreateWalletType.encryptedXprv,
ImportOrigin.fromNode: CreateWalletType.xprv
};
Map<CreateWalletType, WalletType> xprvTypeToWalletType = {
CreateWalletType.encryptedXprv: WalletType.hd,
CreateWalletType.xprv: WalletType.single
};
Map<WalletType, CreateWalletType> walletTypeToXprvType = {
WalletType.hd: CreateWalletType.encryptedXprv,
WalletType.single: CreateWalletType.xprv
};
const int EXTERNAL_GAP_LIMIT = 3;
const int INTERNAL_GAP_LIMIT = 3;
const bool ENCRYPT_DB = false;
Expand Down
171 changes: 65 additions & 106 deletions lib/screens/create_wallet/enc_xprv_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import 'package:my_wit_wallet/screens/create_wallet/bloc/api_create_wallet.dart'
import 'package:my_wit_wallet/screens/create_wallet/bloc/create_wallet_bloc.dart';
import 'package:my_wit_wallet/screens/create_wallet/create_wallet_screen.dart';
import 'package:my_wit_wallet/shared/locator.dart';
import 'package:my_wit_wallet/theme/extended_theme.dart';
import 'package:my_wit_wallet/util/storage/database/wallet.dart';
import 'package:my_wit_wallet/widgets/input_login.dart';
import 'package:my_wit_wallet/screens/create_wallet/nav_action.dart';
import 'package:my_wit_wallet/widgets/toggle_switch.dart';
import 'package:my_wit_wallet/widgets/select.dart';
import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/create_dialog_box/qr_scanner.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'dart:io' show Platform;
Expand Down Expand Up @@ -53,7 +52,7 @@ class EnterXprvCardState extends State<EnterEncryptedXprvCard>
String? errorText;
String? _errorXprvText;
bool isScanQrFocused = false;
int _selectedIndex = 0;
String _selectedOrigin = ImportOrigin.fromMyWitWallet.name;
CreateWalletType _xprvType = CreateWalletType.encryptedXprv;

@override
Expand All @@ -66,7 +65,6 @@ class EnterXprvCardState extends State<EnterEncryptedXprvCard>
_textFocusNode.requestFocus();
_xprvType =
BlocProvider.of<CreateWalletBloc>(context).state.createWalletType;
_selectedIndex = _xprvType == CreateWalletType.encryptedXprv ? 0 : 1;
WidgetsBinding.instance
.addPostFrameCallback((_) => widget.prevAction(prev));
WidgetsBinding.instance
Expand Down Expand Up @@ -100,7 +98,7 @@ class EnterXprvCardState extends State<EnterEncryptedXprvCard>
});
}

Widget _buildConfirmField() {
Widget _buildXprvInput() {
final theme = Theme.of(context);
return TextField(
decoration: InputDecoration(
Expand Down Expand Up @@ -209,7 +207,6 @@ class EnterXprvCardState extends State<EnterEncryptedXprvCard>
setState(() => isXprvValid = false);
}
} catch (e) {
print(e);
setState(() => isXprvValid = false);
}
}
Expand Down Expand Up @@ -275,112 +272,74 @@ class EnterXprvCardState extends State<EnterEncryptedXprvCard>
return Column(children: _children);
}

ImportOrigin labelToWalletOrigin(String origin) {
return ImportOrigin.values.firstWhere((e) {
return e.name == origin;
});
}

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final extendedTheme = theme.extension<ExtendedTheme>()!;
CreateWalletType type =
BlocProvider.of<CreateWalletBloc>(context).state.createWalletType;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Import wallet from an Xprv key',
style: theme.textTheme.titleLarge, //Textstyle
),
SizedBox(
height: 16,
),
Text(
'Xprv is a key exchange format that encodes and protects your wallet with a password. Xprv keys look like a long sequence of apparently random letters and numbers, preceded by "xprv".',
style: theme.textTheme.bodyLarge, //Textstyle
),
SizedBox(height: 8),
Text(
'To import your wallet from a node master key, you need to type the key itself and click continue.',
style: theme.textTheme.bodyLarge, //Textstyle
),
SizedBox(height: 8),
Text(
'To import your wallet from an Xprv key encrypted with a password, you need to type the key itself and its password below:',
style: theme.textTheme.bodyLarge, //Textstyle
),
SizedBox(
height: 16,
),
_buildConfirmField(),
SizedBox(
height: 16,
),
type == CreateWalletType.encryptedXprv
? _buildPasswordField()
: SizedBox(
height: 0,
),
SizedBox(
height: type == CreateWalletType.encryptedXprv ? 16 : 0,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(right: 8),
child: Tooltip(
margin: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: extendedTheme.tooltipBgColor,
),
height: 100,
richMessage: TextSpan(
text: '\'HD Wallet\' ',
style: theme.textTheme.bodyMedium!
.copyWith(fontWeight: FontWeight.bold),
children: <InlineSpan>[
TextSpan(
text:
'(recommended) is the standard BIP-32 compliant wallet.\nSelect ',
style: theme.textTheme.bodyMedium),
TextSpan(
text: '\'Single address\' ',
style: theme.textTheme.bodyMedium!
.copyWith(fontWeight: FontWeight.bold),
),
TextSpan(
text: 'wallet to import a node address.',
style: theme.textTheme.bodyMedium),
],
),
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: Icon(FontAwesomeIcons.circleQuestion,
size: 12, color: extendedTheme.inputIconColor))),
),
ToggleSwitch(
minWidth: 120.0,
inactiveBgColor: extendedTheme.switchInactiveBg,
initialLabelIndex: _selectedIndex,
activeFgColor: extendedTheme.switchActiveFg,
inactiveFgColor: extendedTheme.switchInactiveFg,
activeBgColor: [extendedTheme.switchActiveBg!],
cornerRadius: 4,
borderWidth: 1.0,
borderColor: [extendedTheme.switchBorderColor!],
totalSwitches: 2,
labels:
walletTypeToLabel.values.map((label) => label).toList(),
onToggle: (index) {
WalletType selectedKeyLabel = walletTypeToLabel.keys
.map((label) => label)
.toList()[index];
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: <
Widget>[
Text(
'Import wallet from an Xprv key',
style: theme.textTheme.titleLarge, //Textstyle
),
SizedBox(
height: 16,
),
Text(
'Xprv is a key exchange format that encodes and protects your wallet with a password. Xprv keys look like a long sequence of apparently random letters and numbers, preceded by "xprv".',
style: theme.textTheme.bodyLarge, //Textstyle
),
SizedBox(height: 8),
Text(
'To import your wallet from an Xprv key encrypted with a password, you need to type the key itself and its password below:',
style: theme.textTheme.bodyLarge, //Textstyle
),
SizedBox(
height: 16,
),
Text(
'Xprv origin',
style: theme.textTheme.titleSmall,
),
SizedBox(height: 8),
Select(
selectedItem: _selectedOrigin,
listItems: importOriginToXprvType.keys
.map((label) =>
SelectItem(label.name, importOriginToLabel[label] ?? ''))
.toList(),
onChanged: (String? label) => {
if (label != null)
{
setState(() {
_selectedIndex = index;
});
_setXprvType(walletTypeToXprvType[selectedKeyLabel]!);
_selectedOrigin = label;
}),
_setXprvType(
importOriginToXprvType[labelToWalletOrigin(label)]!),
},
)
]),
]);
}),
SizedBox(
height: 16,
),
_buildXprvInput(),
SizedBox(
height: 16,
),
type == CreateWalletType.encryptedXprv
? _buildPasswordField()
: SizedBox(
height: 0,
),
SizedBox(
height: type == CreateWalletType.encryptedXprv ? 16 : 0,
),
]);
}
}
5 changes: 3 additions & 2 deletions lib/widgets/layouts/dashboard_layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class DashboardLayoutState extends State<DashboardLayout>
? _showCreateVTTDialog
: () {},
icon: Container(
height: 38,
height: 40,
child: Icon(
FontAwesomeIcons.locationArrow,
size: 18,
Expand Down Expand Up @@ -177,7 +177,7 @@ class DashboardLayoutState extends State<DashboardLayout>
? _showReceiveDialog
: () {},
icon: Container(
height: 38,
height: 40,
child: Transform.rotate(
angle: 90 * math.pi / 90,
child: Icon(
Expand Down Expand Up @@ -264,6 +264,7 @@ class DashboardLayoutState extends State<DashboardLayout>
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildBalanceDisplay(),
SizedBox(height: 8),
_buildDashboardActions(),
],
);
Expand Down
4 changes: 3 additions & 1 deletion lib/widgets/layouts/layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@ class LayoutState extends State<Layout> with TickerProviderStateMixin {
style: TextStyle(
color: extendedTheme.headerTextColor,
fontSize: 16))),
SizedBox(height: 8),
SizedBox(
height:
wallet.walletType == WalletType.single ? 8 : 0),
WalletTypeLabel(label: wallet.walletType),
],
))),
Expand Down
23 changes: 16 additions & 7 deletions lib/widgets/select.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import 'package:flutter/material.dart';
import 'package:my_wit_wallet/theme/extended_theme.dart';

DropdownMenuItem<String> _buildWalletDropdownItem(String value) {
DropdownMenuItem<String> _buildWalletDropdownItem(SelectItem value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
value: value.key,
child: Text(value.label),
);
}

typedef void StringCallback(String? value);

class SelectItem {
final String key;
final String label;

SelectItem(this.key, this.label);
}

class Select extends StatelessWidget {
final String selectedItem;
final List<String> listItems;
final List<SelectItem> listItems;
final StringCallback onChanged;

const Select({
Expand All @@ -37,11 +44,12 @@ class Select extends StatelessWidget {
iconEnabledColor: theme.selectedTextColor,
style: TextStyle(color: theme.dropdownTextColor, fontSize: 16),
selectedItemBuilder: (BuildContext context) {
return listItems.map<Widget>((String item) {
return listItems.map<Widget>((SelectItem item) {
return Container(
padding: EdgeInsets.all(8),
alignment: Alignment.centerLeft,
child: Text(
item,
item.label,
style: TextStyle(
color: theme.selectedTextColor,
fontWeight: FontWeight.normal),
Expand All @@ -53,7 +61,8 @@ class Select extends StatelessWidget {
borderRadius: BorderRadius.circular(4),
isExpanded: true,
items: listItems
.map<DropdownMenuItem<String>>(_buildWalletDropdownItem)
.map<DropdownMenuItem<String>>(
(SelectItem item) => _buildWalletDropdownItem(item))
.toList(),
onChanged: onChanged),
),
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/select_wallet_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class SelectWalletBox extends StatelessWidget {
child:
Column(crossAxisAlignment: CrossAxisAlignment.end, children: [
WalletTypeLabel(label: walletType),
SizedBox(height: 8),
SizedBox(height: walletType == WalletType.single ? 8 : 0),
Text(
'$balance ${WIT_UNIT[WitUnit.Wit]}',
textAlign: TextAlign.end,
Expand Down
18 changes: 10 additions & 8 deletions lib/widgets/wallet_type_label.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ class WalletTypeLabel extends StatelessWidget {
}

Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: walletTypeToBgColor(context)[label]),
child: Padding(
padding: EdgeInsets.only(top: 2, bottom: 2, left: 4, right: 4),
child: Text(walletTypeToLabel[label]!,
style: TextStyle(color: WitnetPallet.white, fontSize: 10))));
return label == WalletType.single
? Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: walletTypeToBgColor(context)[label]),
child: Padding(
padding: EdgeInsets.only(top: 2, bottom: 2, left: 4, right: 4),
child: Text(walletTypeToLabel[label]!,
style: TextStyle(color: WitnetPallet.white, fontSize: 10))))
: Container();
}
}
Loading