Merge branch 'refs/heads/dev' into cw-1440-new-buy-sell-flow

# Conflicts:
#	lib/new-ui/widgets/coins_page/cards/cards_view.dart
#	lib/new-ui/widgets/receive_page/receive_top_bar.dart
This commit is contained in:
Robert Malikowski
2026-08-07 01:35:54 +02:00
286 changed files with 13997 additions and 6504 deletions
@@ -20,6 +20,7 @@ class AddPassphraseBottomSheet extends StatefulWidget {
class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
late final TextEditingController passphraseController;
late final TextEditingController confirmPassphraseController;
final _passphraseFormKey = GlobalKey<FormState>();
@override
void initState() {
@@ -112,51 +113,60 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
),
),
SizedBox(height: 24),
BaseTextFormField(
key: ValueKey('add_passphrase_bottom_sheet_widget_passphrase_textfield_key'),
controller: passphraseController,
obscureText: obscurePassphrase,
contentPadding: EdgeInsets.symmetric(horizontal: 12),
hintText: S.of(context).required_passphrase,
suffixIcon: GestureDetector(
onTap: () {
setState(() {
obscurePassphrase = !obscurePassphrase;
});
},
child: Icon(
obscurePassphrase ? Icons.visibility_off : Icons.visibility,
size: 24,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
),
SizedBox(height: 8),
BaseTextFormField(
key: ValueKey('add_passphrase_bottom_sheet_widget_confirm_passphrase_textfield_key'),
controller: confirmPassphraseController,
obscureText: obscurePassphrase,
contentPadding: EdgeInsets.symmetric(horizontal: 12),
hintText: S.of(context).confirm_passphrase,
suffixIcon: GestureDetector(
onTap: () {
setState(() {
obscurePassphrase = !obscurePassphrase;
});
},
child: Icon(
obscurePassphrase ? Icons.visibility_off : Icons.visibility,
size: 24,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
validator: (text) {
if (text == passphraseController.text) {
return null;
}
Form(
key: _passphraseFormKey,
child: Column(
children: [
BaseTextFormField(
key: ValueKey('add_passphrase_bottom_sheet_widget_passphrase_textfield_key'),
controller: passphraseController,
obscureText: obscurePassphrase,
contentPadding: EdgeInsets.symmetric(horizontal: 12),
hintText: S.of(context).required_passphrase,
suffixIcon: GestureDetector(
onTap: () {
setState(() {
obscurePassphrase = !obscurePassphrase;
});
},
child: Icon(
obscurePassphrase ? Icons.visibility_off : Icons.visibility,
size: 24,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
),
SizedBox(height: 8),
BaseTextFormField(
key: ValueKey(
'add_passphrase_bottom_sheet_widget_confirm_passphrase_textfield_key',
),
controller: confirmPassphraseController,
obscureText: obscurePassphrase,
contentPadding: EdgeInsets.symmetric(horizontal: 12),
hintText: S.of(context).confirm_passphrase,
suffixIcon: GestureDetector(
onTap: () {
setState(() {
obscurePassphrase = !obscurePassphrase;
});
},
child: Icon(
obscurePassphrase ? Icons.visibility_off : Icons.visibility,
size: 24,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
validator: (text) {
if (text == passphraseController.text) {
return null;
}
return S.of(context).passphrases_doesnt_match;
},
return S.of(context).passphrases_doesnt_match;
},
),
],
),
),
SizedBox(height: 16),
Padding(
@@ -184,6 +194,11 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
child: PrimaryButton(
key: ValueKey('add_passphrase_bottom_sheet_widget_restore_button_key'),
onPressed: () {
if (_passphraseFormKey.currentState != null &&
!_passphraseFormKey.currentState!.validate()) {
return;
}
Navigator.pop(context);
widget.onRestoreButtonPressed(passphraseController.text);
},
+48 -29
View File
@@ -1,3 +1,4 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/cupertino.dart';
@@ -92,35 +93,53 @@ class LoadingPrimaryButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
child: SizedBox(
width: double.infinity,
height: 52.0,
child: TextButton(
onPressed: (isLoading || isDisabled)
? null
: () {
FocusScope.of(context).unfocus();
onPressed.call();
},
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(isDisabled ? color.withOpacity(0.5) : color),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
)),
child: isLoading
? CupertinoActivityIndicator(animating: true, color: textColor)
: Text(
text,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 15.0,
fontWeight: FontWeight.w600,
color: isDisabled ? textColor.withOpacity(0.5) : textColor,
),
),
final isEnabled = !isLoading && !isDisabled;
// The spinner replaces the label while loading, so the name is kept on a single
// semantics node that also reports the loading and disabled states.
return Semantics(
button: true,
enabled: isEnabled,
label: text,
value: isLoading ? S.of(context).loading : null,
onTap: isEnabled
? () {
FocusScope.of(context).unfocus();
onPressed.call();
}
: null,
excludeSemantics: true,
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
child: SizedBox(
width: double.infinity,
height: 52.0,
child: TextButton(
onPressed: (isLoading || isDisabled)
? null
: () {
FocusScope.of(context).unfocus();
onPressed.call();
},
style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all(isDisabled ? color.withOpacity(0.5) : color),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
)),
child: isLoading
? CupertinoActivityIndicator(animating: true, color: textColor)
: Text(
text,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 15.0,
fontWeight: FontWeight.w600,
color: isDisabled ? textColor.withOpacity(0.5) : textColor,
),
),
),
),
),
);