mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-25 05:58:42 +01:00
Cw 765 onboarding flow improvements (#1817)
* update onboarding flow * update welcome subtitle * update wallet title * add create restore wallet subtitles * info button * minor fix [skip ci] * Update text and iconbutton * Cleanup --------- Co-authored-by: tuxpizza <tuxsudo@tux.pizza>
This commit is contained in:
@@ -85,9 +85,7 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
|
||||
key: ValueKey('restore_options_from_seeds_or_keys_button_key'),
|
||||
onPressed: () => Navigator.pushNamed(
|
||||
context,
|
||||
Routes.restoreWalletFromSeedKeys,
|
||||
arguments: widget.isNewInstall,
|
||||
),
|
||||
Routes.restoreWalletFromSeedKeys),
|
||||
image: imageSeedKeys,
|
||||
title: S.of(context).restore_title_from_seed_keys,
|
||||
description: S.of(context).restore_description_from_seed_keys,
|
||||
@@ -109,8 +107,7 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
|
||||
child: OptionTile(
|
||||
key: ValueKey('restore_options_from_hardware_wallet_button_key'),
|
||||
onPressed: () => Navigator.pushNamed(
|
||||
context, Routes.restoreWalletFromHardwareWallet,
|
||||
arguments: widget.isNewInstall),
|
||||
context, Routes.restoreWalletFromHardwareWallet),
|
||||
image: imageLedger,
|
||||
title: S.of(context).restore_title_from_hardware_wallet,
|
||||
description: S.of(context).restore_description_from_hardware_wallet,
|
||||
@@ -158,15 +155,6 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
|
||||
await PermissionHandler.checkPermission(Permission.camera, context);
|
||||
|
||||
if (!isCameraPermissionGranted) return;
|
||||
bool isPinSet = false;
|
||||
if (widget.isNewInstall) {
|
||||
await Navigator.pushNamed(context, Routes.setupPin,
|
||||
arguments: (PinCodeState<PinCodeWidget> setupPinContext, String _) {
|
||||
setupPinContext.close();
|
||||
isPinSet = true;
|
||||
});
|
||||
}
|
||||
if (!widget.isNewInstall || isPinSet) {
|
||||
try {
|
||||
if (isRestoring) {
|
||||
return;
|
||||
@@ -188,5 +176,4 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
|
||||
_onWalletCreateFailure(context, e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
||||
|
||||
class CreatePinWelcomePage extends BasePage {
|
||||
static const aspectRatioImage = 1.25;
|
||||
final welcomeImageLight = Image.asset('assets/images/welcome_light.png');
|
||||
final welcomeImageDark = Image.asset('assets/images/welcome.png');
|
||||
|
||||
String appTitle(BuildContext context) {
|
||||
if (isMoneroOnly) {
|
||||
return S.of(context).monero_com;
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return S.of(context).haven_app;
|
||||
}
|
||||
|
||||
return S.of(context).cake_wallet;
|
||||
}
|
||||
|
||||
String appDescription(BuildContext context) {
|
||||
if (isMoneroOnly) {
|
||||
return S.of(context).monero_com_wallet_text;
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return S.of(context).haven_app_wallet_text;
|
||||
}
|
||||
|
||||
return S.of(context).new_first_wallet_text;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: body(context));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
final welcomeImage = currentTheme.type == ThemeType.dark ? welcomeImageDark : welcomeImageLight;
|
||||
|
||||
final newWalletImage = Image.asset('assets/images/new_wallet.png',
|
||||
height: 12,
|
||||
width: 12,
|
||||
color: Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor);
|
||||
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
child: ScrollableWithBottomSection(
|
||||
content: Container(
|
||||
alignment: Alignment.center,
|
||||
child: ConstrainedBox(
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 70),
|
||||
AspectRatio(
|
||||
aspectRatio: aspectRatioImage,
|
||||
child: FittedBox(child: welcomeImage, fit: BoxFit.contain),
|
||||
),
|
||||
SizedBox(height: 50),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: Text(
|
||||
S.of(context).welcome,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.hintTextColor,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
appTitle(context),
|
||||
style: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
appDescription(context),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.hintTextColor,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomSection: Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: PrimaryImageButton(
|
||||
key: ValueKey('create_pin_welcome_page_create_a_pin_button_key'),
|
||||
onPressed: () => Navigator.pushNamed(context, Routes.welcomeWallet),
|
||||
image: newWalletImage,
|
||||
text: S.current.set_a_pin,
|
||||
color: Theme.of(context)
|
||||
.extension<WalletListTheme>()!
|
||||
.createNewWalletButtonBackgroundColor,
|
||||
textColor:
|
||||
Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/screens/welcome/welcome_page.dart';
|
||||
|
||||
Widget createWelcomePage() => WelcomePage();
|
||||
@@ -10,42 +10,28 @@ import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class WelcomePage extends BasePage {
|
||||
static const aspectRatioImage = 1.25;
|
||||
final welcomeImageLight = Image.asset('assets/images/welcome_light.png');
|
||||
final welcomeImageDark = Image.asset('assets/images/welcome.png');
|
||||
|
||||
String appTitle(BuildContext context) {
|
||||
if (isMoneroOnly) {
|
||||
return S.of(context).monero_com;
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return S.of(context).haven_app;
|
||||
}
|
||||
|
||||
return S.of(context).cake_wallet;
|
||||
}
|
||||
|
||||
String appDescription(BuildContext context) {
|
||||
if (isMoneroOnly) {
|
||||
return S.of(context).monero_com_wallet_text;
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return S.of(context).haven_app_wallet_text;
|
||||
}
|
||||
|
||||
return S.of(context).new_first_wallet_text;
|
||||
}
|
||||
final welcomeImageLight = Image.asset('assets/images/wallet_type_light.png');
|
||||
final welcomeImageDark = Image.asset('assets/images/wallet_type.png');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: body(context));
|
||||
String? get title => S.current.wallet;
|
||||
|
||||
@override
|
||||
bool get resizeToAvoidBottomInset => false;
|
||||
|
||||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final Uri _url = Uri.parse('https://guides.cakewallet.com/docs/basic-features/basic-features/');
|
||||
return IconButton(
|
||||
icon: Icon(Icons.info_outline),
|
||||
onPressed: () async {
|
||||
await launchUrl(_url);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -59,106 +45,136 @@ class WelcomePage extends BasePage {
|
||||
final restoreWalletImage = Image.asset('assets/images/restore_wallet.png',
|
||||
height: 12, width: 12, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor);
|
||||
|
||||
return WillPopScope(
|
||||
onWillPop: () async => false,
|
||||
child: ScrollableWithBottomSection(
|
||||
content: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24),
|
||||
child: ConstrainedBox(
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
children: <Widget>[
|
||||
AspectRatio(
|
||||
aspectRatio: aspectRatioImage,
|
||||
child: FittedBox(child: welcomeImage, fit: BoxFit.contain),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: Text(
|
||||
S.of(context).welcome,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.hintTextColor,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
return ScrollableWithBottomSection(
|
||||
content: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24),
|
||||
child: ConstrainedBox(
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
children: <Widget>[
|
||||
AspectRatio(
|
||||
aspectRatio: aspectRatioImage,
|
||||
child: FittedBox(child: welcomeImage, fit: BoxFit.contain),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: highlightText(context, S.of(context).welcome_subtitle_new_wallet,
|
||||
S.of(context).create_new)),
|
||||
SizedBox(height: 10),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
appTitle(context),
|
||||
style: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
appDescription(context),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.hintTextColor,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
child: highlightText(context, S.of(context).welcome_subtitle_restore_wallet,
|
||||
S.of(context).restore_existing_wallet)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomSection: Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).please_make_selection,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.hintTextColor,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: PrimaryImageButton(
|
||||
key: ValueKey('welcome_page_create_new_wallet_button_key'),
|
||||
onPressed: () => Navigator.pushNamed(context, Routes.newWalletFromWelcome),
|
||||
image: newWalletImage,
|
||||
text: S.of(context).create_new,
|
||||
color: Theme.of(context)
|
||||
.extension<WalletListTheme>()!
|
||||
.createNewWalletButtonBackgroundColor,
|
||||
textColor:
|
||||
Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: PrimaryImageButton(
|
||||
),
|
||||
bottomSection: Column(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: PrimaryImageButton(
|
||||
key: ValueKey('welcome_page_restore_wallet_button_key'),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, Routes.restoreOptions, arguments: true);
|
||||
},
|
||||
image: restoreWalletImage,
|
||||
text: S.of(context).restore_wallet,
|
||||
color: Theme.of(context).cardColor,
|
||||
textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, Routes.restoreOptions, arguments: true);
|
||||
},
|
||||
image: restoreWalletImage,
|
||||
text: S.of(context).restore_existing_wallet,
|
||||
color: Theme.of(context).cardColor,
|
||||
textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: PrimaryImageButton(
|
||||
key: ValueKey('welcome_page_create_new_wallet_button_key'),
|
||||
onPressed: () => Navigator.pushNamed(context, Routes.newWalletFromWelcome),
|
||||
image: newWalletImage,
|
||||
text: S.of(context).create_new,
|
||||
color: Theme.of(context)
|
||||
.extension<WalletListTheme>()!
|
||||
.createNewWalletButtonBackgroundColor,
|
||||
textColor:
|
||||
Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
RichText highlightText(BuildContext context, String text, String highlightWord) {
|
||||
final regex = RegExp(highlightWord, caseSensitive: false);
|
||||
final matches = regex.allMatches(text);
|
||||
|
||||
if (matches.isEmpty) {
|
||||
return RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
text: text,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1.5,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<InlineSpan> spans = [];
|
||||
int lastMatchEnd = 0;
|
||||
|
||||
for (final match in matches) {
|
||||
final start = match.start;
|
||||
final end = match.end;
|
||||
|
||||
if (start > lastMatchEnd) {
|
||||
spans.add(TextSpan(
|
||||
text: text.substring(lastMatchEnd, start),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1.5,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
spans.add(TextSpan(
|
||||
text: text.substring(start, end),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1.5,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
));
|
||||
|
||||
lastMatchEnd = end;
|
||||
}
|
||||
|
||||
if (lastMatchEnd < text.length) {
|
||||
spans.add(TextSpan(
|
||||
text: text.substring(lastMatchEnd),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1.5,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(children: spans),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user