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

feat(cat-voices): seed phrase error result and unlock password instructions #920

Merged
merged 7 commits into from
Oct 2, 2024
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
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'package:catalyst_voices/pages/registration/create_keychain/stage/check_seed_phrase_instructions_panel.dart';
import 'package:catalyst_voices/pages/registration/create_keychain/stage/instructions_panel.dart';
import 'package:catalyst_voices/pages/registration/create_keychain/stage/seed_phrase_check_instructions_panel.dart';
import 'package:catalyst_voices/pages/registration/create_keychain/stage/seed_phrase_check_panel.dart';
import 'package:catalyst_voices/pages/registration/create_keychain/stage/seed_phrase_check_result_panel.dart';
import 'package:catalyst_voices/pages/registration/create_keychain/stage/seed_phrase_panel.dart';
import 'package:catalyst_voices/pages/registration/create_keychain/stage/splash_panel.dart';
import 'package:catalyst_voices/pages/registration/create_keychain/stage/unlock_password_instructions_panel.dart';
import 'package:catalyst_voices/pages/registration/placeholder_panel.dart';
import 'package:catalyst_voices_blocs/catalyst_voices_blocs.dart';
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
Expand All @@ -30,16 +31,16 @@ class CreateKeychainPanel extends StatelessWidget {
isNextEnabled: seedPhraseState.isStoredConfirmed,
),
CreateKeychainStage.checkSeedPhraseInstructions =>
const CheckSeedPhraseInstructionsPanel(),
const SeedPhraseCheckInstructionsPanel(),
CreateKeychainStage.checkSeedPhrase => SeedPhraseCheckPanel(
seedPhrase: seedPhraseState.seedPhrase,
),
CreateKeychainStage.checkSeedPhraseResult => SeedPhraseCheckResultPanel(
isCheckConfirmed: seedPhraseState.isCheckConfirmed,
),
CreateKeychainStage.unlockPasswordInstructions ||
CreateKeychainStage.unlockPasswordCreate =>
const PlaceholderPanel(),
CreateKeychainStage.unlockPasswordInstructions =>
const UnlockPasswordInstructionsPanel(),
CreateKeychainStage.unlockPasswordCreate => const PlaceholderPanel(),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ class InstructionsPanel extends StatelessWidget {

@override
Widget build(BuildContext context) {
final l10n = context.l10n;

return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 24),
RegistrationStageMessage(
title: context.l10n.accountInstructionsTitle,
subtitle: context.l10n.accountInstructionsMessage,
Expanded(
child: SingleChildScrollView(
child: RegistrationStageMessage(
title: l10n.accountInstructionsTitle,
subtitle: l10n.accountInstructionsMessage,
),
),
),
const Spacer(),
const SizedBox(height: 10),
const RegistrationBackNextNavigation(),
],
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:catalyst_voices/pages/registration/registration_stage_message.dart';
import 'package:catalyst_voices/pages/registration/registration_stage_navigation.dart';
import 'package:catalyst_voices_localization/catalyst_voices_localization.dart';
import 'package:flutter/material.dart';

class SeedPhraseCheckInstructionsPanel extends StatelessWidget {
const SeedPhraseCheckInstructionsPanel({
super.key,
});

@override
Widget build(BuildContext context) {
final l10n = context.l10n;

return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 24),
Expanded(
child: SingleChildScrollView(
child: RegistrationStageMessage(
title: l10n.createKeychainSeedPhraseCheckInstructionsTitle,
subtitle: l10n.createKeychainSeedPhraseCheckInstructionsSubtitle,
),
),
),
const SizedBox(height: 10),
const RegistrationBackNextNavigation(),
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@ class _SeedPhraseCheckPanelState extends State<SeedPhraseCheckPanel> {
final _shuffledSeedPhraseWords = <String>[];
final _userWords = <String>[];

bool get _isStageValid {
if (_seedPhraseWords.isEmpty) {
return false;
}
bool get _hasSeedPhraseWords => _seedPhraseWords.isNotEmpty;

bool get _completedWordsSequence {
return _hasSeedPhraseWords && _userWords.length == _seedPhraseWords.length;
}

return listEquals(_seedPhraseWords, _userWords);
bool get _completedCorrectlyWordsSequence {
return _hasSeedPhraseWords && listEquals(_userWords, _seedPhraseWords);
}

@override
void initState() {
super.initState();

_updateSeedPhraseWords();
_updateUserWords(_seedPhraseWords);
_updateUserWords();
}

@override
Expand Down Expand Up @@ -69,7 +71,7 @@ class _SeedPhraseCheckPanelState extends State<SeedPhraseCheckPanel> {
),
),
const SizedBox(height: 10),
RegistrationBackNextNavigation(isNextEnabled: _isStageValid),
RegistrationBackNextNavigation(isNextEnabled: _completedWordsSequence),
],
);
}
Expand Down Expand Up @@ -109,9 +111,10 @@ class _SeedPhraseCheckPanelState extends State<SeedPhraseCheckPanel> {
..clear()
..addAll(words);

RegistrationCubit.of(context).setSeedPhraseCheckConfirmed(
isConfirmed: _isStageValid,
);
final isConfirmed = _completedCorrectlyWordsSequence;

RegistrationCubit.of(context)
.setSeedPhraseCheckConfirmed(isConfirmed: isConfirmed);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,27 @@ class SeedPhraseCheckResultPanel extends StatelessWidget {

@override
Widget build(BuildContext context) {
final l10n = context.l10n;

return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 24),
RegistrationStageMessage(
title: context.l10n.createKeychainSeedPhraseCheckSuccessTitle,
subtitle: context.l10n.createKeychainSeedPhraseCheckSuccessSubtitle,
),
const Spacer(),
NextStep(
context.l10n.createKeychainSeedPhraseCheckSuccessNextStep,
// TODO(damian-molinski): use correct strings when available.
Expanded(
child: SingleChildScrollView(
child: RegistrationStageMessage(
title: isCheckConfirmed
? l10n.createKeychainSeedPhraseCheckSuccessTitle
: 'Seed phrase words does not match!',
subtitle: isCheckConfirmed
? l10n.createKeychainSeedPhraseCheckSuccessSubtitle
: 'Go back ana make sure order is correct',
),
),
),
if (isCheckConfirmed)
NextStep(l10n.createKeychainSeedPhraseCheckSuccessNextStep),
const SizedBox(height: 10),
RegistrationBackNextNavigation(isNextEnabled: isCheckConfirmed),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,28 @@ import 'package:catalyst_voices/pages/registration/registration_stage_navigation
import 'package:catalyst_voices_localization/catalyst_voices_localization.dart';
import 'package:flutter/material.dart';

class CheckSeedPhraseInstructionsPanel extends StatelessWidget {
const CheckSeedPhraseInstructionsPanel({
class UnlockPasswordInstructionsPanel extends StatelessWidget {
const UnlockPasswordInstructionsPanel({
super.key,
});

@override
Widget build(BuildContext context) {
final l10n = context.l10n;

return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 24),
RegistrationStageMessage(
title: context.l10n.createKeychainSeedPhraseCheckInstructionsTitle,
subtitle:
context.l10n.createKeychainSeedPhraseCheckInstructionsSubtitle,
Expanded(
child: SingleChildScrollView(
child: RegistrationStageMessage(
title: l10n.createKeychainUnlockPasswordInstructionsTitle,
subtitle: l10n.createKeychainUnlockPasswordInstructionsSubtitle,
),
),
),
const Spacer(),
const SizedBox(height: 10),
const RegistrationBackNextNavigation(),
],
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:catalyst_voices/pages/registration/pictures/task_picture.dart';
import 'package:catalyst_voices_assets/catalyst_voices_assets.dart';
import 'package:flutter/material.dart';

class PasswordPicture extends StatelessWidget {
const PasswordPicture({super.key});

@override
Widget build(BuildContext context) {
return TaskPicture(
child: TaskPictureIconBox(
type: TaskPictureType.error,
child: VoicesAssets.icons.lockClosed.buildIcon(size: 48),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:catalyst_voices/pages/registration/information_panel.dart';
import 'package:catalyst_voices/pages/registration/pictures/keychain_picture.dart';
import 'package:catalyst_voices/pages/registration/pictures/password_picture.dart';
import 'package:catalyst_voices/pages/registration/pictures/seed_phrase_picture.dart';
import 'package:catalyst_voices/pages/registration/pictures/task_picture.dart';
import 'package:catalyst_voices_blocs/catalyst_voices_blocs.dart';
Expand Down Expand Up @@ -66,9 +67,9 @@ class RegistrationInfoPanel extends StatelessWidget {
subtitle: context.l10n.createKeychainSeedPhraseCheckSubtitle,
body: context.l10n.createKeychainSeedPhraseCheckBody,
),
CreateKeychainStage.checkSeedPhraseResult =>
CreateKeychainStage.checkSeedPhraseResult ||
CreateKeychainStage.unlockPasswordInstructions =>
_HeaderStrings(title: context.l10n.catalystKeychain),
CreateKeychainStage.unlockPasswordInstructions ||
CreateKeychainStage.unlockPasswordCreate =>
_HeaderStrings(title: 'TODO'),
};
Expand Down Expand Up @@ -138,7 +139,7 @@ class _RegistrationPicture extends StatelessWidget {
),
CreateKeychainStage.unlockPasswordInstructions ||
CreateKeychainStage.unlockPasswordCreate =>
const KeychainPicture(),
const PasswordPicture(),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,18 @@ abstract class VoicesLocalizations {
/// In en, this message translates to:
/// **'Now let’s set your Unlock password for this device!'**
String get createKeychainSeedPhraseCheckSuccessNextStep;

/// No description provided for @createKeychainUnlockPasswordInstructionsTitle.
///
/// In en, this message translates to:
/// **'Set your Catalyst unlock password 
for this device'**
String get createKeychainUnlockPasswordInstructionsTitle;

/// No description provided for @createKeychainUnlockPasswordInstructionsSubtitle.
///
/// In en, this message translates to:
/// **'With over 300 trillion possible combinations, your 12 word seed phrase is great for keeping your account safe. 

But it can be a bit tedious to enter every single time you want to use the app. 

In this next step, you\'ll set your Unlock Password for your current device. It\'s like a shortcut for proving ownership of your Keychain. 

Whenever you recover your account for the first time on a new device, you\'ll need to use your Catalyst Keychain to get started. Every time after that, you can use your Unlock Password to quickly regain access.'**
String get createKeychainUnlockPasswordInstructionsSubtitle;
}

class _VoicesLocalizationsDelegate extends LocalizationsDelegate<VoicesLocalizations> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -572,4 +572,10 @@ class VoicesLocalizationsEn extends VoicesLocalizations {

@override
String get createKeychainSeedPhraseCheckSuccessNextStep => 'Now let’s set your Unlock password for this device!';

@override
String get createKeychainUnlockPasswordInstructionsTitle => 'Set your Catalyst unlock password 
for this device';

@override
String get createKeychainUnlockPasswordInstructionsSubtitle => 'With over 300 trillion possible combinations, your 12 word seed phrase is great for keeping your account safe. 

But it can be a bit tedious to enter every single time you want to use the app. 

In this next step, you\'ll set your Unlock Password for your current device. It\'s like a shortcut for proving ownership of your Keychain. 

Whenever you recover your account for the first time on a new device, you\'ll need to use your Catalyst Keychain to get started. Every time after that, you can use your Unlock Password to quickly regain access.';
}
Original file line number Diff line number Diff line change
Expand Up @@ -572,4 +572,10 @@ class VoicesLocalizationsEs extends VoicesLocalizations {

@override
String get createKeychainSeedPhraseCheckSuccessNextStep => 'Now let’s set your Unlock password for this device!';

@override
String get createKeychainUnlockPasswordInstructionsTitle => 'Set your Catalyst unlock password 
for this device';

@override
String get createKeychainUnlockPasswordInstructionsSubtitle => 'With over 300 trillion possible combinations, your 12 word seed phrase is great for keeping your account safe. 

But it can be a bit tedious to enter every single time you want to use the app. 

In this next step, you\'ll set your Unlock Password for your current device. It\'s like a shortcut for proving ownership of your Keychain. 

Whenever you recover your account for the first time on a new device, you\'ll need to use your Catalyst Keychain to get started. Every time after that, you can use your Unlock Password to quickly regain access.';
}
Original file line number Diff line number Diff line change
Expand Up @@ -649,5 +649,7 @@
"createKeychainSeedPhraseCheckSuccessTitle": "Nice job! You've successfully verified the seed phrase for your keychain.",
"createKeychainSeedPhraseCheckSuccessSubtitle": "Enter your seed phrase to recover your Catalyst Keychain on any device.\u2028\u2028It's kinda like your email and password all rolled into one, so keep it somewhere safe!\u2028\u2028In the next step we’ll add a password to your Catalyst Keychain, so you can lock/unlock access to Voices.",
"yourNextStep": "Your next step",
"createKeychainSeedPhraseCheckSuccessNextStep": "Now let’s set your Unlock password for this device!"
"createKeychainSeedPhraseCheckSuccessNextStep": "Now let’s set your Unlock password for this device!",
"createKeychainUnlockPasswordInstructionsTitle": "Set your Catalyst unlock password \u2028for this device",
"createKeychainUnlockPasswordInstructionsSubtitle": "With over 300 trillion possible combinations, your 12 word seed phrase is great for keeping your account safe. \u2028\u2028But it can be a bit tedious to enter every single time you want to use the app. \u2028\u2028In this next step, you'll set your Unlock Password for your current device. It's like a shortcut for proving ownership of your Keychain. \u2028\u2028Whenever you recover your account for the first time on a new device, you'll need to use your Catalyst Keychain to get started. Every time after that, you can use your Unlock Password to quickly regain access."
}
Loading