mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-29 21:55:58 +00:00
verify recovery phrase view desktop ui layout
This commit is contained in:
parent
98252ac4fb
commit
b57521c6a8
4 changed files with 172 additions and 122 deletions
|
@ -6,9 +6,11 @@ class WordTable extends ConsumerWidget {
|
|||
const WordTable({
|
||||
Key? key,
|
||||
required this.words,
|
||||
required this.isDesktop,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<String> words;
|
||||
final bool isDesktop;
|
||||
|
||||
static const wordsPerRow = 3;
|
||||
static const wordsToShow = 9;
|
||||
|
@ -24,18 +26,19 @@ class WordTable extends ConsumerWidget {
|
|||
children: [
|
||||
for (int i = 1; i <= rows; i++)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||
padding: EdgeInsets.symmetric(vertical: isDesktop ? 8 : 5),
|
||||
child: Row(
|
||||
children: [
|
||||
for (int j = 1; j <= wordsPerRow; j++) ...[
|
||||
if (j > 1)
|
||||
const SizedBox(
|
||||
width: 6,
|
||||
SizedBox(
|
||||
width: isDesktop ? 10 : 6,
|
||||
),
|
||||
Expanded(
|
||||
child: WordTableItem(
|
||||
number: ++index,
|
||||
word: words[index - 1],
|
||||
isDesktop: isDesktop,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -10,10 +10,12 @@ class WordTableItem extends ConsumerWidget {
|
|||
Key? key,
|
||||
required this.number,
|
||||
required this.word,
|
||||
required this.isDesktop,
|
||||
}) : super(key: key);
|
||||
|
||||
final int number;
|
||||
final String word;
|
||||
final bool isDesktop;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
@ -30,7 +32,12 @@ class WordTableItem extends ConsumerWidget {
|
|||
child: MaterialButton(
|
||||
splashColor: CFColors.splashLight,
|
||||
key: Key("coinSelectItemButtonKey_$word"),
|
||||
padding: const EdgeInsets.all(12),
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.symmetric(
|
||||
vertical: 18,
|
||||
horizontal: 12,
|
||||
)
|
||||
: const EdgeInsets.all(12),
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
|
@ -45,7 +52,11 @@ class WordTableItem extends ConsumerWidget {
|
|||
Text(
|
||||
word,
|
||||
textAlign: TextAlign.center,
|
||||
style: STextStyles.baseXS,
|
||||
style: isDesktop
|
||||
? STextStyles.desktopTextExtraSmall.copyWith(
|
||||
color: CFColors.textDark,
|
||||
)
|
||||
: STextStyles.baseXS,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -6,6 +8,8 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
|
|||
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart';
|
||||
import 'package:stackwallet/pages/add_wallet_views/verify_recovery_phrase_view/sub_widgets/word_table.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/manager.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
|
@ -14,6 +18,8 @@ import 'package:stackwallet/utilities/constants.dart';
|
|||
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.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:tuple/tuple.dart';
|
||||
|
||||
class VerifyRecoveryPhraseView extends ConsumerStatefulWidget {
|
||||
|
@ -39,11 +45,13 @@ class _VerifyRecoveryPhraseViewState
|
|||
{
|
||||
late Manager _manager;
|
||||
late List<String> _mnemonic;
|
||||
late final bool isDesktop;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_manager = widget.manager;
|
||||
_mnemonic = widget.mnemonic;
|
||||
isDesktop = Platform.isLinux || Platform.isWindows || Platform.isMacOS;
|
||||
// WidgetsBinding.instance?.addObserver(this);
|
||||
super.initState();
|
||||
}
|
||||
|
@ -75,6 +83,50 @@ class _VerifyRecoveryPhraseViewState
|
|||
// }
|
||||
// }
|
||||
|
||||
Future<void> _continue(bool isMatch) async {
|
||||
if (isMatch) {
|
||||
await ref.read(walletsServiceChangeNotifierProvider).setMnemonicVerified(
|
||||
walletId: _manager.walletId,
|
||||
);
|
||||
|
||||
ref
|
||||
.read(walletsChangeNotifierProvider.notifier)
|
||||
.addWallet(walletId: _manager.walletId, manager: _manager);
|
||||
|
||||
if (mounted) {
|
||||
unawaited(Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(HomeView.routeName, (route) => false));
|
||||
}
|
||||
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.success,
|
||||
message: "Correct! Your wallet is set up.",
|
||||
iconAsset: Assets.svg.check,
|
||||
context: context,
|
||||
));
|
||||
} else {
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message: "Incorrect. Please try again.",
|
||||
iconAsset: Assets.svg.circleX,
|
||||
context: context,
|
||||
));
|
||||
|
||||
final int next = Random().nextInt(_mnemonic.length);
|
||||
ref
|
||||
.read(verifyMnemonicWordIndexStateProvider.state)
|
||||
.update((state) => next);
|
||||
|
||||
ref
|
||||
.read(verifyMnemonicCorrectWordStateProvider.state)
|
||||
.update((state) => _mnemonic[next]);
|
||||
|
||||
ref
|
||||
.read(verifyMnemonicSelectedWordStateProvider.state)
|
||||
.update((state) => "");
|
||||
}
|
||||
}
|
||||
|
||||
Tuple2<List<String>, String> randomize(
|
||||
List<String> mnemonic, int chosenIndex, int wordsToShow) {
|
||||
final List<String> remaining = [];
|
||||
|
@ -113,12 +165,12 @@ class _VerifyRecoveryPhraseViewState
|
|||
return false;
|
||||
}
|
||||
|
||||
// Future<void> delete() async {
|
||||
// await ref
|
||||
// .read(walletsServiceChangeNotifierProvider)
|
||||
// .deleteWallet(_manager.walletName, false);
|
||||
// await _manager.exitCurrentWallet();
|
||||
// }
|
||||
Future<void> delete() async {
|
||||
await ref
|
||||
.read(walletsServiceChangeNotifierProvider)
|
||||
.deleteWallet(_manager.walletName, false);
|
||||
await _manager.exitCurrentWallet();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -128,47 +180,74 @@ class _VerifyRecoveryPhraseViewState
|
|||
|
||||
return WillPopScope(
|
||||
onWillPop: onWillPop,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: AppBarBackButton(
|
||||
onPressed: () async {
|
||||
// await delete();
|
||||
Navigator.of(context).popUntil(
|
||||
ModalRoute.withName(
|
||||
// NewWalletRecoveryPhraseWarningView.routeName,
|
||||
NewWalletRecoveryPhraseView.routeName,
|
||||
child: MasterScaffold(
|
||||
isDesktop: isDesktop,
|
||||
appBar: isDesktop
|
||||
? DesktopAppBar(
|
||||
isCompactHeight: false,
|
||||
leading: AppBarBackButton(
|
||||
onPressed: () async {
|
||||
Navigator.of(context).popUntil(
|
||||
ModalRoute.withName(
|
||||
NewWalletRecoveryPhraseView.routeName,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
color: CFColors.almostWhite,
|
||||
trailing: ExitToMyStackButton(
|
||||
onPressed: () async {
|
||||
await delete();
|
||||
if (mounted) {
|
||||
Navigator.of(context).popUntil(
|
||||
ModalRoute.withName(DesktopHomeView.routeName),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
: AppBar(
|
||||
leading: AppBarBackButton(
|
||||
onPressed: () async {
|
||||
Navigator.of(context).popUntil(
|
||||
ModalRoute.withName(
|
||||
NewWalletRecoveryPhraseView.routeName,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
body: SizedBox(
|
||||
width: isDesktop ? 410 : null,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding:
|
||||
isDesktop ? const EdgeInsets.all(0) : const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
SizedBox(
|
||||
height: isDesktop ? 24 : 4,
|
||||
),
|
||||
Text(
|
||||
"Verify recovery phrase",
|
||||
textAlign: TextAlign.center,
|
||||
style: STextStyles.label.copyWith(
|
||||
fontSize: 12,
|
||||
),
|
||||
style: isDesktop
|
||||
? STextStyles.desktopH2
|
||||
: STextStyles.label.copyWith(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
SizedBox(
|
||||
height: isDesktop ? 16 : 4,
|
||||
),
|
||||
Text(
|
||||
"Tap word number ",
|
||||
isDesktop ? "Select word number" : "Tap word number ",
|
||||
textAlign: TextAlign.center,
|
||||
style: STextStyles.pageTitleH1,
|
||||
style: isDesktop
|
||||
? STextStyles.desktopSubtitleH1
|
||||
: STextStyles.pageTitleH1,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
SizedBox(
|
||||
height: isDesktop ? 16 : 12,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
|
@ -192,10 +271,19 @@ class _VerifyRecoveryPhraseViewState
|
|||
),
|
||||
),
|
||||
),
|
||||
if (isDesktop)
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
),
|
||||
WordTable(
|
||||
words: randomize(_mnemonic, correctIndex, 9).item1,
|
||||
isDesktop: isDesktop,
|
||||
),
|
||||
const Spacer(),
|
||||
if (!isDesktop) const Spacer(),
|
||||
if (isDesktop)
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
|
@ -210,92 +298,33 @@ class _VerifyRecoveryPhraseViewState
|
|||
verifyMnemonicCorrectWordStateProvider.state)
|
||||
.state;
|
||||
|
||||
return TextButton(
|
||||
onPressed: selectedWord.isNotEmpty
|
||||
? () async {
|
||||
if (correctWord == selectedWord) {
|
||||
await ref
|
||||
.read(
|
||||
walletsServiceChangeNotifierProvider)
|
||||
.setMnemonicVerified(
|
||||
walletId: _manager.walletId,
|
||||
);
|
||||
|
||||
ref
|
||||
.read(walletsChangeNotifierProvider
|
||||
.notifier)
|
||||
.addWallet(
|
||||
walletId: _manager.walletId,
|
||||
manager: _manager);
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(
|
||||
HomeView.routeName,
|
||||
(route) => false);
|
||||
}
|
||||
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.success,
|
||||
message:
|
||||
"Correct! Your wallet is set up.",
|
||||
iconAsset: Assets.svg.check,
|
||||
context: context,
|
||||
);
|
||||
} else {
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message: "Incorrect. Please try again.",
|
||||
iconAsset: Assets.svg.circleX,
|
||||
context: context,
|
||||
);
|
||||
|
||||
final int next =
|
||||
Random().nextInt(_mnemonic.length);
|
||||
ref
|
||||
.read(
|
||||
verifyMnemonicWordIndexStateProvider
|
||||
.state)
|
||||
.update((state) => next);
|
||||
|
||||
ref
|
||||
.read(
|
||||
verifyMnemonicCorrectWordStateProvider
|
||||
.state)
|
||||
.update((state) => _mnemonic[next]);
|
||||
|
||||
ref
|
||||
.read(
|
||||
verifyMnemonicSelectedWordStateProvider
|
||||
.state)
|
||||
.update((state) => "");
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: isDesktop ? 70 : 0,
|
||||
),
|
||||
child: TextButton(
|
||||
onPressed: selectedWord.isNotEmpty
|
||||
? () async {
|
||||
await _continue(
|
||||
correctWord == selectedWord);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
style: selectedWord.isNotEmpty
|
||||
? Theme.of(context)
|
||||
.textButtonTheme
|
||||
.style
|
||||
?.copyWith(
|
||||
backgroundColor:
|
||||
MaterialStateProperty.all<Color>(
|
||||
CFColors.stackAccent,
|
||||
),
|
||||
: null,
|
||||
style: selectedWord.isNotEmpty
|
||||
? CFColors.getPrimaryEnabledButtonColor(
|
||||
context)
|
||||
: CFColors.getPrimaryDisabledButtonColor(
|
||||
context),
|
||||
child: isDesktop
|
||||
? Text(
|
||||
"Verify",
|
||||
style: selectedWord.isNotEmpty
|
||||
? STextStyles.desktopButtonEnabled
|
||||
: STextStyles.desktopButtonDisabled,
|
||||
)
|
||||
: Theme.of(context)
|
||||
.textButtonTheme
|
||||
.style
|
||||
?.copyWith(
|
||||
backgroundColor:
|
||||
MaterialStateProperty.all<Color>(
|
||||
CFColors.stackAccent.withOpacity(
|
||||
0.25,
|
||||
),
|
||||
),
|
||||
: Text(
|
||||
"Continue",
|
||||
style: STextStyles.button,
|
||||
),
|
||||
child: Text(
|
||||
"Continue",
|
||||
style: STextStyles.button,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -180,6 +180,13 @@ class STextStyles {
|
|||
height: 28 / 20,
|
||||
);
|
||||
|
||||
static final TextStyle desktopSubtitleH1 = GoogleFonts.inter(
|
||||
color: CFColors.textDark,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 24,
|
||||
height: 33 / 24,
|
||||
);
|
||||
|
||||
static final TextStyle desktopButtonEnabled = GoogleFonts.inter(
|
||||
color: CFColors.buttonTextPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
|
|
Loading…
Reference in a new issue