WIP: desktop wallet keys popup layouts

This commit is contained in:
julian 2022-10-28 13:51:25 -06:00
parent 8549eda1ed
commit 3a15538273
7 changed files with 363 additions and 3 deletions

23
assets/svg/keys.svg Normal file
View file

@ -0,0 +1,23 @@
<svg width="99" height="57" viewBox="0 0 99 57" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_6055_8386)">
<path d="M90.1893 8.04883H18.9405C14.0708 8.04883 10.123 11.9965 10.123 16.8663V47.6738C10.123 52.5436 14.0708 56.4913 18.9405 56.4913H90.1893C95.0591 56.4913 99.0068 52.5436 99.0068 47.6738V16.8663C99.0068 11.9965 95.0591 8.04883 90.1893 8.04883Z" fill="#E1E2E3"/>
<path d="M91.9528 5.84445V44.9928C91.9528 47.7275 89.7366 49.9437 87.002 49.9437H5.85138C3.11082 49.9437 0.894531 47.7275 0.894531 44.9928V5.84445C0.894531 3.10984 3.11082 0.893555 5.85138 0.893555L88.2888 1.06037C90.4038 1.63232 91.9528 3.55667 91.9528 5.84445V5.84445Z" stroke="#222222" stroke-width="3" stroke-miterlimit="10"/>
<path d="M15.9121 18.4336V32.4045" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M9.86523 21.9248L21.9595 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M21.9595 21.9248L9.86523 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M36.252 18.4336V32.4045" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M30.2051 21.9248L42.2993 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M42.2993 21.9248L30.2051 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M56.5918 18.4336V32.4045" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M50.5449 21.9248L62.6392 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M62.6392 21.9248L50.5449 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M76.9316 18.4336V32.4045" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M70.8848 21.9248L82.979 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M82.979 21.9248L70.8848 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_6055_8386">
<rect width="99" height="56.4914" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -6,10 +6,12 @@ class MnemonicTable extends StatelessWidget {
Key? key,
required this.words,
required this.isDesktop,
this.itemBorderColor,
}) : super(key: key);
final List<String> words;
final bool isDesktop;
final Color? itemBorderColor;
@override
Widget build(BuildContext context) {
@ -40,6 +42,7 @@ class MnemonicTable extends StatelessWidget {
number: ++index,
word: words[index - 1],
isDesktop: isDesktop,
borderColor: itemBorderColor,
),
),
],
@ -61,6 +64,7 @@ class MnemonicTable extends StatelessWidget {
number: i + 1,
word: words[i],
isDesktop: isDesktop,
borderColor: itemBorderColor,
),
),
],

View file

@ -9,16 +9,19 @@ class MnemonicTableItem extends StatelessWidget {
required this.number,
required this.word,
required this.isDesktop,
this.borderColor,
}) : super(key: key);
final int number;
final String word;
final bool isDesktop;
final Color? borderColor;
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
return RoundedWhiteContainer(
borderColor: borderColor,
padding: isDesktop
? const EdgeInsets.symmetric(horizontal: 12, vertical: 9)
: const EdgeInsets.all(8),

View file

@ -4,6 +4,7 @@ import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
@ -30,10 +31,14 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:tuple/tuple.dart';
/// [eventBus] should only be set during testing
@ -246,7 +251,9 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
const SizedBox(
width: 32,
),
const WalletKeysButton(),
WalletKeysButton(
walletId: walletId,
),
const SizedBox(
width: 32,
),
@ -766,11 +773,24 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
}
class WalletKeysButton extends StatelessWidget {
const WalletKeysButton({Key? key}) : super(key: key);
const WalletKeysButton({
Key? key,
required this.walletId,
}) : super(key: key);
final String walletId;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
showDialog<void>(
context: context,
builder: (context) => UnlockWalletKeysDesktop(
walletId: walletId,
),
);
},
child: Container(
color: Colors.transparent,
child: Row(
@ -796,3 +816,311 @@ class WalletKeysButton extends StatelessWidget {
);
}
}
class UnlockWalletKeysDesktop extends ConsumerStatefulWidget {
const UnlockWalletKeysDesktop({
Key? key,
required this.walletId,
}) : super(key: key);
final String walletId;
@override
ConsumerState<UnlockWalletKeysDesktop> createState() =>
_UnlockWalletKeysDesktopState();
}
class _UnlockWalletKeysDesktopState
extends ConsumerState<UnlockWalletKeysDesktop> {
late final TextEditingController passwordController;
late final FocusNode passwordFocusNode;
bool continueEnabled = false;
bool hidePassword = true;
@override
void initState() {
passwordController = TextEditingController();
passwordFocusNode = FocusNode();
super.initState();
}
@override
void dispose() {
passwordController.dispose();
passwordFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DesktopDialog(
maxWidth: 579,
maxHeight: double.infinity,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: const [
DesktopDialogCloseButton(),
],
),
const SizedBox(
height: 12,
),
SvgPicture.asset(
Assets.svg.keys,
width: 100,
height: 58,
),
const SizedBox(
height: 55,
),
Text(
"Wallet keys",
style: STextStyles.desktopH2(context),
),
const SizedBox(
height: 16,
),
Text(
"Enter your password",
style: STextStyles.desktopTextMedium(context).copyWith(
color: Theme.of(context).extension<StackColors>()!.textDark3,
),
),
const SizedBox(
height: 24,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
key: const Key("enterPasswordUnlockWalletKeysDesktopFieldKey"),
focusNode: passwordFocusNode,
controller: passwordController,
style: STextStyles.desktopTextMedium(context).copyWith(
height: 2,
),
obscureText: hidePassword,
enableSuggestions: false,
autocorrect: false,
decoration: standardInputDecoration(
"Enter password",
passwordFocusNode,
context,
).copyWith(
suffixIcon: UnconstrainedBox(
child: SizedBox(
height: 70,
child: Row(
children: [
GestureDetector(
key: const Key(
"enterUnlockWalletKeysDesktopFieldShowPasswordButtonKey"),
onTap: () async {
setState(() {
hidePassword = !hidePassword;
});
},
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(1000),
),
height: 32,
width: 32,
child: Center(
child: SvgPicture.asset(
hidePassword
? Assets.svg.eye
: Assets.svg.eyeSlash,
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
width: 24,
height: 19,
),
),
),
),
const SizedBox(
width: 10,
),
],
),
),
),
),
onChanged: (newValue) {
setState(() {
continueEnabled = newValue.isNotEmpty;
});
},
),
),
),
const SizedBox(
height: 55,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32,
),
child: Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
onPressed: Navigator.of(context).pop,
),
),
const SizedBox(
width: 16,
),
Expanded(
child: PrimaryButton(
label: "Continue",
enabled: continueEnabled,
onPressed: continueEnabled
? () async {
// todo: check password
Navigator.of(context).pop();
final words = await ref
.read(walletsChangeNotifierProvider)
.getManager(widget.walletId)
.mnemonic;
await showDialog<void>(
context: context,
builder: (context) => WalletKeysDesktopPopup(
words: words,
),
);
}
: null,
),
),
],
),
),
const SizedBox(
height: 32,
),
],
),
);
}
}
class WalletKeysDesktopPopup extends StatelessWidget {
const WalletKeysDesktopPopup({
Key? key,
required this.words,
}) : super(key: key);
final List<String> words;
@override
Widget build(BuildContext context) {
return DesktopDialog(
maxWidth: 614,
maxHeight: double.infinity,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(
left: 32,
),
child: Text(
"Wallet keys",
style: STextStyles.desktopH3(context),
),
),
const DesktopDialogCloseButton(),
],
),
const SizedBox(
height: 28,
),
Text(
"Recovery phrase",
style: STextStyles.desktopTextMedium(context),
),
const SizedBox(
height: 8,
),
Center(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32,
),
child: Text(
"Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
style: STextStyles.desktopTextExtraExtraSmall(context),
textAlign: TextAlign.center,
),
),
),
const SizedBox(
height: 24,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32,
),
child: MnemonicTable(
words: words,
isDesktop: true,
itemBorderColor: Theme.of(context)
.extension<StackColors>()!
.buttonBackSecondary,
),
),
const SizedBox(
height: 24,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32,
),
child: Row(
children: [
Expanded(
child: SecondaryButton(
label: "Show QR code",
onPressed: () {
// todo show qr code
},
),
),
const SizedBox(
width: 16,
),
Expanded(
child: PrimaryButton(
label: "Copy",
onPressed: () {
// todo copy to clipboard
},
),
),
],
),
),
const SizedBox(
height: 32,
),
],
),
);
}
}

View file

@ -144,6 +144,7 @@ class _SVG {
String get aboutDesktop => "assets/svg/about-desktop.svg";
String get walletDesktop => "assets/svg/wallet-desktop.svg";
String get exitDesktop => "assets/svg/exit-desktop.svg";
String get keys => "assets/svg/keys.svg";
String get ellipse1 => "assets/svg/Ellipse-43.svg";
String get ellipse2 => "assets/svg/Ellipse-42.svg";

View file

@ -28,8 +28,8 @@ class RoundedWhiteContainer extends StatelessWidget {
radiusMultiplier: radiusMultiplier,
width: width,
height: height,
child: child,
borderColor: borderColor,
child: child,
);
}
}

View file

@ -308,6 +308,7 @@ flutter:
- assets/svg/exchange-desktop.svg
- assets/svg/wallet-desktop.svg
- assets/svg/exit-desktop.svg
- assets/svg/keys.svg
# coin icons
- assets/svg/coin_icons/Bitcoin.svg
- assets/svg/coin_icons/Bitcoincash.svg