mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
desktop restore layout
This commit is contained in:
parent
cf8b0ea83a
commit
bd5711e098
4 changed files with 467 additions and 153 deletions
|
@ -10,6 +10,7 @@ import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_o
|
|||
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_options_platform_layout.dart';
|
||||
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart';
|
||||
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/mnemonic_word_count_select_sheet.dart';
|
||||
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
|
||||
import 'package:stackwallet/providers/ui/color_theme_provider.dart';
|
||||
import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
|
@ -232,11 +233,13 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
|
|||
|
||||
final lengths = Constants.possibleLengthsForCoin(coin).toList();
|
||||
|
||||
return DesktopScaffold(
|
||||
return MasterScaffold(
|
||||
isDesktop: isDesktop,
|
||||
appBar: isDesktop
|
||||
? const DesktopAppBar(
|
||||
isCompactHeight: false,
|
||||
leading: AppBarBackButton(),
|
||||
trailing: ExitToMyStackButton(),
|
||||
)
|
||||
: AppBar(
|
||||
leading: AppBarBackButton(
|
||||
|
|
|
@ -17,6 +17,7 @@ import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widge
|
|||
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/restoring_dialog.dart';
|
||||
import 'package:stackwallet/pages/home_view/home_view.dart';
|
||||
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
|
||||
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/services/coins/coin_service.dart';
|
||||
import 'package:stackwallet/services/coins/manager.dart';
|
||||
|
@ -36,8 +37,13 @@ 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/custom_buttons/app_bar_icon_button.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
||||
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
|
||||
import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
|
||||
import 'package:stackwallet/widgets/table_view/table_view.dart';
|
||||
import 'package:stackwallet/widgets/table_view/table_view_cell.dart';
|
||||
import 'package:stackwallet/widgets/table_view/table_view_row.dart';
|
||||
import 'package:wakelock/wakelock.dart';
|
||||
|
||||
class RestoreWalletView extends ConsumerStatefulWidget {
|
||||
|
@ -529,13 +535,22 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
final isDesktop = Util.isDesktop;
|
||||
return MasterScaffold(
|
||||
isDesktop: isDesktop,
|
||||
appBar: isDesktop
|
||||
? const DesktopAppBar(
|
||||
isCompactHeight: false,
|
||||
leading: AppBarBackButton(),
|
||||
trailing: ExitToMyStackButton(),
|
||||
)
|
||||
: AppBar(
|
||||
leading: AppBarBackButton(
|
||||
onPressed: () async {
|
||||
if (FocusScope.of(context).hasFocus) {
|
||||
FocusScope.of(context).unfocus();
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
await Future<void>.delayed(
|
||||
const Duration(milliseconds: 50));
|
||||
}
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
|
@ -555,7 +570,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
key: const Key("restoreWalletViewQrCodeButton"),
|
||||
size: 36,
|
||||
shadows: const [],
|
||||
color: Theme.of(context).extension<StackColors>()!.background,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.background,
|
||||
icon: QrCodeIcon(
|
||||
width: 20,
|
||||
height: 20,
|
||||
|
@ -579,7 +596,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
key: const Key("restoreWalletPasteButton"),
|
||||
size: 36,
|
||||
shadows: const [],
|
||||
color: Theme.of(context).extension<StackColors>()!.background,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.background,
|
||||
icon: ClipboardIcon(
|
||||
width: 20,
|
||||
height: 20,
|
||||
|
@ -598,28 +617,312 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: isDesktop
|
||||
? MainAxisAlignment.spaceAround
|
||||
: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (isDesktop) const Spacer(),
|
||||
if (!isDesktop)
|
||||
Text(
|
||||
widget.walletName,
|
||||
style: STextStyles.itemSubtitle(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
SizedBox(
|
||||
height: isDesktop ? 0 : 4,
|
||||
),
|
||||
Text(
|
||||
"Recovery phrase",
|
||||
style: STextStyles.pageTitleH1(context),
|
||||
style: isDesktop
|
||||
? STextStyles.desktopH2(context)
|
||||
: STextStyles.pageTitleH1(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
SizedBox(
|
||||
height: isDesktop ? 16 : 8,
|
||||
),
|
||||
Text(
|
||||
"Enter your $_seedWordCount-word recovery phrase.",
|
||||
style: STextStyles.subtitle(context),
|
||||
style: isDesktop
|
||||
? STextStyles.desktopSubtitleH2(context)
|
||||
: STextStyles.subtitle(context),
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 16 : 10,
|
||||
),
|
||||
if (isDesktop)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: pasteMnemonic,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 12,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.svg.clipboard,
|
||||
width: 22,
|
||||
height: 22,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.buttonTextSecondary,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
width: 8,
|
||||
),
|
||||
Text(
|
||||
"Paste",
|
||||
style: STextStyles
|
||||
.desktopButtonSmallSecondaryEnabled(context),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
if (isDesktop)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 1008,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
const cols = 4;
|
||||
final int rows = _seedWordCount ~/ cols;
|
||||
final int remainder = _seedWordCount % cols;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Form(
|
||||
key: _formKey,
|
||||
child: TableView(
|
||||
shrinkWrap: true,
|
||||
rowSpacing: 20,
|
||||
rows: [
|
||||
for (int i = 0; i < rows; i++)
|
||||
TableViewRow(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
spacing: 16,
|
||||
cells: [
|
||||
for (int j = 1; j <= cols; j++)
|
||||
TableViewCell(
|
||||
flex: 1,
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
textCapitalization:
|
||||
TextCapitalization.none,
|
||||
key: Key(
|
||||
"restoreMnemonicFormField_$i"),
|
||||
decoration:
|
||||
_getInputDecorationFor(
|
||||
_inputStatuses[
|
||||
i * 4 + j - 1],
|
||||
"${i * 4 + j}"),
|
||||
autovalidateMode:
|
||||
AutovalidateMode
|
||||
.onUserInteraction,
|
||||
selectionControls:
|
||||
i * 4 + j - 1 == 1
|
||||
? textSelectionControls
|
||||
: null,
|
||||
onChanged: (value) {
|
||||
if (value.isEmpty) {
|
||||
setState(() {
|
||||
_inputStatuses[
|
||||
i * 4 + j - 1] =
|
||||
FormInputStatus.empty;
|
||||
});
|
||||
} else if (_isValidMnemonicWord(
|
||||
value
|
||||
.trim()
|
||||
.toLowerCase())) {
|
||||
setState(() {
|
||||
_inputStatuses[
|
||||
i * 4 + j - 1] =
|
||||
FormInputStatus.valid;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
_inputStatuses[
|
||||
i * 4 + j - 1] =
|
||||
FormInputStatus
|
||||
.invalid;
|
||||
});
|
||||
}
|
||||
},
|
||||
controller:
|
||||
_controllers[i * 4 + j - 1],
|
||||
style:
|
||||
STextStyles.field(context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.overlay,
|
||||
),
|
||||
),
|
||||
if (_inputStatuses[
|
||||
i * 4 + j - 1] ==
|
||||
FormInputStatus.invalid)
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
left: 12.0,
|
||||
bottom: 4.0,
|
||||
),
|
||||
child: Text(
|
||||
"Please check spelling",
|
||||
textAlign: TextAlign.left,
|
||||
style: STextStyles.label(
|
||||
context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<
|
||||
StackColors>()!
|
||||
.textError,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
expandingChild: null,
|
||||
),
|
||||
if (remainder > 0)
|
||||
TableViewRow(
|
||||
spacing: 16,
|
||||
cells: [
|
||||
for (int i = rows * cols;
|
||||
i < _seedWordCount;
|
||||
i++) ...[
|
||||
TableViewCell(
|
||||
flex: 1,
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
textCapitalization:
|
||||
TextCapitalization.none,
|
||||
key: Key(
|
||||
"restoreMnemonicFormField_$i"),
|
||||
decoration:
|
||||
_getInputDecorationFor(
|
||||
_inputStatuses[i],
|
||||
"${i + 1}"),
|
||||
autovalidateMode:
|
||||
AutovalidateMode
|
||||
.onUserInteraction,
|
||||
selectionControls: i == 1
|
||||
? textSelectionControls
|
||||
: null,
|
||||
onChanged: (value) {
|
||||
if (value.isEmpty) {
|
||||
setState(() {
|
||||
_inputStatuses[i] =
|
||||
FormInputStatus.empty;
|
||||
});
|
||||
} else if (_isValidMnemonicWord(
|
||||
value
|
||||
.trim()
|
||||
.toLowerCase())) {
|
||||
setState(() {
|
||||
_inputStatuses[i] =
|
||||
FormInputStatus.valid;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
_inputStatuses[i] =
|
||||
FormInputStatus
|
||||
.invalid;
|
||||
});
|
||||
}
|
||||
},
|
||||
controller: _controllers[i],
|
||||
style:
|
||||
STextStyles.field(context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.overlay,
|
||||
),
|
||||
),
|
||||
if (_inputStatuses[i] ==
|
||||
FormInputStatus.invalid)
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
left: 12.0,
|
||||
bottom: 4.0,
|
||||
),
|
||||
child: Text(
|
||||
"Please check spelling",
|
||||
textAlign: TextAlign.left,
|
||||
style: STextStyles.label(
|
||||
context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<
|
||||
StackColors>()!
|
||||
.textError,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
for (int i = remainder;
|
||||
i < cols;
|
||||
i++) ...[
|
||||
TableViewCell(
|
||||
flex: 1,
|
||||
child: Container(),
|
||||
),
|
||||
],
|
||||
],
|
||||
expandingChild: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 32,
|
||||
),
|
||||
SizedBox(
|
||||
height: 70,
|
||||
width: 480,
|
||||
child: TextButton(
|
||||
style: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.getPrimaryEnabledButtonColor(context),
|
||||
onPressed: requestRestore,
|
||||
child: Text(
|
||||
"Restore wallet",
|
||||
style: STextStyles.button(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (isDesktop) const Spacer(),
|
||||
if (!isDesktop)
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
controller: controller,
|
||||
|
@ -637,7 +940,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 4),
|
||||
child: TextFormField(
|
||||
textCapitalization: TextCapitalization.none,
|
||||
textCapitalization:
|
||||
TextCapitalization.none,
|
||||
key: Key("restoreMnemonicFormField_$i"),
|
||||
decoration: _getInputDecorationFor(
|
||||
_inputStatuses[i - 1], "$i"),
|
||||
|
@ -665,7 +969,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
}
|
||||
},
|
||||
controller: _controllers[i - 1],
|
||||
style: STextStyles.field(context).copyWith(
|
||||
style:
|
||||
STextStyles.field(context).copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.overlay,
|
||||
|
@ -684,8 +989,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
child: Text(
|
||||
"Please check spelling",
|
||||
textAlign: TextAlign.left,
|
||||
style:
|
||||
STextStyles.label(context).copyWith(
|
||||
style: STextStyles.label(context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textError,
|
||||
|
|
|
@ -6,10 +6,12 @@ class TableView extends StatefulWidget {
|
|||
Key? key,
|
||||
required this.rows,
|
||||
this.rowSpacing = 10.0,
|
||||
this.shrinkWrap = false,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<TableViewRow> rows;
|
||||
final double rowSpacing;
|
||||
final bool shrinkWrap;
|
||||
|
||||
@override
|
||||
State<TableView> createState() => _TableViewState();
|
||||
|
@ -19,6 +21,7 @@ class _TableViewState extends State<TableView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView(
|
||||
shrinkWrap: widget.shrinkWrap,
|
||||
children: [
|
||||
for (int i = 0; i < widget.rows.length; i++)
|
||||
Column(
|
||||
|
|
|
@ -12,6 +12,7 @@ class TableViewRow extends StatelessWidget {
|
|||
this.onExpandChanged,
|
||||
this.padding = const EdgeInsets.all(0),
|
||||
this.spacing = 0.0,
|
||||
this.crossAxisAlignment = CrossAxisAlignment.center,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<TableViewCell> cells;
|
||||
|
@ -20,6 +21,7 @@ class TableViewRow extends StatelessWidget {
|
|||
final void Function(ExpandableState)? onExpandChanged;
|
||||
final EdgeInsetsGeometry padding;
|
||||
final double spacing;
|
||||
final CrossAxisAlignment crossAxisAlignment;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -29,9 +31,10 @@ class TableViewRow extends StatelessWidget {
|
|||
? Padding(
|
||||
padding: padding,
|
||||
child: Row(
|
||||
crossAxisAlignment: crossAxisAlignment,
|
||||
children: [
|
||||
for (int i = 0; i < cells.length; i++) ...[
|
||||
if (i != 0 || i != cells.length)
|
||||
if (i != 0 && i != cells.length)
|
||||
SizedBox(
|
||||
width: spacing,
|
||||
),
|
||||
|
@ -50,7 +53,7 @@ class TableViewRow extends StatelessWidget {
|
|||
child: Row(
|
||||
children: [
|
||||
for (int i = 0; i < cells.length; i++) ...[
|
||||
if (i != 0 || i != cells.length)
|
||||
if (i != 0 && i != cells.length)
|
||||
SizedBox(
|
||||
width: spacing,
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue