New themes (#2239)

* Add theme base v2

* Initial new theme base files

* Typos

* Fixes

* Update theme files

* feat: Migrate to Material 3 Theming

Foundation, Theme Data Refactor, and First Extension Cleanup Batch.

This commit completes the first major phase of migrating to Material 3 theming by setting up the foundations for material 3 integration and begins the initial migration, removing custom theme extensions, updating theme data, and refactoring all relevant widget and page theming to use Material 3’s built-in color and typography tokens.

These changes:
- Lays the groundwork for Material 3 theming by restructuring the app’s theme configuration to use Material 3’s ColorScheme and TextTheme as the primary sources of color and typography throughout the app.
- Refactors the core theme config files by removing legacy custom color roles ensuring all color definitions now map directly to Material 3’s role.
- Begins the first batch migration of custom theme extensions (InfoTheme, PlaceholderTheme, KeyboardTheme, PinCodeTheme) and updates all affected widgets and pages to use Material 3 color and typography tokens instead of the custom properties.
- Cleans up the codebase by deleting the files of the initial set of migrated extensions and eliminating all related imports and usages.

* feat: Migrate to Material 3 Theming.

This change:
- Updates the themes README.md file to reflect the current structure and give more information based on the first major phase that was completed.

* feat: Migrate to Material 3 Theming

Deleting previous theme extensions

* feat: Migrate to Material 3 Theming

Another batch of migrations from existing extensions

* feat: Migration to Material 3 Theming

Third Migration batch for theme extensions

* fwat: Migration to Material 3 Theming

Final Migration batch for previous theme extensions

* Update onboarding hero

* Update button radius

* Add surfaceContainer to light theme

* feat(themes): Migrate to Material 3 Theming

This change:
- Adds new set of hero images
- Modifies the core structure for the themes
- Add missing color tokens to the theme classes
- Adds a CustomThemeColor class for custom color tokens
- Modifies the themelist to have a fall back for previous theme implementation
- Adds localization for some texts
- Modifies the flow for loading the theme on app start
- Add a WidgetsBindingObserver that listens for changes in the device theme and updates the app theme when there is a change
- Registers the themeStore as a Singleton for codebase wide use

* feat(themes): Migrate to Material 3 theming

This change:
- Migrates UI flows across the app to the new themes
- Confirms styling and typography of components across the app uses the new themes
- Remove instances of Palette use
- Switch TextStyles across the app to use theme text styles

* feat(themes): Migrate to Material 3 Theming.

This change:
- Adjusts bottomsheets styling and removes duplicate close button
- Removes more themedata extensions from the previous implementation

* - Remove outlines from cards and dock
- Update menu colors
- Update padding/divider size for cards

* - Update PIN screen
- Fix navigation dock shadow
- Update wallet screen colors

* Update border radius --skip-ci

* feat(themes): Migrate to Material 3 Theming.

This change:
- Adds gradient backgrounds to the dashbaord and balance cards.
- Migrates the input fields across the app to BaseTextFormFields.
- Removes dependence of input fields on individual styling, focusing instead on using theme defined InputDecoration styling with adjustments on individual components where needed.
- Applies new theme styling to BaseTextFormField, AddressTextField and CurrencyAmountTextField.

* - Switch some hero images to PNG
- Fix nagivation_dock shadow
- Minor fixes

* feat: Add fallback to previous underline styling in central widgets

This change:
- Adds a fallback to CurrencyAmountTextField, AddressTextField, and BaseTextFormField, allowing them use the previous theme styling.
- Adds localization for new texts

* feat(themes): Update warning box colors for dark and light themes

* feat(themes): Relaod themes when user restores from backup, ensuring the user previous theme preference is used.

* feat(themes): Handle themes logic during restore from backup

This change:
- Refactors theme loading logic to handle backup restore edgecase
- Refreshes the theme based on the user saved preference during restore from backup flow

* Fix card gradients and spacing

* Fix even more radiuses
Test new icons for navigation_dock.dart

* Update onboarding flow backgrounds
Fix swap icon clipping
Fix some text colors
Add more hero images

* Fix incorrect color for light theme

* Fix more hero images and cleanup

* Update text field icons
Fix info box CTA colors
Fix sync indicator colors

* Update toggle colors
Update dark theme colors (minor)
Update crypto_balance_widget.dart icon

* Update page transitions in router.dart
Fix some colors

* feat(themes): Display label by default for filled textfields

* feat(themes): Refactor theme handling across various components

This change:
- Fixes issue with themeMode resetting to system mode when app is restarted causing a UI glitch
- Updates theme checks from `currentTheme.type == ThemeType.dark` to `currentTheme.isDark` for consistency
- Adjusts UI components to use the theme directly from the themeStore

* feat(themes): Add animating tagline to the create pin welcome screen

* Revert text fields label temporarily, fix a couple colors, and cleanup some images

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
Co-authored-by: Blazebrain <davidadegoke16@gmail.com>
This commit is contained in:
tuxsudo
2025-05-25 23:11:45 +03:00
committed by GitHub
co-authored by OmarHatem Blazebrain
parent 7b8ddf9685
commit df88914628
412 changed files with 11173 additions and 13192 deletions
+10 -12
View File
@@ -2,7 +2,6 @@ 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/material.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
class AddTemplateButton extends StatelessWidget {
final Function() onTap;
@@ -20,31 +19,30 @@ class AddTemplateButton extends StatelessWidget {
child: DottedBorder(
borderType: BorderType.RRect,
dashPattern: [6, 4],
color:
Theme.of(context).extension<SendPageTheme>()!.templateDottedBorderColor,
color: Theme.of(context).colorScheme.outline,
strokeWidth: 2,
radius: Radius.circular(20),
radius: Radius.circular(12),
child: Container(
height: 34,
padding: EdgeInsets.symmetric(
horizontal: responsiveLayoutUtil.shouldRenderMobileUI ? 10 : 30),
horizontal: responsiveLayoutUtil.shouldRenderMobileUI ? 10 : 30,
),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
borderRadius: BorderRadius.all(Radius.circular(12)),
color: Colors.transparent,
),
child: currentTemplatesLength >= 1
? Icon(
Icons.add,
color: Theme.of(context).extension<SendPageTheme>()!.templateNewTextColor,
color: Theme.of(context).colorScheme.onSurfaceVariant,
)
: Text(
S.of(context).new_template,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<SendPageTheme>()!.templateNewTextColor,
),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
),
+146 -153
View File
@@ -2,8 +2,7 @@ import 'package:cake_wallet/entities/contact_base.dart';
import 'package:cake_wallet/entities/qr_scanner.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/permission_handler.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
@@ -22,9 +21,7 @@ class AddressTextField<T extends Currency> extends StatelessWidget {
this.options = const [AddressTextFieldOption.qrCode, AddressTextFieldOption.addressBook],
this.onURIScanned,
this.focusNode,
this.isBorderExist = true,
this.buttonColor,
this.borderColor,
this.iconColor,
this.textStyle,
this.hintStyle,
@@ -35,6 +32,10 @@ class AddressTextField<T extends Currency> extends StatelessWidget {
this.onSelectedContact,
this.selectedCurrency,
this.addressKey,
this.fillColor,
this.hasUnderlineBorder = false,
this.borderWidth = 1.0,
this.contentPadding,
});
static const prefixIconWidth = 34.0;
@@ -47,25 +48,32 @@ class AddressTextField<T extends Currency> extends StatelessWidget {
final Function(Uri)? onURIScanned;
final List<AddressTextFieldOption> options;
final FormFieldValidator<String>? validator;
final bool isBorderExist;
final Color? buttonColor;
final Color? borderColor;
final Color? fillColor;
final Color? iconColor;
final double borderWidth;
final TextStyle? textStyle;
final TextStyle? hintStyle;
final bool hasUnderlineBorder;
final EdgeInsetsGeometry? contentPadding;
final FocusNode? focusNode;
final T? selectedCurrency;
final Key? addressKey;
final Function(BuildContext context)? onPushPasteButton;
final Function(BuildContext context)? onPushAddressBookButton;
final Function(BuildContext context)? onPushAddressPickerButton;
final Function(ContactBase contact)? onSelectedContact;
final T? selectedCurrency;
final Key? addressKey;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
TextFormField(
BaseTextFormField(
contentPadding: contentPadding,
borderWidth: borderWidth,
hasUnderlineBorder: hasUnderlineBorder,
key: addressKey,
enableIMEPersonalizedLearning: false,
keyboardType: TextInputType.visiblePassword,
@@ -73,156 +81,142 @@ class AddressTextField<T extends Currency> extends StatelessWidget {
enabled: isActive,
controller: controller,
focusNode: focusNode,
style: textStyle ??
TextStyle(
fontSize: 16, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
decoration: InputDecoration(
suffixIcon: SizedBox(
width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length),
),
hintStyle: hintStyle ?? TextStyle(fontSize: 16, color: Theme.of(context).hintColor),
hintText: placeholder ?? S.current.widgets_address,
focusedBorder: isBorderExist
? UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ?? Theme.of(context).dividerColor, width: 1.0))
: InputBorder.none,
disabledBorder: isBorderExist
? UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ?? Theme.of(context).dividerColor, width: 1.0))
: InputBorder.none,
enabledBorder: isBorderExist
? UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ?? Theme.of(context).dividerColor, width: 1.0))
: InputBorder.none,
textStyle: textStyle ??
Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
fillColor: fillColor ?? Theme.of(context).colorScheme.surfaceContainer,
suffixIcon: SizedBox(
width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length),
),
placeholderTextStyle: hintStyle ??
Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
hintText: placeholder ?? S.current.widgets_address,
validator: validator,
),
Positioned(
top: 2,
right: 0,
child: SizedBox(
width:
(prefixIconWidth * options.length) + (spaceBetweenPrefixIcons * options.length),
child: Row(
mainAxisAlignment: responsiveLayoutUtil.shouldRenderMobileUI
? MainAxisAlignment.spaceBetween
: MainAxisAlignment.end,
children: [
if (this.options.contains(AddressTextFieldOption.paste)) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).paste,
child: InkWell(
onTap: () async => _pasteAddress(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color:
buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/paste_ios.png',
color: iconColor ??
Theme.of(context)
.extension<SendPageTheme>()!
.textFieldButtonIconColor,
)),
top: 8,
right: 6,
child: SizedBox(
width: (prefixIconWidth * options.length) + (spaceBetweenPrefixIcons * options.length),
child: Row(
mainAxisAlignment: responsiveLayoutUtil.shouldRenderMobileUI
? MainAxisAlignment.spaceBetween
: MainAxisAlignment.end,
children: [
if (this.options.contains(AddressTextFieldOption.paste)) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).paste,
child: InkWell(
onTap: () async => _pasteAddress(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.all(Radius.circular(6)),
),
child: Image.asset(
'assets/images/paste_ios.png',
color: iconColor ?? Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
),
],
if (this.options.contains(AddressTextFieldOption.qrCode) &&
DeviceInfo.instance.isMobile) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).scan_qr_code,
child: InkWell(
onTap: () async => _presentQRScanner(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color:
buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/qr_code_icon.png',
color: iconColor ??
Theme.of(context)
.extension<SendPageTheme>()!
.textFieldButtonIconColor,
)),
),
),
),
],
if (this.options.contains(AddressTextFieldOption.addressBook)) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).address_book,
child: InkWell(
onTap: () async => _presetAddressBookPicker(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color:
buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/open_book.png',
color: iconColor ??
Theme.of(context)
.extension<SendPageTheme>()!
.textFieldButtonIconColor,
)),
),
),
),
],
if (this.options.contains(AddressTextFieldOption.walletAddresses)) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).address_book,
child: InkWell(
onTap: () async => _presetWalletAddressPicker(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color:
buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/open_book.png',
color: iconColor ??
Theme.of(context)
.extension<SendPageTheme>()!
.textFieldButtonIconColor,
)),
),
),
)
],
),
],
),
))
if (this.options.contains(AddressTextFieldOption.qrCode) &&
DeviceInfo.instance.isMobile) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).scan_qr_code,
child: InkWell(
onTap: () async => _presentQRScanner(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.all(
Radius.circular(6),
),
),
child: Image.asset(
'assets/images/qr_code_icon.png',
color: iconColor ?? Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
),
),
],
if (this.options.contains(AddressTextFieldOption.addressBook)) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).address_book,
child: InkWell(
onTap: () async => _presetAddressBookPicker(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.all(
Radius.circular(6),
),
),
child: Image.asset(
'assets/images/open_book.png',
color: iconColor ?? Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
),
),
],
if (this.options.contains(AddressTextFieldOption.walletAddresses)) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).address_book,
child: InkWell(
onTap: () async => _presetWalletAddressPicker(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: buttonColor ?? Theme.of(context).colorScheme.surfaceContainerLow,
borderRadius: BorderRadius.all(Radius.circular(6)),
),
child: Image.asset(
'assets/images/open_book.png',
color: iconColor ?? Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
),
)
],
],
),
),
)
],
);
}
@@ -256,8 +250,7 @@ class AddressTextField<T extends Currency> extends StatelessWidget {
}
Future<void> _presetWalletAddressPicker(BuildContext context) async {
final address =
await Navigator.of(context).pushNamed(Routes.pickerWalletAddress);
final address = await Navigator.of(context).pushNamed(Routes.pickerWalletAddress);
if (address is String) {
controller?.text = address;
+1 -3
View File
@@ -1,5 +1,4 @@
import 'dart:ui';
import 'package:cake_wallet/themes/extensions/alert_theme.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/material.dart';
@@ -21,8 +20,7 @@ class AlertBackground extends StatelessWidget {
filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
child: Container(
decoration: BoxDecoration(
color:
Theme.of(context).extension<AlertTheme>()!.backdropColor),
color: Theme.of(context).colorScheme.surface.withOpacity(0.8)),
child: Center(
child: Container(
width: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint,
+22 -16
View File
@@ -1,5 +1,4 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
class AlertCloseButton extends StatelessWidget {
@@ -17,24 +16,31 @@ class AlertCloseButton extends StatelessWidget {
final double? bottom;
final bool isPositioned;
final closeButton = Image.asset(
'assets/images/close.png',
color: Palette.darkBlueCraiola,
);
@override
Widget build(BuildContext context) {
final button = GestureDetector(
onTap: onTap ?? () => Navigator.of(context).pop(),
child: Semantics(
label: S.of(context).close,
button: true,
enabled: true,
child: Container(
height: 42,
width: 42,
decoration: BoxDecoration(color: Colors.white, shape: BoxShape.circle),
child: Center(child: image ?? closeButton))));
onTap: onTap ?? () => Navigator.of(context).pop(),
child: Semantics(
label: S.of(context).close,
button: true,
enabled: true,
child: Container(
height: 42,
width: 42,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.onSurface,
shape: BoxShape.circle,
),
child: Center(
child: image ??
Image.asset(
'assets/images/close.png',
color: Theme.of(context).colorScheme.surface,
),
),
),
),
);
return isPositioned ? Positioned(bottom: bottom ?? 60, child: button) : button;
}
+17 -16
View File
@@ -44,25 +44,26 @@ class AlertWithOneAction extends BaseAlertDialog {
width: 300,
height: 52,
padding: EdgeInsets.only(left: 12, right: 12),
color: Theme.of(context).dialogBackgroundColor,
color: Theme.of(context).colorScheme.surface,
child: ButtonTheme(
minWidth: double.infinity,
child: TextButton(
key: buttonKey,
onPressed: buttonAction,
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
child: Text(
buttonText,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Theme.of(context).primaryColor,
decoration: TextDecoration.none,
),
)),
key: buttonKey,
onPressed: buttonAction,
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
child: Text(
buttonText,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.primary,
decoration: TextDecoration.none,
),
),
),
),
);
}
+15 -21
View File
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
class AlertWithPickerOption extends BaseAlertDialog {
AlertWithPickerOption(
@@ -46,12 +45,13 @@ class AlertWithPickerOption extends BaseAlertDialog {
Text(
contentText,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 10,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurface,
decoration: TextDecoration.none,
),
),
const SizedBox(height: 4),
Container(
@@ -75,35 +75,29 @@ class AlertWithPickerOption extends BaseAlertDialog {
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Theme.of(context).colorScheme.background),
color: Theme.of(context).colorScheme.surface),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
displayKey,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodySmall!.copyWith(
decoration: TextDecoration.none,
),
),
Row(
children: [
Text(
displayValue,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodySmall!.copyWith(
decoration: TextDecoration.none,
),
),
const SizedBox(width: 4),
Icon(
Icons.arrow_forward_ios,
size: 18,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
color: Theme.of(context).colorScheme.onSurface,
),
],
),
@@ -1,4 +1,3 @@
import 'dart:ui';
import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
import 'package:flutter/cupertino.dart';
+194
View File
@@ -0,0 +1,194 @@
import 'package:flutter/material.dart';
class AnimatedTypingText extends StatefulWidget {
final List<String> words;
final TextStyle? style;
final Duration typingSpeed;
final Duration pauseDuration;
final Color cursorColor;
final double cursorWidth;
final double cursorHeight;
final Duration cursorBlinkDuration;
const AnimatedTypingText({
Key? key,
required this.words,
this.style,
this.typingSpeed = const Duration(milliseconds: 100),
this.pauseDuration = const Duration(milliseconds: 3000),
this.cursorColor = Colors.black,
this.cursorWidth = 2.0,
this.cursorHeight = 20.0,
this.cursorBlinkDuration = const Duration(milliseconds: 500),
}) : super(key: key);
@override
State<AnimatedTypingText> createState() => _AnimatedTypingTextState();
}
class _AnimatedTypingTextState extends State<AnimatedTypingText> with TickerProviderStateMixin {
late AnimationController _controller;
late AnimationController _cursorController;
late Animation<double> _cursorAnimation;
String _displayText = '';
double _maxTextWidth = 0;
int _currentWordIndex = 0;
int _currentCharIndex = 0;
bool _isTyping = true;
bool _isPaused = false;
bool _isWaitingForPause = false;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: widget.typingSpeed,
);
_cursorController = AnimationController(
vsync: this,
duration: widget.cursorBlinkDuration,
)..repeat(reverse: true);
_cursorAnimation = Tween<double>(begin: 1.0, end: 0.0).animate(
CurvedAnimation(
parent: _cursorController,
curve: Curves.easeInOut,
),
);
WidgetsBinding.instance.addPostFrameCallback((_) {
_calculateMaxTextWidth();
});
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_updateText();
if (!_isWaitingForPause) {
_controller.reset();
_controller.forward();
}
}
});
_controller.forward();
}
void _calculateMaxTextWidth() {
final textStyle = widget.style ?? DefaultTextStyle.of(context).style;
double maxWidth = 0;
final textPainter = TextPainter(
textDirection: TextDirection.ltr,
);
for (final word in widget.words) {
textPainter.text = TextSpan(text: word, style: textStyle);
textPainter.layout();
if (textPainter.width > maxWidth) {
maxWidth = textPainter.width;
}
}
setState(() {
_maxTextWidth = maxWidth;
});
}
void _updateText() {
if (_isWaitingForPause) return;
if (_isPaused) {
if (_isTyping) {
_isTyping = false;
_isWaitingForPause = true;
Future.delayed(widget.pauseDuration, () {
if (mounted) {
setState(() {
_isPaused = false;
_isWaitingForPause = false;
_controller.reset();
_controller.forward();
});
}
});
} else {
_deletePrevChar();
}
} else {
if (_isTyping) {
_typeNextChar();
} else {
_deletePrevChar();
}
}
setState(() {
_displayText = widget.words[_currentWordIndex].substring(0, _currentCharIndex);
});
}
void _typeNextChar() {
if (_currentCharIndex < widget.words[_currentWordIndex].length) {
_currentCharIndex++;
} else {
_isPaused = true;
}
}
void _deletePrevChar() {
if (_currentCharIndex > 0) {
_currentCharIndex--;
} else {
_currentWordIndex = (_currentWordIndex + 1) % widget.words.length;
_currentCharIndex = 0;
_isTyping = true;
_isPaused = false;
}
}
@override
void dispose() {
_controller.dispose();
_cursorController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: _maxTextWidth + widget.cursorWidth,
child: Stack(
clipBehavior: Clip.none,
children: [
// Fixed cursor position
Positioned(
right: 0,
child: AnimatedBuilder(
animation: _cursorAnimation,
builder: (context, child) {
return Opacity(
opacity: _cursorAnimation.value,
child: Container(
width: widget.cursorWidth,
height: widget.cursorHeight,
color: widget.cursorColor,
),
);
},
),
),
// Animated text
Align(
alignment: Alignment.centerRight,
child: Text(
_displayText + ' ',
style: widget.style,
),
),
],
),
);
}
}
+79 -81
View File
@@ -1,7 +1,6 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'dart:ui';
import 'package:cake_wallet/src/widgets/section_divider.dart';
import 'package:cake_wallet/themes/extensions/alert_theme.dart';
import 'package:flutter/material.dart';
class BaseAlertDialog extends StatelessWidget {
@@ -49,13 +48,12 @@ class BaseAlertDialog extends StatelessWidget {
return Text(
titleText!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: titleTextSize,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: titleTextSize,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
decoration: TextDecoration.none,
),
);
}
@@ -65,13 +63,12 @@ class BaseAlertDialog extends StatelessWidget {
child: Text(
headerText!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 25,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
decoration: TextDecoration.none,
),
),
);
}
@@ -83,16 +80,13 @@ class BaseAlertDialog extends StatelessWidget {
children: [
contentTextWidget ??
Text(
contentText,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
),
contentText,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
decoration: TextDecoration.none,
),
),
],
),
);
@@ -100,57 +94,59 @@ class BaseAlertDialog extends StatelessWidget {
Widget actionButtons(BuildContext context) {
return Container(
height: 60,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: TextButton(
key: leftActionButtonKey,
onPressed: actionLeft,
style: TextButton.styleFrom(
backgroundColor:
leftActionButtonColor ?? Theme.of(context).dialogBackgroundColor,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.zero))),
child: Text(
leftActionButtonText,
textAlign: TextAlign.center,
style: TextStyle(
height: 60,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: TextButton(
key: leftActionButtonKey,
onPressed: actionLeft,
style: TextButton.styleFrom(
backgroundColor: leftActionButtonColor ?? Theme.of(context).colorScheme.surface,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.zero),
),
),
child: Text(
leftActionButtonText,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 15,
fontWeight: FontWeight.w600,
color: leftActionButtonTextColor ??
Theme.of(context).colorScheme.errorContainer,
decoration: TextDecoration.none,
),
)),
),
const VerticalSectionDivider(),
Expanded(
child: TextButton(
key: rightActionButtonKey,
onPressed: actionRight,
style: TextButton.styleFrom(
backgroundColor: rightActionButtonColor ?? Theme.of(context).colorScheme.surface,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.zero),
),
),
child: Text(
rightActionButtonText,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 15,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: leftActionButtonTextColor ??
Theme.of(context).extension<AlertTheme>()!.leftButtonTextColor,
color: rightActionButtonTextColor ?? Theme.of(context).colorScheme.onSurface,
decoration: TextDecoration.none,
),
)),
),
),
const VerticalSectionDivider(),
Expanded(
child: TextButton(
key: rightActionButtonKey,
onPressed: actionRight,
style: TextButton.styleFrom(
backgroundColor:
rightActionButtonColor ?? Theme.of(context).dialogBackgroundColor,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.zero))),
child: Text(
rightActionButtonText,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: rightActionButtonTextColor ?? Theme.of(context).primaryColor,
decoration: TextDecoration.none,
),
)),
),
],
));
),
],
),
);
}
Widget headerImage(BuildContext context, String imageUrl) {
@@ -160,7 +156,7 @@ class BaseAlertDialog extends StatelessWidget {
right: 0,
child: CircleAvatar(
radius: 50,
backgroundColor: Colors.white,
backgroundColor: Theme.of(context).colorScheme.surfaceContainerHighest,
child: ClipOval(
child: Image.network(
imageUrl,
@@ -182,14 +178,15 @@ class BaseAlertDialog extends StatelessWidget {
filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
child: Container(
decoration:
BoxDecoration(color: Theme.of(context).extension<AlertTheme>()!.backdropColor),
BoxDecoration(color: Theme.of(context).colorScheme.surface.withOpacity(0.8)),
child: Center(
child: GestureDetector(
onTap: () => null,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Theme.of(context).dialogBackgroundColor),
borderRadius: BorderRadius.circular(30),
color: Theme.of(context).colorScheme.surface,
),
width: 300,
child: Stack(
clipBehavior: Clip.none,
@@ -203,11 +200,12 @@ class BaseAlertDialog extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
if (headerText?.isNotEmpty ?? false) headerTitle(context),
titleText != null ?
Padding(
padding: EdgeInsets.fromLTRB(24, 20, 24, 0),
child: title(context),
) : SizedBox(height: 16),
titleText != null
? Padding(
padding: EdgeInsets.fromLTRB(24, 20, 24, 0),
child: title(context),
)
: SizedBox(height: 16),
isDividerExists
? Padding(
padding: EdgeInsets.only(top: 16, bottom: 8),
+125 -65
View File
@@ -1,39 +1,50 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class BaseTextFormField extends StatelessWidget {
BaseTextFormField(
{this.controller,
this.keyboardType = TextInputType.text,
this.textInputAction = TextInputAction.done,
this.textAlign = TextAlign.start,
this.autovalidateMode,
this.hintText = '',
this.maxLines = 1,
this.inputFormatters,
this.textColor,
this.hintColor,
this.borderColor,
this.fillColor,
this.filled,
this.prefix,
this.prefixIcon,
this.suffix,
this.suffixIcon,
this.enabled = true,
this.readOnly = false,
this.enableInteractiveSelection = true,
this.obscureText = false,
this.validator,
this.textStyle,
this.placeholderTextStyle,
this.maxLength,
this.focusNode,
this.initialValue,
this.onSubmit,
this.borderWidth = 1.0,
super.key});
BaseTextFormField({
this.onChanged,
this.controller,
this.keyboardType = TextInputType.text,
this.textInputAction = TextInputAction.done,
this.textAlign = TextAlign.start,
this.autovalidateMode,
this.hintText = '',
this.maxLines = 1,
this.inputFormatters,
this.textColor,
this.hintColor,
this.fillColor,
this.prefix,
this.prefixIcon,
this.suffix,
this.suffixIcon,
this.enabled = true,
this.readOnly = false,
this.enableInteractiveSelection = true,
this.obscureText = false,
this.validator,
this.textStyle,
this.placeholderTextStyle,
this.maxLength,
this.focusNode,
this.initialValue,
this.onSubmit,
this.autofocus = false,
this.autocorrect = true,
this.enableSuggestions = true,
this.contentPadding,
this.alignLabelWithHint = false,
this.floatingLabelBehavior,
this.cursorColor,
this.cursorWidth,
this.isDense,
this.enableIMEPersonalizedLearning,
this.onFieldSubmitted,
this.hasUnderlineBorder = false,
this.borderWidth = 1.0,
super.key,
});
final TextEditingController? controller;
final TextInputType? keyboardType;
@@ -45,9 +56,7 @@ class BaseTextFormField extends StatelessWidget {
final List<TextInputFormatter>? inputFormatters;
final Color? textColor;
final Color? hintColor;
final Color? borderColor;
final Color? fillColor;
bool? filled;
final Widget? prefix;
final Widget? prefixIcon;
final Widget? suffix;
@@ -61,13 +70,33 @@ class BaseTextFormField extends StatelessWidget {
final bool readOnly;
final bool? enableInteractiveSelection;
final String? initialValue;
final double borderWidth;
final void Function(String)? onSubmit;
final bool obscureText;
final bool? autofocus;
final bool? autocorrect;
final bool? enableSuggestions;
final void Function(String)? onChanged;
final EdgeInsetsGeometry? contentPadding;
final bool? alignLabelWithHint;
final FloatingLabelBehavior? floatingLabelBehavior;
final Color? cursorColor;
final double? cursorWidth;
final bool? isDense;
final bool? enableIMEPersonalizedLearning;
final void Function(String)? onFieldSubmitted;
final bool hasUnderlineBorder;
final double borderWidth;
@override
Widget build(BuildContext context) {
return TextFormField(
enableIMEPersonalizedLearning: enableIMEPersonalizedLearning ?? true,
cursorColor: cursorColor,
cursorWidth: cursorWidth ?? 2.0,
onChanged: onChanged,
autofocus: autofocus ?? false,
autocorrect: autocorrect ?? true,
enableSuggestions: enableSuggestions ?? true,
enableInteractiveSelection: enableInteractiveSelection,
readOnly: readOnly,
initialValue: initialValue,
@@ -84,37 +113,68 @@ class BaseTextFormField extends StatelessWidget {
maxLength: maxLength,
onFieldSubmitted: onSubmit,
style: textStyle ??
TextStyle(
fontSize: 16.0,
color: textColor ??
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16.0, color: textColor ?? Theme.of(context).colorScheme.onSurface),
decoration: InputDecoration(
prefix: prefix,
prefixIcon: prefixIcon,
suffix: suffix,
suffixIcon: suffixIcon,
fillColor: fillColor,
filled: filled,
hintStyle: placeholderTextStyle ??
TextStyle(
color: hintColor ?? Theme.of(context).hintColor,
fontSize: 16),
hintText: hintText,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ??
Theme.of(context).extension<CakeTextTheme>()!.textfieldUnderlineColor,
width: borderWidth)),
disabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ??
Theme.of(context).extension<CakeTextTheme>()!.textfieldUnderlineColor,
width: borderWidth)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ??
Theme.of(context).extension<CakeTextTheme>()!.textfieldUnderlineColor,
width: borderWidth))),
isDense: isDense,
alignLabelWithHint: alignLabelWithHint,
contentPadding: contentPadding,
floatingLabelBehavior: FloatingLabelBehavior.never,
prefix: prefix,
prefixIcon: prefixIcon,
suffix: suffix,
suffixIcon: suffixIcon,
filled: !hasUnderlineBorder,
//border: !hasUnderlineBorder ? OutlineInputBorder() : null,
fillColor:
hasUnderlineBorder ? null : fillColor ?? Theme.of(context).colorScheme.surfaceContainer,
hintStyle: placeholderTextStyle ??
Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: hintColor ?? Theme.of(context).hintColor, fontSize: 16),
hintText: hasUnderlineBorder ? hintText : null,
labelText: !hasUnderlineBorder ? hintText : null,
labelStyle: !hasUnderlineBorder ? placeholderTextStyle : null,
focusedBorder: hasUnderlineBorder
? UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.outlineVariant,
style: borderWidth == 0.0 ? BorderStyle.none : BorderStyle.solid,
width: borderWidth,
),
)
: null,
disabledBorder: hasUnderlineBorder
? UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.outlineVariant,
width: borderWidth,
),
)
: null,
enabledBorder: hasUnderlineBorder
? UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.outlineVariant,
style: borderWidth == 1 ? BorderStyle.none : BorderStyle.solid,
width: borderWidth,
),
)
: null,
// OutlineInputBorder(
// borderRadius: BorderRadius.circular(10),
// borderSide: BorderSide(
// color: Theme.of(context).colorScheme.outlineVariant,
// width: 1.5,
// )
// ),
errorBorder: hasUnderlineBorder
? UnderlineInputBorder(
borderSide: BorderSide(color: Theme.of(context).colorScheme.error),
)
: null,
),
validator: validator,
);
}
+34 -34
View File
@@ -1,6 +1,5 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/src/widgets/standard_switch.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/utils/date_picker.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/wallet_type.dart';
@@ -10,8 +9,6 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/decred/decred.dart';
import 'package:cw_core/wallet_type.dart';
class BlockchainHeightWidget extends StatefulWidget {
BlockchainHeightWidget({
@@ -83,18 +80,22 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
Row(
children: <Widget>[
Flexible(
child: Container(
padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
child: BaseTextFormField(
key: widget.blockHeightTextFieldKey,
focusNode: widget.focusNode,
controller: restoreHeightController,
keyboardType:
TextInputType.numberWithOptions(signed: false, decimal: false),
hintText: widget.isSilentPaymentsScan
? S.of(context).silent_payments_scan_from_height
: S.of(context).widgets_restore_from_blockheight,
)))
child: Container(
padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
child: BaseTextFormField(
key: widget.blockHeightTextFieldKey,
focusNode: widget.focusNode,
controller: restoreHeightController,
keyboardType: TextInputType.numberWithOptions(
signed: false,
decimal: false,
),
hintText: widget.isSilentPaymentsScan
? S.of(context).silent_payments_scan_from_height
: S.of(context).widgets_restore_from_blockheight,
),
),
)
],
),
if (widget.hasDatePicker) ...[
@@ -102,10 +103,11 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
padding: EdgeInsets.only(top: 15, bottom: 15),
child: Text(
S.of(context).widgets_or,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
Row(
@@ -115,12 +117,13 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
child: InkWell(
onTap: () => _selectDate(context),
child: IgnorePointer(
child: BaseTextFormField(
controller: dateController,
hintText: widget.isSilentPaymentsScan
? S.of(context).silent_payments_scan_from_date
: S.of(context).widgets_restore_from_date,
)),
child: BaseTextFormField(
controller: dateController,
hintText: widget.isSilentPaymentsScan
? S.of(context).silent_payments_scan_from_date
: S.of(context).widgets_restore_from_date,
),
),
),
))
],
@@ -133,11 +136,9 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
children: [
Text(
S.of(context).scan_one_block,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
Padding(
padding: const EdgeInsets.only(right: 8),
@@ -156,10 +157,9 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
? S.of(context).silent_payments_scan_from_date_or_blockheight
: S.of(context).restore_from_date_or_blockheight,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
color: Theme.of(context).hintColor),
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
)
]
@@ -1,10 +1,9 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/core/material_base_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class AddPassphraseBottomSheet extends StatefulWidget {
AddPassphraseBottomSheet({
@@ -14,7 +13,7 @@ class AddPassphraseBottomSheet extends StatefulWidget {
});
final void Function(String) onRestoreButtonPressed;
final ThemeBase currentTheme;
final MaterialThemeBase currentTheme;
@override
State<AddPassphraseBottomSheet> createState() => _AddPassphraseBottomSheetState();
@@ -38,13 +37,19 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
super.dispose();
}
final passphraseImageLight = 'assets/images/passphrase_light.png';
final passphraseImageDark = 'assets/images/passphrase_dark.png';
bool obscurePassphrase = true;
@override
Widget build(BuildContext context) {
final passphraseImage = widget.currentTheme.isDark ? passphraseImageDark : passphraseImageLight;
return Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.vertical(top: Radius.circular(30.0)),
color: Theme.of(context).dialogBackgroundColor,
color: Theme.of(context).colorScheme.surface,
),
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
@@ -59,8 +64,7 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
height: 6,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.6),
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
),
@@ -71,15 +75,16 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
Text(
S.of(context).add_passphrase,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
decoration: TextDecoration.none,
),
),
SvgPicture.asset('assets/images/passphrase_key.svg'),
SizedBox(height: 20),
CakeImageWidget(imageUrl: passphraseImage, height: 85),
SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text.rich(
@@ -87,13 +92,12 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
children: [
TextSpan(
text: '${S.of(context).warning.toUpperCase()}: ',
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w700,
color: Palette.red,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontWeight: FontWeight.w700,
color: Theme.of(context).colorScheme.errorContainer,
decoration: TextDecoration.none,
),
),
TextSpan(
text: S.of(context).add_passphrase_warning_text,
@@ -101,68 +105,51 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
],
),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.7),
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
decoration: TextDecoration.none,
),
),
),
SizedBox(height: 24),
TextFormField(
BaseTextFormField(
key: ValueKey('add_passphrase_bottom_sheet_widget_passphrase_textfield_key'),
controller: passphraseController,
obscureText: obscurePassphrase,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 12),
filled: true,
fillColor: Theme.of(context).cardColor,
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).textTheme.bodyLarge?.color?.withOpacity(0.6),
),
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(16),
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),
TextFormField(
BaseTextFormField(
key: ValueKey('add_passphrase_bottom_sheet_widget_confirm_passphrase_textfield_key'),
controller: confirmPassphraseController,
obscureText: obscurePassphrase,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 12),
filled: true,
fillColor: Theme.of(context).cardColor,
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).textTheme.bodyLarge?.color?.withOpacity(0.6),
),
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(16),
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) {
@@ -188,8 +175,8 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
Navigator.pop(context);
},
text: S.of(context).cancel,
color: Theme.of(context).cardColor,
textColor: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
color: Theme.of(context).colorScheme.surfaceContainer,
textColor: Theme.of(context).colorScheme.onSurface,
),
),
),
@@ -203,8 +190,8 @@ class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
widget.onRestoreButtonPressed(passphraseController.text);
},
text: S.of(context).restore,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
),
),
),
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
abstract class BaseBottomSheet extends StatelessWidget {
final String titleText;
@@ -21,7 +20,7 @@ abstract class BaseBottomSheet extends StatelessWidget {
height: 6,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
@@ -40,17 +39,15 @@ abstract class BaseBottomSheet extends StatelessWidget {
Text(
titleText,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.titleLarge!.copyWith(
fontSize: 20,
fontWeight: FontWeight.w600,
decoration: TextDecoration.none,
),
),
],
),
const SizedBox(height: 13),
const SizedBox(height: 24),
],
);
}
@@ -67,7 +64,7 @@ abstract class BaseBottomSheet extends StatelessWidget {
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0)),
child: Container(
color: Theme.of(context).dialogBackgroundColor,
color: Theme.of(context).colorScheme.surface,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
@@ -1,10 +1,6 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/standard_slide_button_widget.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/core/material_base_theme.dart';
import 'package:cake_wallet/utils/address_formatter.dart';
import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cw_core/crypto_currency.dart';
@@ -16,7 +12,7 @@ import 'base_bottom_sheet_widget.dart';
class ConfirmSendingBottomSheet extends BaseBottomSheet {
final CryptoCurrency currency;
final ThemeBase currentTheme;
final MaterialThemeBase currentTheme;
final String? paymentId;
final String? paymentIdValue;
final String? expirationTime;
@@ -60,28 +56,18 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
@override
Widget contentWidget(BuildContext context) {
final itemTitleTextStyle = TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
);
final itemSubTitleTextStyle = TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: currentTheme.type == ThemeType.bright
? Theme.of(context).extension<CakeTextTheme>()!.titleColor
: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
decoration: TextDecoration.none,
);
final itemTitleTextStyle = Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
decoration: TextDecoration.none,
);
final itemSubTitleTextStyle = Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurfaceVariant,
decoration: TextDecoration.none,
);
final tileBackgroundColor = currentTheme.type == ThemeType.light
? Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor
: currentTheme.type == ThemeType.oled
? Colors.black.withOpacity(0.5)
: Theme.of(context).extension<FilterTheme>()!.buttonColor;
final tileBackgroundColor = Theme.of(context).colorScheme.surfaceContainer;
Widget content = Padding(
padding: EdgeInsets.fromLTRB(8, 0, showScrollbar ? 16 : 8, 8),
@@ -92,7 +78,6 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
padding: const EdgeInsets.only(bottom: 8),
child: AddressTile(
itemTitle: paymentId!,
currentTheme: currentTheme,
itemTitleTextStyle: itemTitleTextStyle,
walletType: walletType,
isBatchSending: false,
@@ -139,7 +124,6 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
return isBatchSending || contactName.isNotEmpty
? AddressExpansionTile(
contactType: isOpenCryptoPay ? 'Open CryptoPay' : S.of(context).contact,
currentTheme: currentTheme,
name: isBatchSending ? batchContactTitle : contactName,
address: _address,
amount: _amount,
@@ -151,7 +135,6 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
)
: AddressTile(
itemTitle: S.of(context).address,
currentTheme: currentTheme,
itemTitleTextStyle: itemTitleTextStyle,
isBatchSending: isBatchSending,
walletType: walletType,
@@ -167,7 +150,6 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
padding: const EdgeInsets.only(top: 8),
child: AddressExpansionTile(
contactType: 'Change',
currentTheme: currentTheme,
name: S.of(context).send_change_to_you,
address: change!.address,
amount: change!.amount + ' ${currency.title}',
@@ -208,11 +190,11 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
return Container(
padding: const EdgeInsets.fromLTRB(40, 12, 40, 34),
decoration: BoxDecoration(
color: Theme.of(context).dialogBackgroundColor,
color: Theme.of(context).colorScheme.surface,
boxShadow: [
if (showScrollbar)
BoxShadow(
color: Colors.black.withOpacity(0.5),
color: Theme.of(context).colorScheme.outlineVariant,
spreadRadius: 2,
blurRadius: 10,
offset: const Offset(0, 0),
@@ -254,8 +236,10 @@ class StandardTile extends StatelessWidget {
label: itemTitle,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(10), color: tileBackgroundColor),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: tileBackgroundColor,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -280,7 +264,6 @@ class AddressTile extends StatelessWidget {
const AddressTile({
super.key,
required this.itemTitle,
required this.currentTheme,
required this.itemTitleTextStyle,
required this.isBatchSending,
required this.amount,
@@ -291,7 +274,6 @@ class AddressTile extends StatelessWidget {
});
final String itemTitle;
final ThemeBase currentTheme;
final TextStyle itemTitleTextStyle;
final bool isBatchSending;
final String amount;
@@ -321,12 +303,10 @@ class AddressTile extends StatelessWidget {
AddressFormatter.buildSegmentedAddress(
address: address,
walletType: walletType,
evenTextStyle: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none)
evenTextStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w600,
decoration: TextDecoration.none,
),
),
],
),
@@ -338,7 +318,6 @@ class AddressExpansionTile extends StatelessWidget {
const AddressExpansionTile({
super.key,
required this.contactType,
required this.currentTheme,
required this.name,
required this.address,
required this.amount,
@@ -350,7 +329,6 @@ class AddressExpansionTile extends StatelessWidget {
});
final String contactType;
final ThemeBase currentTheme;
final String name;
final String address;
final String amount;
@@ -378,21 +356,25 @@ class AddressExpansionTile extends StatelessWidget {
childrenPadding: isBatchSending ? const EdgeInsets.only(bottom: 8) : EdgeInsets.zero,
tilePadding: EdgeInsets.zero,
dense: true,
iconColor: Theme.of(context).colorScheme.onSurfaceVariant,
visualDensity: VisualDensity.compact,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(isBatchSending ? name : contactType,
style: itemTitleTextStyle, softWrap: true)),
Text(isBatchSending ? amount : name,
style: TextStyle(
fontSize: 14,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
)),
child: Text(
isBatchSending ? name : contactType,
style: itemTitleTextStyle,
softWrap: true,
),
),
Text(
isBatchSending ? amount : name,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w600,
decoration: TextDecoration.none,
),
),
],
),
children: [
@@ -400,14 +382,12 @@ class AddressExpansionTile extends StatelessWidget {
children: [
Expanded(
child: AddressFormatter.buildSegmentedAddress(
address: address,
walletType: walletType,
evenTextStyle: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
address: address,
walletType: walletType,
evenTextStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none)
decoration: TextDecoration.none,
),
),
),
],
@@ -1,9 +1,6 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/core/material_base_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
@@ -26,7 +23,7 @@ class LoadingBottomSheet extends BaseBottomSheet {
}
class InfoBottomSheet extends BaseBottomSheet {
final ThemeBase currentTheme;
final MaterialThemeBase currentTheme;
final String? contentImage;
final Color? contentImageColor;
final String? content;
@@ -89,13 +86,13 @@ class InfoBottomSheet extends BaseBottomSheet {
child: AutoSizeText(
content!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurfaceVariant,
decoration: TextDecoration.none,
),
),
),
const Spacer(flex: 2),
@@ -112,13 +109,11 @@ class InfoBottomSheet extends BaseBottomSheet {
Text(
'Don’t ask me next time',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurfaceVariant,
decoration: TextDecoration.none,
),
),
],
),
@@ -143,12 +138,12 @@ class InfoBottomSheet extends BaseBottomSheet {
key: leftActionButtonKey,
onPressed: actionLeftButton,
text: leftButtonText ?? '',
color: currentTheme.type == ThemeType.dark
? Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor
: Theme.of(context).cardColor,
textColor: currentTheme.type == ThemeType.dark
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
color: currentTheme.isDark
? Theme.of(context).colorScheme.surfaceContainerLow
: Theme.of(context).colorScheme.surfaceContainer,
textColor: currentTheme.isDark
? Theme.of(context).colorScheme.onSurfaceVariant
: Theme.of(context).colorScheme.onPrimary,
),
),
),
@@ -159,10 +154,10 @@ class InfoBottomSheet extends BaseBottomSheet {
key: rightActionButtonKey,
onPressed: actionRightButton,
text: rightButtonText ?? '',
color: Theme.of(context).primaryColor,
textColor: currentTheme.type == ThemeType.dark
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
color: Theme.of(context).colorScheme.primary,
textColor: currentTheme.isDark
? Theme.of(context).colorScheme.onSurfaceVariant
: Theme.of(context).colorScheme.onPrimary,
),
),
),
@@ -176,8 +171,8 @@ class InfoBottomSheet extends BaseBottomSheet {
key: actionButtonKey,
onPressed: actionButton ?? () {},
text: actionButtonText ?? '',
color: Theme.of(context).primaryColor,
textColor: Colors.white,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
isLoading: false,
isDisabled: false,
),
@@ -221,11 +216,11 @@ class _SimpleCheckboxState extends State<SimpleCheckbox> {
initialValue = value!;
widget.onChanged?.call(value);
}),
checkColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
checkColor: Theme.of(context).colorScheme.onSurfaceVariant,
activeColor: Colors.transparent,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
side: WidgetStateBorderSide.resolveWith((states) => BorderSide(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor, width: 1.0)),
side: WidgetStateBorderSide.resolveWith((states) =>
BorderSide(color: Theme.of(context).colorScheme.onSurfaceVariant, width: 1.0)),
),
);
}
+82 -43
View File
@@ -1,59 +1,98 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CakeImageWidget extends StatelessWidget {
CakeImageWidget({
required this.imageUrl,
Widget? displayOnError,
const CakeImageWidget({
super.key,
this.imageUrl,
this.height,
this.width,
}) : _displayOnError = displayOnError ?? Icon(Icons.error);
this.fit = BoxFit.cover,
this.loadingWidget,
this.errorWidget,
this.color,
});
final String? imageUrl;
final double? height;
final double? width;
final Widget? _displayOnError;
final BoxFit fit;
final Widget? loadingWidget;
final Widget? errorWidget;
final Color? color;
@override
Widget build(BuildContext context) {
try {
if (imageUrl == null || imageUrl!.isEmpty) return _displayOnError!;
if (imageUrl!.contains('assets/images')) {
return Image.asset(
imageUrl!,
height: height,
width: width,
errorBuilder: (_, __, ___) => Icon(Icons.error),
);
}
if (imageUrl!.contains('.svg')) {
return SvgPicture.network(
imageUrl!,
height: height,
width: width,
placeholderBuilder: (_) => Icon(Icons.error),
);
}
return Image.network(
imageUrl!,
fit: BoxFit.cover,
height: height,
width: width,
loadingBuilder: (BuildContext _, Widget child, ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return CupertinoActivityIndicator(animating: true);
}
},
errorBuilder: (_, __, ___) => Icon(Icons.error),
);
} catch (_) {
return _displayOnError!;
if (imageUrl == null || imageUrl!.isEmpty) {
return _buildErrorWidget(context);
}
final isSvg = imageUrl!.toLowerCase().endsWith('.svg');
final isAsset = imageUrl!.startsWith('assets/');
Widget imageWidget;
if (isAsset) {
imageWidget = isSvg
? SvgPicture.asset(
imageUrl!,
height: height,
width: width,
fit: fit,
color: color,
)
: Image.asset(
imageUrl!,
height: height,
width: width,
fit: fit,
color: color,
);
} else {
imageWidget = isSvg
? SvgPicture.network(
imageUrl!,
height: height,
width: width,
fit: fit,
color: color,
placeholderBuilder: (_) {
return loadingWidget ?? const Center(child: CircularProgressIndicator());
},
errorBuilder: (_, __, ___) => _buildErrorWidget(context),
)
: Image.network(
imageUrl!,
height: height,
width: width,
fit: fit,
color: color,
loadingBuilder: (_, Widget child, ImageChunkEvent? progress) {
if (progress == null) return child;
return loadingWidget ?? const Center(child: CircularProgressIndicator());
},
errorBuilder: (_, __, ___) => _buildErrorWidget(context),
);
}
return imageWidget;
}
Widget _buildErrorWidget(BuildContext context) {
return Container(
height: height,
width: width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
color: Theme.of(context).colorScheme.surfaceContainerHighest,
),
child: Center(
child: errorWidget ??
Icon(
Icons.error_outline,
color: Theme.of(context).colorScheme.error,
size: 24,
),
),
);
}
}
+2 -5
View File
@@ -1,4 +1,3 @@
import 'package:cake_wallet/themes/extensions/cake_scrollbar_theme.dart';
import 'package:flutter/material.dart';
class CakeScrollbar extends StatelessWidget {
@@ -28,8 +27,7 @@ class CakeScrollbar extends StatelessWidget {
height: backgroundHeight,
width: width,
decoration: BoxDecoration(
color: backgroundColor ??
Theme.of(context).extension<CakeScrollbarTheme>()!.trackColor,
color: backgroundColor ?? Theme.of(context).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.all(Radius.circular(3))),
child: Stack(
children: <Widget>[
@@ -40,8 +38,7 @@ class CakeScrollbar extends StatelessWidget {
height: thumbHeight,
width: width,
decoration: BoxDecoration(
color: thumbColor ??
Theme.of(context).extension<CakeScrollbarTheme>()!.thumbColor,
color: thumbColor ?? Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.all(Radius.circular(3))),
),
)
+16 -22
View File
@@ -1,11 +1,7 @@
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
class CheckBoxPicker extends StatefulWidget {
CheckBoxPicker({
@@ -43,12 +39,12 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
child: Text(
widget.title,
textAlign: TextAlign.center,
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
decoration: TextDecoration.none,
color: Colors.white,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
@@ -57,7 +53,7 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(30)),
child: Container(
color: Theme.of(context).dialogTheme.backgroundColor,
color: Theme.of(context).colorScheme.surfaceContainer,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.65,
@@ -91,14 +87,14 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
Widget itemsList() {
return Container(
color: Theme.of(context).extension<PickerTheme>()!.dividerColor,
color: Theme.of(context).colorScheme.outlineVariant,
child: ListView.separated(
padding: EdgeInsets.zero,
controller: controller,
shrinkWrap: true,
separatorBuilder: (context, index) => widget.isSeparated
? Divider(
color: Theme.of(context).extension<PickerTheme>()!.dividerColor,
color: Theme.of(context).colorScheme.outlineVariant,
height: 1,
)
: const SizedBox(),
@@ -120,15 +116,15 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
},
child: Container(
height: 55,
color: Theme.of(context).dialogTheme.backgroundColor,
color: Theme.of(context).colorScheme.surfaceContainer,
padding: EdgeInsets.only(left: 24, right: 24),
child: Row(
children: [
StandardCheckbox(
value: item.value,
gradientBackground: true,
borderColor: Theme.of(context).dividerColor,
iconColor: Colors.white,
borderColor: Theme.of(context).colorScheme.outlineVariant,
iconColor: Theme.of(context).colorScheme.onPrimary,
onChanged: (bool? value) {
if (value == null) {
return;
@@ -143,15 +139,13 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
widget.displayItem?.call(item) ??
Text(
item.title,
style: TextStyle(
fontSize: 14,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: item.isDisabled
? Colors.grey.withOpacity(0.5)
: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w600,
color: item.isDisabled
? Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.5)
: Theme.of(context).colorScheme.onSurface,
decoration: TextDecoration.none,
),
)
],
),
+8 -18
View File
@@ -1,8 +1,4 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
class CheckboxWidget extends StatefulWidget {
CheckboxWidget({required this.value, required this.caption, required this.onChanged});
@@ -38,20 +34,16 @@ class CheckboxWidgetState extends State<CheckboxWidget> {
margin: EdgeInsets.only(right: 10.0),
decoration: BoxDecoration(
border: Border.all(
color: value
? Palette.blueCraiola
: Theme.of(context).extension<FilterTheme>()!.checkboxBoundsColor,
color: Theme.of(context).colorScheme.outline,
width: 1.0,
),
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
color: Theme.of(context).colorScheme.surface,
),
child: value
? Icon(
Icons.check,
color: Colors.blue,
color: Theme.of(context).colorScheme.primary,
size: 20.0,
)
: null,
@@ -59,15 +51,13 @@ class CheckboxWidgetState extends State<CheckboxWidget> {
Expanded(
child: Text(
caption,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
)
],
)
),
);
}
}
+35 -28
View File
@@ -1,9 +1,8 @@
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../themes/utils/custom_theme_colors.dart';
class DashBoardRoundedCardWidget extends StatelessWidget {
DashBoardRoundedCardWidget({
this.onTap,
@@ -20,6 +19,7 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
super.key,
this.marginV,
this.marginH,
required this.isDarkTheme,
});
final VoidCallback? onTap;
@@ -35,17 +35,29 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
final double? marginH;
final double? shadowSpread;
final double? shadowBlur;
final bool isDarkTheme;
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: marginH ?? 20, vertical: marginV ?? 8),
//padding: EdgeInsets.all(20),
margin: EdgeInsets.symmetric(horizontal: marginH ?? 20, vertical: marginV ?? 5),
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(customBorder ?? 20),
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
colors: [
isDarkTheme
? CustomThemeColors.cardGradientColorPrimaryDark
: CustomThemeColors.cardGradientColorPrimaryLight,
isDarkTheme
? CustomThemeColors.cardGradientColorSecondaryDark
: CustomThemeColors.cardGradientColorSecondaryLight,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
// border: Border.all(
// color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
// width: 1
@@ -59,15 +71,14 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
// )
// ],
),
child: OutlinedButton(
child: TextButton(
onPressed: onTap,
style: OutlinedButton.styleFrom(
side: BorderSide(width: 1, color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor),
backgroundColor:
Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(customBorder ?? 20)),
padding: EdgeInsets.all(24)),
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
padding: EdgeInsets.only(left: 24, top: 24, right: 20, bottom: 24),
),
child: Column(
children: [
Row(
@@ -79,24 +90,20 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
children: [
Text(
title,
style: TextStyle(
color: Theme.of(context)
.extension<DashboardPageTheme>()!
.cardTextColor,
fontSize: 24,
fontWeight: FontWeight.w900,
),
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.w800,
fontSize: 24,
),
softWrap: true,
),
SizedBox(height: 5),
Text(
subTitle,
style: TextStyle(
color: Theme.of(context)
.extension<DashboardPageTheme>()!
.cardTextColor,
fontWeight: FontWeight.w500,
fontFamily: 'Lato'),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontWeight: FontWeight.w500,
),
softWrap: true,
),
],
@@ -121,7 +128,7 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
child: IconButton(
icon: Icon(Icons.close),
onPressed: onClose,
color: Theme.of(context).extension<DashboardPageTheme>()!.cardTextColor,
//color: Theme.of(context).colorScheme.onSurface,
),
),
],
+6 -7
View File
@@ -18,13 +18,12 @@ class DiscountBadge extends StatelessWidget {
return Container(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Text(
isAmount ? '\$${percentage.toStringAsFixed(2)}' : S.of(context).discount(percentage.toStringAsFixed(2)),
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
),
isAmount
? '\$${percentage.toStringAsFixed(2)}'
: S.of(context).discount(percentage.toStringAsFixed(2)),
style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w500,
),
),
decoration: BoxDecoration(
image: DecorationImage(
+14 -16
View File
@@ -1,4 +1,4 @@
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
import 'package:flutter/material.dart';
class GradientBackground extends StatelessWidget {
@@ -9,22 +9,20 @@ class GradientBackground extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
gradient: LinearGradient(
colors: [
Theme.of(context)
.extension<DashboardPageTheme>()!
.firstGradientBackgroundColor,
Theme.of(context)
.extension<DashboardPageTheme>()!
.secondGradientBackgroundColor,
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor,
Theme.of(context).colorScheme.surface,
Theme.of(context).brightness == Brightness.dark
? CustomThemeColors.backgroundGradientColorDark
: CustomThemeColors.backgroundGradientColorLight,
],
begin: Alignment.topRight,
end: Alignment.bottomLeft,
)),
child: scaffold);
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: scaffold,
);
}
}
@@ -1,6 +1,5 @@
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:flutter/material.dart';
class HavenWalletRemovalPopup extends StatelessWidget {
@@ -23,10 +22,8 @@ class HavenWalletRemovalPopup extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
gradient: LinearGradient(colors: [
Theme.of(context).extension<DashboardPageTheme>()!.firstGradientBackgroundColor,
Theme.of(context)
.extension<DashboardPageTheme>()!
.secondGradientBackgroundColor,
Theme.of(context).colorScheme.primaryContainer,
Theme.of(context).colorScheme.secondaryContainer,
], begin: Alignment.centerLeft, end: Alignment.centerRight)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
@@ -38,12 +35,12 @@ class HavenWalletRemovalPopup extends StatelessWidget {
child: Container(
alignment: Alignment.bottomCenter,
child: DefaultTextStyle(
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
decoration: TextDecoration.none,
fontSize: 24.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
child: Text("Emergency Notice"),
),
@@ -63,13 +60,11 @@ class HavenWalletRemovalPopup extends StatelessWidget {
),
child: Text(
"It looks like you have Haven wallets in your list. Haven is getting removed in next release of Cake Wallet, and you currently have Haven in the following wallets:\n\n[${affectedWalletNames.join(", ")}]\n\nPlease move your funds to other wallet, as you will lose access to your Haven funds in next update.\n\nFor assistance, please use the in-app support or email support@cakewallet.com",
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
decoration: TextDecoration.none,
fontSize: 16.0,
fontFamily: 'Lato',
color: Theme.of(context)
.extension<DashboardPageTheme>()!
.textColor,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
)
+35 -36
View File
@@ -1,15 +1,12 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/generated/i18n.dart';
class IntroducingCard extends StatelessWidget {
IntroducingCard(
{required this.borderColor,
required this.closeCard,
required this.title,
{required this.borderColor,
required this.closeCard,
required this.title,
required this.subTitle});
final String title;
@@ -20,16 +17,17 @@ class IntroducingCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(16,0,16,16),
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
border: Border.all(
color: borderColor,
width: 1,
),
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor),
borderRadius: BorderRadius.circular(30.0),
border: Border.all(
color: borderColor,
width: 1,
),
color: Theme.of(context).colorScheme.surfaceContainer,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -42,30 +40,28 @@ class IntroducingCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(title ?? '',
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
AutoSizeText(
title,
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold,
color: Theme.of(context).extension<DashboardPageTheme>()!.cardTextColor,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
height: 1,
),
maxLines: 1,
textAlign: TextAlign.center,
),
SizedBox(height: 14),
Text(subTitle ?? '',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
color: Theme.of(context).extension<DashboardPageTheme>()!.cardTextColor,
height: 1)),
Text(
subTitle,
textAlign: TextAlign.left,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0,16,16,0),
padding: const EdgeInsets.fromLTRB(0, 16, 16, 0),
child: Semantics(
label: S.of(context).close,
child: GestureDetector(
@@ -74,14 +70,17 @@ class IntroducingCard extends StatelessWidget {
height: 23,
width: 23,
decoration: BoxDecoration(
color: Colors.white, shape: BoxShape.circle),
color: Theme.of(context).colorScheme.surfaceContainer,
shape: BoxShape.circle,
),
child: Center(
child: Image.asset(
'assets/images/x.png',
color: Palette.darkBlueCraiola,
height: 15,
width: 15,
)),
child: Image.asset(
'assets/images/x.png',
color: Theme.of(context).colorScheme.onSurface,
height: 15,
width: 15,
),
),
),
),
),
+7 -4
View File
@@ -1,19 +1,22 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class KeyboardDoneButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
// FIXME: Add translation
return CupertinoButton(
padding: EdgeInsets.only(right: 24.0, top: 8.0, bottom: 8.0),
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Text(
'Done',
style: TextStyle(color: Colors.blueAccent,fontWeight: FontWeight.bold)
S.of(context).done,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.primary,
fontWeight: FontWeight.bold,
),
),
);
}
}
}
+49 -50
View File
@@ -1,20 +1,17 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class ListRow extends StatelessWidget {
ListRow({
required this.title,
required this.value,
this.titleFontSize = 14,
this.valueFontSize = 16,
this.image,
this.padding,
this.color,
this.hintTextColor,
this.mainTextColor,
this.textWidget
});
ListRow(
{required this.title,
required this.value,
this.titleFontSize = 14,
this.valueFontSize = 16,
this.image,
this.padding,
this.color,
this.hintTextColor,
this.mainTextColor,
this.textWidget});
final String title;
final String value;
@@ -27,50 +24,52 @@ class ListRow extends StatelessWidget {
final Color? mainTextColor;
final Widget? textWidget;
Widget _getTextWidget (BuildContext context) => textWidget ?? Text(
value,
style: TextStyle(
fontSize: valueFontSize,
fontWeight: FontWeight.w500,
color: mainTextColor ?? Theme.of(context).extension<CakeTextTheme>()!.titleColor
),
);
Widget _getTextWidget(BuildContext context) =>
textWidget ??
Text(
value,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: valueFontSize,
fontWeight: FontWeight.w500,
color: mainTextColor,
),
);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
color: color ?? Theme.of(context).colorScheme.background,
color: color ?? Theme.of(context).colorScheme.surface,
child: Padding(
padding: padding ?? const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(title,
style: TextStyle(
fontSize: titleFontSize,
fontWeight: FontWeight.w500,
color: hintTextColor ?? Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor),
textAlign: TextAlign.left),
Padding(
padding: const EdgeInsets.only(top: 12),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: _getTextWidget(context)),
image != null
? Padding(
padding: EdgeInsets.only(left: 24),
child: image,
)
: Offstage()
],
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
title,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: titleFontSize,
fontWeight: FontWeight.w500,
color: hintTextColor,
),
)
]),
textAlign: TextAlign.left,
),
Padding(
padding: const EdgeInsets.only(top: 12),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(child: _getTextWidget(context)),
image != null
? Padding(
padding: EdgeInsets.only(left: 24),
child: image,
)
: Offstage()
],
),
)
]),
),
);
}
+51 -36
View File
@@ -1,4 +1,3 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -57,16 +56,16 @@ class _NumberTextFieldState extends State<NumberTextField> {
@override
Widget build(BuildContext context) => TextField(
style: textMediumSemiBold(color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
enableInteractiveSelection: false,
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.bottom,
controller: _controller,
focusNode: _focusNode,
textInputAction: TextInputAction.done,
keyboardType: TextInputType.number,
maxLength: widget.max.toString().length + (widget.min.isNegative ? 1 : 0),
decoration: InputDecoration(
style: textMediumSemiBold(color: Theme.of(context).colorScheme.onSurfaceVariant),
enableInteractiveSelection: false,
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.bottom,
controller: _controller,
focusNode: _focusNode,
textInputAction: TextInputAction.done,
keyboardType: TextInputType.number,
maxLength: widget.max.toString().length + (widget.min.isNegative ? 1 : 0),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.all(0),
fillColor: Colors.transparent,
@@ -74,34 +73,50 @@ class _NumberTextFieldState extends State<NumberTextField> {
isDense: true,
filled: true,
suffixIconConstraints: BoxConstraints(
maxHeight: widget.arrowsHeight,
maxWidth: widget.arrowsWidth + widget.contentPadding.right),
maxHeight: widget.arrowsHeight,
maxWidth: widget.arrowsWidth + widget.contentPadding.right,
),
prefixIconConstraints: BoxConstraints(
maxHeight: widget.arrowsHeight,
maxWidth: widget.arrowsWidth + widget.contentPadding.left),
maxHeight: widget.arrowsHeight,
maxWidth: widget.arrowsWidth + widget.contentPadding.left,
),
prefixIcon: Material(
type: MaterialType.transparency,
child: InkWell(
child: Container(
width: widget.arrowsWidth,
alignment: Alignment.bottomCenter,
child: Icon(Icons.arrow_left_outlined, size: widget.arrowsWidth)),
onTap: _canGoDown ? () => _update(false) : null)),
type: MaterialType.transparency,
child: InkWell(
child: Container(
width: widget.arrowsWidth,
alignment: Alignment.bottomCenter,
child: Icon(
Icons.arrow_left_outlined,
size: widget.arrowsWidth,
),
),
onTap: _canGoDown ? () => _update(false) : null,
),
),
suffixIcon: Material(
type: MaterialType.transparency,
child: InkWell(
child: Container(
width: widget.arrowsWidth,
alignment: Alignment.bottomCenter,
child: Icon(Icons.arrow_right_outlined, size: widget.arrowsWidth)),
onTap: _canGoUp ? () => _update(true) : null))),
maxLines: 1,
onChanged: (value) {
final intValue = int.tryParse(value);
widget.onChanged?.call(intValue);
_updateArrows(intValue);
},
inputFormatters: [_NumberTextInputFormatter(widget.min, widget.max)]);
type: MaterialType.transparency,
child: InkWell(
child: Container(
width: widget.arrowsWidth,
alignment: Alignment.bottomCenter,
child: Icon(
Icons.arrow_right_outlined,
size: widget.arrowsWidth,
),
),
onTap: _canGoUp ? () => _update(true) : null,
),
),
),
maxLines: 1,
onChanged: (value) {
final intValue = int.tryParse(value);
widget.onChanged?.call(intValue);
_updateArrows(intValue);
},
inputFormatters: [_NumberTextInputFormatter(widget.min, widget.max)],
);
void _update(bool up) {
var intValue = int.tryParse(_controller.text);
+12 -20
View File
@@ -1,4 +1,3 @@
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:flutter/material.dart';
class OptionTile extends StatelessWidget {
@@ -21,13 +20,12 @@ class OptionTile extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: EdgeInsets.only(left: 6, right: 6),
alignment: Alignment.center,
child: TextButton(
child: ElevatedButton(
style: TextButton.styleFrom(
backgroundColor: Theme.of(context).cardColor,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
padding: EdgeInsets.all(24)
backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
padding: EdgeInsets.all(24),
),
onPressed: onPressed,
child: Row(
@@ -46,25 +44,19 @@ class OptionTile extends StatelessWidget {
children: <Widget>[
Text(
title,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.extension<OptionTileTheme>()!
.titleColor,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurface,
),
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
description,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.extension<OptionTileTheme>()!
.descriptionColor,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
)
],
+50 -59
View File
@@ -9,11 +9,7 @@ import 'package:cw_core/transaction_priority.dart';
import 'package:flutter/material.dart';
import 'package:cw_core/currency.dart';
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_scrollbar_theme.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
//TODO(David): PickerWidget is intertwined and confusing as is, find a way to optimize?
class Picker<Item> extends StatefulWidget {
Picker({
required this.selectedAtIndex,
@@ -159,13 +155,13 @@ class _PickerState<Item> extends State<Picker<Item>> {
key: ValueKey('picker_title_text_key'),
widget.title!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
decoration: TextDecoration.none,
color: Colors.white,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 18,
fontWeight: FontWeight.bold,
decoration: TextDecoration.none,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
Padding(
@@ -180,7 +176,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(30)),
child: Container(
color: Theme.of(context).dialogTheme.backgroundColor,
color: Theme.of(context).colorScheme.surface,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: containerHeight,
@@ -189,7 +185,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (widget.hintText != null)
if (widget.hintText != null) ...[
Padding(
padding: const EdgeInsets.all(16),
child: SearchBarWidget(
@@ -198,10 +194,11 @@ class _PickerState<Item> extends State<Picker<Item>> {
hintText: widget.hintText,
),
),
Divider(
color: Theme.of(context).extension<PickerTheme>()!.dividerColor,
height: 1,
),
Divider(
color: Theme.of(context).colorScheme.outlineVariant,
height: 1,
),
],
if (widget.selectedAtIndex != -1 && widget.headerEnabled)
buildSelectedItem(widget.selectedAtIndex),
Flexible(
@@ -224,15 +221,10 @@ class _PickerState<Item> extends State<Picker<Item>> {
key: ValueKey('picker_descriptinon_text_key'),
widget.description!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
decoration: TextDecoration.none,
color: Theme.of(context)
.extension<CakeTextTheme>()!
.titleColor,
),
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w500,
decoration: TextDecoration.none,
),
),
)
: Offstage(),
@@ -267,7 +259,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
? 0
: filteredItems.length;
return Container(
color: Theme.of(context).extension<PickerTheme>()!.dividerColor,
color: Theme.of(context).colorScheme.outlineVariant,
child: widget.isGridView
? GridView.builder(
key: ValueKey('picker_items_grid_view_key'),
@@ -292,7 +284,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
shrinkWrap: true,
separatorBuilder: (context, index) => widget.isSeparated
? Divider(
color: Theme.of(context).extension<PickerTheme>()!.dividerColor,
color: Theme.of(context).colorScheme.outlineVariant,
height: 1,
)
: const SizedBox(),
@@ -348,13 +340,10 @@ class _PickerState<Item> extends State<Picker<Item>> {
key: ValueKey('picker_items_index_${itemName}_text_key'),
widget.displayItem?.call(item) ?? item.toString(),
softWrap: true,
style: TextStyle(
fontSize: 14,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w600,
decoration: TextDecoration.none,
),
),
),
if (tag != null)
@@ -367,17 +356,17 @@ class _PickerState<Item> extends State<Picker<Item>> {
child: Text(
key: ValueKey('picker_items_index_${index}_tag_key'),
tag,
style: TextStyle(
fontSize: 7.0,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeScrollbarTheme>()!.thumbColor,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 7.0,
color: Theme.of(context).colorScheme.primary,
),
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
//border: Border.all(color: ),
color: Theme.of(context).extension<CakeScrollbarTheme>()!.trackColor,
color: Theme.of(context).colorScheme.surfaceVariant,
),
),
),
@@ -396,7 +385,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
},
child: Container(
height: isCustomItem ? 95 : 55,
color: Theme.of(context).dialogTheme.backgroundColor,
color: Theme.of(context).colorScheme.surface,
padding: EdgeInsets.symmetric(horizontal: 24),
child: isCustomItem
? Column(
@@ -439,13 +428,13 @@ class _PickerState<Item> extends State<Picker<Item>> {
key: ValueKey('picker_items_index_${itemName}_selected_item_text_key'),
widget.displayItem?.call(item) ?? item.toString(),
softWrap: true,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w700,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontWeight: FontWeight.w700,
color: Theme.of(context).colorScheme.onSurface,
decoration: TextDecoration.none,
),
),
),
if (tag != null)
@@ -457,17 +446,17 @@ class _PickerState<Item> extends State<Picker<Item>> {
child: Center(
child: Text(
tag,
style: TextStyle(
fontSize: 7.0,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeScrollbarTheme>()!.thumbColor,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 7.0,
color: Theme.of(context).colorScheme.primary,
),
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
//border: Border.all(color: ),
color: Theme.of(context).extension<CakeScrollbarTheme>()!.trackColor,
color: Theme.of(context).colorScheme.surfaceVariant,
),
),
),
@@ -475,7 +464,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
),
),
),
Icon(Icons.check_circle, color: Theme.of(context).primaryColor),
Icon(Icons.check_circle, color: Theme.of(context).colorScheme.primary),
],
);
@@ -486,7 +475,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
},
child: Container(
height: isCustomItem ? 95 : 55,
color: Theme.of(context).dialogTheme.backgroundColor,
color: Theme.of(context).colorScheme.surface,
padding: EdgeInsets.symmetric(horizontal: 24),
child: isCustomItem
? Column(
@@ -516,12 +505,14 @@ class _PickerState<Item> extends State<Picker<Item>> {
child: Center(
child: Text(
item.name.substring(0, min(item.name.length, 2)).toUpperCase(),
style: TextStyle(fontSize: 11),
style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontSize: 11,
),
),
),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey.shade400,
color: Theme.of(context).colorScheme.surfaceContainer,
),
);
}
@@ -1,7 +1,6 @@
import 'package:cake_wallet/themes/extensions/account_list_theme.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
class PickerInnerWrapperWidget extends StatelessWidget {
PickerInnerWrapperWidget(
@@ -32,20 +31,21 @@ class PickerInnerWrapperWidget extends StatelessWidget {
child: Text(
title!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
decoration: TextDecoration.none,
color: Colors.white),
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
fontSize: 18,
decoration: TextDecoration.none,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
SizedBox(height: 8),
Padding(
padding: EdgeInsets.symmetric(horizontal: 24),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(14)),
child: Container(
color: Theme.of(context).dialogTheme.backgroundColor,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight:
@@ -73,7 +73,7 @@ class PickerInnerWrapperWidget extends StatelessWidget {
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(14)),
child: Container(
color: Theme.of(context).dialogTheme.backgroundColor,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: containerHeight,
+113 -83
View File
@@ -13,6 +13,7 @@ class PrimaryButton extends StatelessWidget {
this.isDottedBorder = false,
this.borderColor = Colors.black,
this.onDisabledPressed,
this.borderRadius,
super.key,
});
@@ -24,33 +25,40 @@ class PrimaryButton extends StatelessWidget {
final String text;
final bool isDisabled;
final bool isDottedBorder;
final BorderRadius? borderRadius;
@override
Widget build(BuildContext context) {
final content = ConstrainedBox(
constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
child: SizedBox(
width: double.infinity,
height: 52.0,
child: TextButton(
onPressed:
isDisabled ? (onDisabledPressed != null ? onDisabledPressed : null) : onPressed,
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(isDisabled ? color.withOpacity(0.5) : color),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26.0),
),
),
overlayColor: MaterialStateProperty.all(Colors.transparent)),
child: Text(text,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w600,
color: isDisabled ? textColor.withOpacity(0.5) : textColor)),
)),
width: double.infinity,
height: 52.0,
child: TextButton(
onPressed:
isDisabled ? (onDisabledPressed != null ? onDisabledPressed : null) : onPressed,
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(
isDisabled ? color.withOpacity(0.5) : color,
),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: borderRadius ?? BorderRadius.circular(12.0),
),
),
overlayColor: WidgetStateProperty.all(Colors.transparent),
),
child: Text(
text,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 15.0,
fontWeight: FontWeight.w600,
color: isDisabled ? textColor.withOpacity(0.5) : textColor,
),
),
),
),
);
return isDottedBorder
@@ -59,7 +67,7 @@ class PrimaryButton extends StatelessWidget {
dashPattern: [6, 4],
color: borderColor,
strokeWidth: 2,
radius: Radius.circular(26),
radius: Radius.circular(15),
child: content)
: content;
}
@@ -88,45 +96,52 @@ class LoadingPrimaryButton extends StatelessWidget {
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:
MaterialStateProperty.all(isDisabled ? color.withOpacity(0.5) : color),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26.0),
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(12.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,
),
)),
child: isLoading
? CupertinoActivityIndicator(animating: true, color: textColor)
: Text(text,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w600,
color: isDisabled ? textColor.withOpacity(0.5) : textColor)),
)),
),
),
),
);
}
}
class PrimaryIconButton extends StatelessWidget {
const PrimaryIconButton(
{required this.onPressed,
required this.iconData,
required this.text,
required this.color,
required this.borderColor,
required this.iconColor,
required this.iconBackgroundColor,
required this.textColor,
this.mainAxisAlignment = MainAxisAlignment.start,
this.radius = 26, super.key});
const PrimaryIconButton({
required this.onPressed,
required this.iconData,
required this.text,
required this.color,
required this.borderColor,
required this.iconColor,
required this.iconBackgroundColor,
required this.textColor,
this.mainAxisAlignment = MainAxisAlignment.start,
this.radius = 12,
super.key,
});
final VoidCallback onPressed;
final IconData iconData;
@@ -149,8 +164,8 @@ class PrimaryIconButton extends StatelessWidget {
child: TextButton(
onPressed: onPressed,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(color),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
backgroundColor: WidgetStateProperty.all(color),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(radius),
),
@@ -164,14 +179,22 @@ class PrimaryIconButton extends StatelessWidget {
width: 26.0,
height: 52.0,
decoration: BoxDecoration(shape: BoxShape.circle, color: iconBackgroundColor),
child: Center(child: Icon(iconData, color: iconColor, size: 22.0)),
child: Center(
child: Icon(iconData, color: iconColor, size: 22.0),
),
),
],
),
Container(
height: 52.0,
child: Center(
child: Text(text, style: TextStyle(fontSize: 16.0, color: textColor)),
child: Text(
text,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
color: textColor,
),
),
),
)
],
@@ -188,7 +211,8 @@ class PrimaryImageButton extends StatelessWidget {
required this.text,
required this.color,
required this.textColor,
this.borderColor = Colors.transparent, super.key});
this.borderColor = Colors.transparent,
super.key});
final VoidCallback onPressed;
final Image image;
@@ -202,30 +226,36 @@ class PrimaryImageButton extends StatelessWidget {
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
child: SizedBox(
width: double.infinity,
height: 52.0,
child: TextButton(
onPressed: onPressed,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(color),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26.0),
),
)),
child: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
image,
SizedBox(width: 15),
Text(
text,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: textColor),
)
],
width: double.infinity,
height: 52.0,
child: ElevatedButton(
onPressed: onPressed,
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(color),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
))),
)),
child: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
image,
SizedBox(width: 15),
Text(
text,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 15,
fontWeight: FontWeight.w600,
color: textColor,
),
)
],
),
),
),
),
);
}
}
+75 -66
View File
@@ -1,6 +1,3 @@
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
@@ -60,40 +57,36 @@ class ProviderOptionTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
final backgroundColor = isSelected
? isLightMode
? Theme.of(context).extension<ReceivePageTheme>()!.currentTileBackgroundColor
: Theme.of(context).extension<OptionTileTheme>()!.titleColor
: Theme.of(context).cardColor;
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.surfaceContainer;
final textColor = isSelected
? isLightMode
? Colors.white
: Theme.of(context).cardColor
: Theme.of(context).extension<OptionTileTheme>()!.titleColor;
? Theme.of(context).colorScheme.onPrimary
: Theme.of(context).colorScheme.onSurface;
final badgeColor = isSelected
? Theme.of(context).cardColor
: Theme.of(context).extension<OptionTileTheme>()!.titleColor;
? Theme.of(context).colorScheme.surfaceContainer
: Theme.of(context).colorScheme.onSurface;
final badgeTextColor = isSelected
? Theme.of(context).extension<OptionTileTheme>()!.titleColor
: Theme.of(context).cardColor;
? Theme.of(context).colorScheme.onSurface
: Theme.of(context).colorScheme.surfaceContainer;
final imagePath = isSelected
? isLightMode
? !isLightMode
? darkImagePath
: lightImagePath
: isLightMode
? lightImagePath
: darkImagePath;
: !isLightMode
? darkImagePath
: lightImagePath;
final rightSubTitleIconPath = isSelected
? isLightMode
? !isLightMode
? rightSubTitleDarkIconPath
: rightSubTitleLightIconPath
: isLightMode
? rightSubTitleLightIconPath
: rightSubTitleDarkIconPath;
: !isLightMode
? rightSubTitleDarkIconPath
: rightSubTitleLightIconPath;
return GestureDetector(
onTap: onPressed,
@@ -112,15 +105,24 @@ class ProviderOptionTile extends StatelessWidget {
children: [
Row(
children: [
getImage(imagePath, height: imageHeight, width: imageWidth),
getImage(imagePath,
height: imageHeight, width: imageWidth, imageColor: textColor),
SizedBox(width: 8),
Expanded(
child: Container(
child: Row(
children: [
Expanded(
child: Text(title,
style: titleTextStyle ?? textLargeBold(color: textColor))),
child: Text(
title,
style: titleTextStyle ??
Theme.of(context).textTheme.bodyLarge?.copyWith(
color: textColor,
fontWeight: FontWeight.w700,
fontSize: 18,
),
),
),
Row(
children: [
if (leadingIcon != null)
@@ -142,18 +144,26 @@ class ProviderOptionTile extends StatelessWidget {
rightSubTitleIconPath: rightSubTitleIconPath),
if (bottomLeftSubTitle != null || bottomRightSubTitle != null)
subTitleWidget(
leftSubTitle: bottomLeftSubTitle,
textColor: textColor,
subTitleFontSize: 12),
leftSubTitle: bottomLeftSubTitle,
textColor: textColor,
subTitleFontSize: 12,
),
if (badges != null && badges!.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 12),
child: Row(children: [
...badges!
.map((badge) => Badge(
title: badge, textColor: badgeTextColor, backgroundColor: badgeColor))
.toList()
]),
child: Row(
children: [
...badges!
.map(
(badge) => Badge(
title: badge,
textColor: badgeTextColor,
backgroundColor: badgeColor,
),
)
.toList()
],
),
)
],
),
@@ -188,21 +198,19 @@ class subTitleWidget extends StatelessWidget {
children: [
leftSubTitle != null || subTitleIconPath != null
? Row(
children: [
if (subTitleIconPath != null && subTitleIconPath!.isNotEmpty)
Padding(
padding: const EdgeInsets.only(right: 6),
child: getImage(subTitleIconPath!),
children: [
if (subTitleIconPath != null && subTitleIconPath!.isNotEmpty)
Padding(
padding: const EdgeInsets.only(right: 6),
child: getImage(subTitleIconPath!),
),
Text(
leftSubTitle ?? '',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: subTitleFontSize, fontWeight: FontWeight.w700, color: textColor),
),
Text(
leftSubTitle ?? '',
style: TextStyle(
fontSize: subTitleFontSize,
fontWeight: FontWeight.w700,
color: textColor),
),
],
)
],
)
: Offstage(),
rightSubTitle != null || rightSubTitleIconPath != null
? Row(
@@ -214,7 +222,7 @@ class subTitleWidget extends StatelessWidget {
),
Text(
rightSubTitle ?? '',
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: subTitleFontSize, fontWeight: FontWeight.w700, color: textColor),
),
],
@@ -245,11 +253,10 @@ class Badge extends StatelessWidget {
alignment: Alignment.center,
child: Text(
title,
style: TextStyle(
color: textColor,
fontSize: 12,
fontWeight: FontWeight.w600,
),
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: textColor,
fontWeight: FontWeight.w600,
),
),
),
),
@@ -373,8 +380,8 @@ class _OptionTilePlaceholderState extends State<OptionTilePlaceholder>
@override
Widget build(BuildContext context) {
final backgroundColor = Theme.of(context).cardColor;
final titleColor = Theme.of(context).extension<OptionTileTheme>()!.titleColor.withOpacity(0.4);
final backgroundColor = Theme.of(context).colorScheme.surfaceContainer;
final titleColor = Theme.of(context).colorScheme.onSurface.withOpacity(0.4);
return widget.errorText != null
? Container(
@@ -382,25 +389,27 @@ class _OptionTilePlaceholderState extends State<OptionTilePlaceholder>
padding: widget.padding ?? EdgeInsets.all(16),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius ?? 12)),
borderRadius: BorderRadius.all(
Radius.circular(widget.borderRadius ?? 12),
),
color: backgroundColor,
),
child: Column(
children: [
Text(
widget.errorText!,
style: TextStyle(
color: titleColor,
fontSize: 16,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: titleColor,
fontSize: 16,
),
),
if (widget.withSubtitle) SizedBox(height: 8),
Text(
'',
style: TextStyle(
color: titleColor,
fontSize: 16,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: titleColor,
fontSize: 16,
),
),
],
),
+14 -26
View File
@@ -1,4 +1,4 @@
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
@@ -6,41 +6,29 @@ class SearchBarWidget extends StatelessWidget {
const SearchBarWidget({
required this.searchController,
this.hintText,
this.borderRadius = 14,
super.key,
});
final TextEditingController searchController;
final String? hintText;
final double borderRadius;
@override
Widget build(BuildContext context) {
return TextFormField(
return BaseTextFormField(
key: ValueKey('search_bar_widget_key'),
controller: searchController,
style: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
decoration: InputDecoration(
hintText: hintText ?? S.of(context).search,
hintStyle: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
prefixIcon: Icon( Icons.search,
color: Theme.of(context).primaryColor),
filled: true,
fillColor: Theme.of(context).extension<PickerTheme>()!.searchBackgroundFillColor,
alignLabelWithHint: false,
contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(
color: Theme.of(context).extension<PickerTheme>()!.searchBorderColor ??
Colors.transparent,
)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: const BorderSide(
color: Colors.transparent,
)),
),
textStyle: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant),
hintText: hintText ?? S.of(context).search,
placeholderTextStyle: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant),
prefixIcon: Icon(Icons.search, color: Theme.of(context).colorScheme.primary),
alignLabelWithHint: false,
contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
);
}
}
+8 -5
View File
@@ -1,26 +1,29 @@
import 'package:flutter/material.dart';
class SectionDivider extends StatelessWidget {
const SectionDivider({required this.direction});
const SectionDivider({required this.direction, this.margin});
final Axis direction;
final EdgeInsets? margin;
@override
Widget build(BuildContext context) {
return Container(
height: direction == Axis.horizontal ? 1 : null,
width: direction == Axis.vertical ? 1 : null,
color: Theme.of(context).dividerColor,
color: Theme.of(context).colorScheme.outlineVariant.withOpacity(0.5),
margin: margin,
);
}
}
class HorizontalSectionDivider extends StatelessWidget {
const HorizontalSectionDivider();
const HorizontalSectionDivider({this.margin});
final EdgeInsets? margin;
@override
Widget build(BuildContext context) {
return SectionDivider(direction: Axis.horizontal);
return SectionDivider(direction: Axis.horizontal, margin: margin);
}
}
@@ -10,12 +10,14 @@ class SeedLanguageSelector extends StatefulWidget {
required this.initialSelected,
this.seedType = MoneroSeedType.defaultSeedType,
this.buttonKey,
this.borderRadius,
Key? key,
}) : super(key: key);
final String initialSelected;
final MoneroSeedType seedType;
final Key? buttonKey;
final BorderRadius? borderRadius;
@override
SeedLanguageSelectorState createState() => SeedLanguageSelectorState(selected: initialSelected);
@@ -29,6 +31,7 @@ class SeedLanguageSelectorState extends State<SeedLanguageSelector> {
@override
Widget build(BuildContext context) {
return SelectButton(
borderRadius: widget.borderRadius,
key: widget.buttonKey,
image: null,
text:
+98 -64
View File
@@ -1,8 +1,6 @@
import 'package:cake_wallet/core/seed_validator.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/validable_annotated_editable_text.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -80,69 +78,105 @@ class SeedWidgetState extends State<SeedWidget> {
@override
Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Stack(children: [
SizedBox(height: 35),
if (_showPlaceholder)
Positioned(
top: 10,
left: 0,
child: Text(S.of(context).enter_seed_phrase,
style: TextStyle(fontSize: 16.0, color: Theme.of(context).hintColor))),
Padding(
padding: EdgeInsets.only(right: 40, top: 10),
child: ValidatableAnnotatedEditableText(
key: widget.seedTextFieldKey,
cursorColor: Colors.blue,
backgroundCursorColor: Colors.blue,
validStyle: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
backgroundColor: Colors.transparent,
fontWeight: FontWeight.normal,
fontSize: 16),
invalidStyle: TextStyle(
fontSize: 16,
color: Colors.red,
fontWeight: FontWeight.normal,
backgroundColor: Colors.transparent),
focusNode: focusNode,
controller: controller,
words: words,
normalizeSeed: normalizeSeed,
textStyle: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
backgroundColor: Colors.transparent,
fontWeight: FontWeight.normal,
fontSize: 16),
)),
Positioned(
top: 0,
right: 8,
child: Container(
width: 32,
height: 32,
child: InkWell(
key: widget.pasteButtonKey,
onTap: () async => _pasteText(),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).hintColor,
borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset('assets/images/paste_ios.png',
color: Theme.of(context)
.extension<SendPageTheme>()!
.textFieldButtonIconColor)),
)))
]),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(top: 15),
height: 1.0,
color: Theme.of(context).extension<CakeTextTheme>()!.textfieldUnderlineColor),
]));
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainer,
borderRadius: BorderRadius.circular(12),
),
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(left: 12, right: 8, top: 8, bottom: 8),
child: Row(
children: [
Expanded(
child: Stack(
children: [
Container(
constraints: BoxConstraints(minHeight: 40),
child: Align(
alignment: Alignment.centerLeft,
child: ValidatableAnnotatedEditableText(
key: widget.seedTextFieldKey,
cursorColor: Theme.of(context).colorScheme.primary,
backgroundCursorColor: Theme.of(context).colorScheme.primary,
validStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
backgroundColor: Colors.transparent,
fontWeight: FontWeight.normal,
fontSize: 16,
),
invalidStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.errorContainer,
backgroundColor: Colors.transparent,
fontWeight: FontWeight.normal,
fontSize: 16,
),
focusNode: focusNode,
controller: controller,
words: words,
normalizeSeed: normalizeSeed,
textStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
backgroundColor: Colors.transparent,
fontWeight: FontWeight.normal,
fontSize: 16,
),
),
),
),
if (_showPlaceholder)
Positioned.fill(
child: IgnorePointer(
child: Align(
alignment: Alignment.centerLeft,
child: Text(
S.of(context).enter_seed_phrase,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 16,
),
),
),
),
),
],
),
),
Container(
width: 32,
height: 32,
child: InkWell(
key: widget.pasteButtonKey,
onTap: () async => _pasteText(),
child: Container(
padding: EdgeInsets.all(6),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.all(
Radius.circular(6),
),
),
child: Image.asset(
'assets/images/paste_ios.png',
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
),
],
),
),
],
),
),
],
),
);
}
Future<void> _pasteText() async {
+11 -16
View File
@@ -1,4 +1,3 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart';
class SeedPhraseGridWidget extends StatelessWidget {
@@ -28,35 +27,31 @@ class SeedPhraseGridWidget extends StatelessWidget {
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Theme.of(context).cardColor,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
child: Text(
//maxLines: 1,
numberCount.toString(),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
height: 1,
fontWeight: FontWeight.w800,
color: Theme.of(context)
.extension<CakeTextTheme>()!
.buttonTextColor
.withOpacity(0.5)),
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
height: 1.9,
fontWeight: FontWeight.w700,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
),
),
),
const SizedBox(width: 6),
Expanded(
child: Text(
'${item[0].toLowerCase()}${item.substring(1)}',
style: TextStyle(
fontSize: 14,
height: 0.8,
fontWeight: FontWeight.w700,
color: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
height: 1.9,
fontWeight: FontWeight.w700,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
],
+7 -4
View File
@@ -1,5 +1,6 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/entities/service_status.dart';
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
@@ -20,9 +21,9 @@ class ServiceStatusTile extends StatelessWidget {
Expanded(
child: AutoSizeText(
"${status.title}${status.status != null ? " - ${status.status}" : ""}",
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w800,
height: 1,
),
@@ -32,7 +33,7 @@ class ServiceStatusTile extends StatelessWidget {
),
Text(
_getTimeString(status.date),
style: TextStyle(fontSize: 12),
style: Theme.of(context).textTheme.bodySmall,
),
],
),
@@ -40,7 +41,9 @@ class ServiceStatusTile extends StatelessWidget {
leading: RotatedBox(
child: Icon(
Icons.info,
color: status.status == "resolved" ? Colors.green : Colors.red,
color: status.status == "resolved"
? CustomThemeColors.syncGreen
: Theme.of(context).colorScheme.errorContainer,
),
quarterTurns: 2,
),
+22 -22
View File
@@ -5,8 +5,6 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/service_status_tile.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -44,14 +42,14 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
},
child: SvgPicture.asset(
"assets/images/notification_icon.svg",
color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
color: Theme.of(context).colorScheme.onSurface,
width: 30,
placeholderBuilder: (_) => Icon(Icons.error),
),
);
}
return Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.only(left: 16, top: 12, right: 8, bottom: 8),
child: FutureBuilder<ServicesResponse>(
future: widget.servicesResponse,
builder: (context, state) {
@@ -66,6 +64,7 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
setState(() => wasOpened = true);
showModalBottomSheet(
backgroundColor: Theme.of(context).colorScheme.surface,
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
@@ -81,14 +80,18 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
Widget body;
if (state.data!.servicesStatus.isEmpty) {
body = Center(
child: Text("Everything is up and running as expected"),
child: Text(
"Everything is up and running as expected",
style: Theme.of(context).textTheme.bodyMedium,
),
);
} else {
body = SingleChildScrollView(
child: Column(
children: state.data!.servicesStatus
.map((status) => ServiceStatusTile(status))
.toList()),
children: state.data!.servicesStatus
.map((status) => ServiceStatusTile(status))
.toList(),
),
);
}
return Padding(
@@ -100,29 +103,26 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width / 8,
horizontal: 24,
vertical: 20,
),
child: PrimaryImageButton(
onPressed: () {
try {
launchUrl(Uri.parse("https://status.cakewallet.com/"),
launchUrl(
Uri.parse(
"https://status.cakewallet.com/",
),
mode: LaunchMode.externalApplication);
} catch (_) {}
},
image: Image.asset(
"assets/images/status_website_image.png",
color: Theme.of(context).brightness == Brightness.light
? Colors.white
: null,
color: Theme.of(context).colorScheme.onPrimary,
),
text: "Status Website",
color: Theme.of(context)
.extension<WalletListTheme>()!
.createNewWalletButtonBackgroundColor,
textColor: Theme.of(context)
.extension<WalletListTheme>()!
.restoreWalletButtonTextColor,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
),
),
)
@@ -137,8 +137,8 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
children: [
SvgPicture.asset(
"assets/images/notification_icon.svg",
color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
width: 30,
color: Theme.of(context).colorScheme.onSurface,
width: 20,
placeholderBuilder: (_) => Icon(Icons.error),
),
if (state.hasData && state.data!.hasUpdates && !wasOpened)
@@ -147,7 +147,7 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
width: 7,
margin: EdgeInsetsDirectional.only(start: 15),
decoration: BoxDecoration(
color: Colors.red,
color: Theme.of(context).colorScheme.errorContainer,
shape: BoxShape.circle,
),
),
+16 -23
View File
@@ -1,10 +1,4 @@
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
class SettingActionButton extends StatelessWidget {
final bool isLastTile;
@@ -33,19 +27,20 @@ class SettingActionButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isLightMode = Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
Color? color = isSelected
? Theme.of(context).extension<CakeMenuTheme>()!.settingTitleColor
? Theme.of(context).colorScheme.primary
: selectionActive
? Palette.darkBlue
: Theme.of(context).extension<CakeMenuTheme>()!.settingTitleColor;
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurface;
return Container(
//padding: EdgeInsets.only(top: 5, left: 15, bottom: 5),
margin: EdgeInsets.only(top: 10, left: 20, bottom: 0, right: 20),
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(isLightMode ? Theme.of(context).cardColor : Colors.black12),
shape: MaterialStateProperty.all(
backgroundColor: WidgetStateProperty.all(
Theme.of(context).colorScheme.surfaceContainer,
),
shape: WidgetStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
@@ -66,25 +61,23 @@ class SettingActionButton extends StatelessWidget {
image,
height: 16,
width: 16,
color: Theme.of(context)
.extension<CakeMenuTheme>()!
.settingActionsIconColor,
color: Theme.of(context).colorScheme.primary,
),
SizedBox(width: 16),
Expanded(
child: Text(
title,
style: TextStyle(
color: color,
fontSize: 16,
fontWeight: FontWeight.bold,
),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: color,
fontSize: 16,
fontWeight: FontWeight.w800,
),
),
),
if(isArrowVisible)
if (isArrowVisible)
Icon(
Icons.arrow_forward_ios,
color: Colors.grey,
color: Theme.of(context).colorScheme.primary,
size: 16,
)
],
@@ -93,4 +86,4 @@ class SettingActionButton extends StatelessWidget {
),
);
}
}
}
+12 -13
View File
@@ -1,5 +1,3 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:flutter/material.dart';
class StandardCheckbox extends StatelessWidget {
@@ -23,19 +21,20 @@ class StandardCheckbox extends StatelessWidget {
@override
Widget build(BuildContext context) {
final baseGradient = LinearGradient(colors: [
Theme.of(context).extension<FilterTheme>()!.checkboxFirstGradientColor,
Theme.of(context).extension<FilterTheme>()!.checkboxSecondGradientColor,
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.primary.withOpacity(0.7),
], begin: Alignment.centerLeft, end: Alignment.centerRight);
final boxBorder = Border.all(
color: borderColor ?? Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
width: 1.0,
color: borderColor ?? Theme.of(context).colorScheme.outline,
width: 2.0,
);
final checkedBoxDecoration = BoxDecoration(
gradient: gradientBackground ? baseGradient : null,
border: gradientBackground ? null : boxBorder,
borderRadius: BorderRadius.all(Radius.circular(8.0)));
gradient: gradientBackground ? baseGradient : null,
border: gradientBackground ? null : boxBorder,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
);
final uncheckedBoxDecoration =
BoxDecoration(border: boxBorder, borderRadius: BorderRadius.all(Radius.circular(8.0)));
@@ -54,7 +53,7 @@ class StandardCheckbox extends StatelessWidget {
child: value
? Icon(
Icons.check,
color: iconColor ?? Theme.of(context).primaryColor,
color: iconColor ?? Theme.of(context).colorScheme.primary,
size: 20.0,
)
: Offstage(),
@@ -66,11 +65,11 @@ class StandardCheckbox extends StatelessWidget {
child: Text(
caption,
softWrap: true,
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16.0,
fontFamily: 'Lato',
fontWeight: FontWeight.normal,
color: captionColor ?? Theme.of(context).extension<CakeTextTheme>()!.titleColor,
color: captionColor ?? Theme.of(context).colorScheme.onSurface,
decoration: TextDecoration.none,
),
),
+8 -13
View File
@@ -1,5 +1,3 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
import 'package:flutter/material.dart';
class StandardExpandableList<T> extends StatelessWidget {
@@ -18,21 +16,18 @@ class StandardExpandableList<T> extends StatelessWidget {
return Container(
decoration: decoration ??
BoxDecoration(
color: Theme.of(context).colorScheme.background,
color: Theme.of(context).colorScheme.surface,
),
child: Theme(
data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
child: ExpansionTile(
iconColor: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
collapsedIconColor:
Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
iconColor: Theme.of(context).colorScheme.onSurface,
collapsedIconColor: Theme.of(context).colorScheme.onSurface,
title: Text(
title,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.left,
),
children: expandableItems.map((item) {
@@ -43,10 +38,10 @@ class StandardExpandableList<T> extends StatelessWidget {
child: Text(
item.toString(),
maxLines: 1,
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
color: Theme.of(context).colorScheme.primary),
),
),
);
+12 -16
View File
@@ -1,4 +1,3 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/src/widgets/standard_list_card.dart';
import 'package:cake_wallet/src/widgets/standard_list_status_row.dart';
import 'package:flutter/material.dart';
@@ -22,16 +21,15 @@ class StandardListRow extends StatelessWidget {
final leading = buildLeading(context);
final trailing = buildTrailing(context);
return Container(
height: 56,
padding: EdgeInsets.only(left: 12, right: 12),
height: 56,
padding: EdgeInsets.only(left: 12, right: 12),
child: TextButton(
onPressed: () => onTap?.call(context),
style: ButtonStyle(
//backgroundColor: MaterialStateProperty.all(Theme.of(context).cardColor),
shape: MaterialStateProperty.all(
//backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.surfaceContainer),
shape: WidgetStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)
),
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
),
@@ -58,11 +56,10 @@ class StandardListRow extends StatelessWidget {
Expanded(
child: Text(
title,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: titleColor(context),
),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: titleColor(context),
fontWeight: isSelected ? FontWeight.w800 : FontWeight.w400,
),
),
)
],
@@ -72,9 +69,8 @@ class StandardListRow extends StatelessWidget {
Widget? buildTrailing(BuildContext context) => null;
Color titleColor(BuildContext context) => isSelected
? Theme.of(context).primaryColor
: Theme.of(context).extension<CakeTextTheme>()!.titleColor;
Color titleColor(BuildContext context) =>
isSelected ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onSurface;
}
class SectionHeaderListRow extends StatelessWidget {
@@ -84,7 +80,7 @@ class SectionHeaderListRow extends StatelessWidget {
Container(
width: double.infinity,
height: 40,
color: Theme.of(context).colorScheme.background,
color: Theme.of(context).colorScheme.surface,
),
//StandardListSeparator(padding: EdgeInsets.only(left: 24))
]);
+50 -62
View File
@@ -1,16 +1,15 @@
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/core/material_base_theme.dart';
class TradeDetailsStandardListCard extends StatelessWidget {
TradeDetailsStandardListCard(
{required this.id,
this.extraId,
required this.create,
required this.pair,
required this.onTap,
required this.currentTheme});
TradeDetailsStandardListCard({
required this.id,
this.extraId,
required this.create,
required this.pair,
required this.onTap,
required this.currentTheme,
});
final String id;
final String? extraId;
@@ -21,70 +20,59 @@ class TradeDetailsStandardListCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final darkTheme = currentTheme == ThemeType.dark;
final baseGradient = LinearGradient(colors: [
Theme.of(context).extension<ExchangePageTheme>()!.firstGradientTopPanelColor,
Theme.of(context).extension<ExchangePageTheme>()!.secondGradientTopPanelColor,
], begin: Alignment.centerLeft, end: Alignment.centerRight);
final gradient = LinearGradient(colors: [
PaletteDark.wildNightBlue,
PaletteDark.oceanBlue,
], begin: Alignment.bottomCenter, end: Alignment.topCenter);
final textColor = Colors.white;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
child: GestureDetector(
onTap: () => onTap(context),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
gradient: darkTheme ? gradient : baseGradient),
borderRadius: BorderRadius.circular(15.0),
color: Theme.of(context).colorScheme.surfaceContainerHighest,
),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20.0, vertical: 16.0),
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(id,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: textColor)),
SizedBox(
height: 8,
),
if (extraId != null && extraId!.isNotEmpty)
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
id,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 8,
),
if (extraId != null && extraId!.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(extraId!,
style: TextStyle(
child: Text(
extraId!,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: textColor)),
),
),
),
Text(create,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: textColor)),
SizedBox(
height: 35,
),
Text(pair,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
color: textColor)),
]),
Text(
create,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
),
),
SizedBox(
height: 35,
),
Text(
pair,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
+43 -46
View File
@@ -1,9 +1,5 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/address_theme.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class StandardListStatusRow extends StatelessWidget {
StandardListStatusRow({required this.title, required this.value, this.status});
@@ -16,50 +12,51 @@ class StandardListStatusRow extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
width: double.infinity,
color: Theme.of(context).colorScheme.background,
color: Theme.of(context).colorScheme.surface,
child: Padding(
padding:
const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(title,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor),
textAlign: TextAlign.left),
Padding(
padding: const EdgeInsets.only(top: 12),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<AddressTheme>()!.actionButtonColor,
borderRadius: BorderRadius.circular(30.0),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SyncIndicatorIcon(
boolMode: false,
value: status ?? value,
size: 6,
),
SizedBox(
width: 5,
),
Text(value,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor))
],
),
),
padding: const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
title,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
)
]),
textAlign: TextAlign.left,
),
Padding(
padding: const EdgeInsets.only(top: 12),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(30.0),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SyncIndicatorIcon(
boolMode: false,
value: status ?? value,
size: 6,
),
SizedBox(
width: 5,
),
Text(
value,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
),
)
],
),
),
),
)
]),
),
);
}
+1 -2
View File
@@ -1,6 +1,5 @@
import 'package:cake_wallet/src/widgets/list_row.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:flutter/material.dart';
class StandardPickerList<T> extends StatefulWidget {
@@ -68,7 +67,7 @@ class _StandardPickerListState<T> extends State<StandardPickerList<T>> {
mainAxisAlignment: MainAxisAlignment.center,
sliderValue: customValue,
isWrapped: false,
borderColor: Theme.of(context).extension<PickerTheme>()!.dividerColor,
borderColor: Theme.of(context).colorScheme.outlineVariant,
onSliderChanged: (newValue) {
setState(() => customValue = newValue);
value = widget.onSliderChanged(newValue).toString();
@@ -1,9 +1,5 @@
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/core/material_base_theme.dart';
import 'package:flutter/material.dart';
class StandardSlideButton extends StatefulWidget {
@@ -19,7 +15,7 @@ class StandardSlideButton extends StatefulWidget {
final VoidCallback onSlideComplete;
final String buttonText;
final double height;
final ThemeBase currentTheme;
final MaterialThemeBase currentTheme;
final String accessibleNavigationModeButtonText;
@override
@@ -33,75 +29,78 @@ class _StandardSlideButtonState extends State<StandardSlideButton> {
Widget build(BuildContext context) {
final bool accessible = MediaQuery.of(context).accessibleNavigation;
final tileBackgroundColor = widget.currentTheme.type == ThemeType.light
? Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor
: widget.currentTheme.type == ThemeType.oled
? Colors.black.withOpacity(0.5)
: Theme.of(context).extension<FilterTheme>()!.buttonColor;
final tileBackgroundColor = Theme.of(context).colorScheme.surfaceContainer;
return accessible
? PrimaryButton(
text: widget.accessibleNavigationModeButtonText,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
onPressed: () => widget.onSlideComplete())
: LayoutBuilder(builder: (context, constraints) {
final double maxWidth = constraints.maxWidth;
const double sideMargin = 4.0;
final double effectiveMaxWidth = maxWidth - 2 * sideMargin;
const double sliderWidth = 42.0;
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
onPressed: () => widget.onSlideComplete(),
)
: LayoutBuilder(
builder: (context, constraints) {
final double maxWidth = constraints.maxWidth;
const double sideMargin = 4.0;
final double effectiveMaxWidth = maxWidth - 2 * sideMargin;
const double sliderWidth = 42.0;
return Container(
height: widget.height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: tileBackgroundColor),
child: Stack(
alignment: Alignment.centerLeft,
children: [
Center(
child: Text(widget.buttonText,
style: TextStyle(
return Container(
height: widget.height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: tileBackgroundColor,
),
child: Stack(
alignment: Alignment.centerLeft,
children: [
Center(
child: Text(
widget.buttonText,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor))),
Positioned(
left: sideMargin + _dragPosition,
child: GestureDetector(
onHorizontalDragUpdate: (details) {
setState(() {
_dragPosition += details.delta.dx;
if (_dragPosition < 0) _dragPosition = 0;
if (_dragPosition > effectiveMaxWidth - sliderWidth) {
_dragPosition = effectiveMaxWidth - sliderWidth;
}
});
},
onHorizontalDragEnd: (details) {
if (_dragPosition >= effectiveMaxWidth - sliderWidth - 10) {
widget.onSlideComplete();
} else {
setState(() => _dragPosition = 0);
}
},
child: Container(
width: sliderWidth,
height: widget.height - 8,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
alignment: Alignment.center,
child: Icon(Icons.arrow_forward,
color: widget.currentTheme.type == ThemeType.bright
? Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor
: Theme.of(context).extension<FilterTheme>()!.buttonColor),
),
),
),
)
],
),
);
});
Positioned(
left: sideMargin + _dragPosition,
child: GestureDetector(
onHorizontalDragUpdate: (details) {
setState(() {
_dragPosition += details.delta.dx;
if (_dragPosition < 0) _dragPosition = 0;
if (_dragPosition > effectiveMaxWidth - sliderWidth) {
_dragPosition = effectiveMaxWidth - sliderWidth;
}
});
},
onHorizontalDragEnd: (details) {
if (_dragPosition >= effectiveMaxWidth - sliderWidth - 10) {
widget.onSlideComplete();
} else {
setState(() => _dragPosition = 0);
}
},
child: Container(
width: sliderWidth,
height: widget.height - 8,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.primary,
),
alignment: Alignment.center,
child: Icon(
Icons.arrow_forward,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
)
],
),
);
},
);
}
}
+10 -7
View File
@@ -14,7 +14,6 @@ class StandardSwitch extends StatefulWidget {
class StandardSwitchState extends State<StandardSwitch> {
@override
Widget build(BuildContext context) {
return Semantics(
toggled: widget.value,
child: GestureDetector(
@@ -26,16 +25,20 @@ class StandardSwitchState extends State<StandardSwitch> {
width: 50,
height: 28,
decoration: BoxDecoration(
color: widget.value
? Theme.of(context).primaryColor
: Theme.of(context).disabledColor,
borderRadius: BorderRadius.all(Radius.circular(14.0))),
color: widget.value
? Theme.of(context).colorScheme.surfaceContainerHighest
: Theme.of(context).colorScheme.surfaceContainerLowest,
borderRadius: BorderRadius.all(
Radius.circular(14.0),
),
),
child: Container(
width: 24.0,
height: 24.0,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle),
color: Theme.of(context).colorScheme.primary,
shape: BoxShape.circle,
),
),
),
),
+91 -93
View File
@@ -1,7 +1,5 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
class TemplateTile extends StatefulWidget {
TemplateTile({
@@ -22,87 +20,83 @@ class TemplateTile extends StatefulWidget {
final bool? hasMultipleRecipients;
@override
TemplateTileState createState() => TemplateTileState(
to,
amount,
from,
onTap,
onRemove
);
TemplateTileState createState() => TemplateTileState(to, amount, from, onTap, onRemove);
}
class TemplateTileState extends State<TemplateTile> {
TemplateTileState(
this.to,
this.amount,
this.from,
this.onTap,
this.onRemove
);
TemplateTileState(this.to, this.amount, this.from, this.onTap, this.onRemove);
final String to;
final String amount;
final String from;
final VoidCallback onTap;
final VoidCallback onRemove;
final trash = Image.asset('assets/images/trash.png', height: 16, width: 16, color: Colors.white);
bool isRemovable = false;
@override
Widget build(BuildContext context) {
final color = isRemovable
? Colors.white
: Theme.of(context).extension<SendPageTheme>()!.templateTitleColor;
final toIcon = Image.asset('assets/images/to_icon.png', color: color);
final toIcon = Image.asset(
'assets/images/to_icon.png',
color: Theme.of(context).colorScheme.onSurface,
);
final content = Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: widget.hasMultipleRecipients ?? false
? [
Text(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: widget.hasMultipleRecipients ?? false
? [
Text(
to,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
),
),
]
: [
Text(
amount,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
),
),
Padding(
padding: EdgeInsets.only(left: 5),
child: Text(
from,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
Padding(
padding: EdgeInsets.only(left: 5),
child: toIcon,
),
Padding(
padding: EdgeInsets.only(left: 5),
child: Text(
to,
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w600, color: color),
),
]
: [
Text(
amount,
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w600, color: color),
),
Padding(
padding: EdgeInsets.only(left: 5),
child: Text(
from,
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w600,
color: color),
),
color: Theme.of(context).colorScheme.onSurface,
),
),
Padding(
padding: EdgeInsets.only(left: 5),
child: toIcon,
),
Padding(
padding: EdgeInsets.only(left: 5),
child: Text(
to,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: color),
),
),
]);
),
],
);
final tile = Container(
padding: EdgeInsets.only(right: 10),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20)),
borderRadius: BorderRadius.all(Radius.circular(12)),
child: GestureDetector(
onTap: onTap,
onLongPress: () {
@@ -113,47 +107,51 @@ class TemplateTileState extends State<TemplateTile> {
child: Container(
height: 40,
padding: EdgeInsets.only(left: 24, right: 24),
color: Theme.of(context).extension<SendPageTheme>()!.templateBackgroundColor,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
child: content,
),
),
)
);
));
final removableTile = Container(
padding: EdgeInsets.only(right: 10),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20)),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
isRemovable = false;
});
},
child: Container(
height: 40,
padding: EdgeInsets.only(left: 24, right: 10),
color: Colors.orange,
child: content,
padding: EdgeInsets.only(right: 10),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(12)),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
isRemovable = false;
});
},
child: Container(
height: 40,
padding: EdgeInsets.only(left: 24, right: 10),
color: CustomThemeColors.syncYellow,
child: content,
),
),
GestureDetector(
onTap: onRemove,
child: Container(
height: 40,
width: 44,
color: Theme.of(context).colorScheme.errorContainer,
child: Center(
child: Image.asset(
'assets/images/trash.png',
height: 16,
width: 16,
color: Theme.of(context).colorScheme.onErrorContainer,
),
),
GestureDetector(
onTap: onRemove,
child: Container(
height: 40,
width: 44,
color: Palette.darkRed,
child: Center(
child: trash,
),
),
)
],
),
)
)
],
),
),
);
return isRemovable ? removableTile : tile;
+16 -17
View File
@@ -1,4 +1,3 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart';
class TextInfoBox extends StatelessWidget {
@@ -15,7 +14,7 @@ class TextInfoBox extends StatelessWidget {
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Theme.of(context).cardColor,
color: Theme.of(context).colorScheme.surfaceContainer,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -23,27 +22,27 @@ class TextInfoBox extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title,
style: TextStyle(
fontSize: 14,
Text(
title,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w500,
color: Theme.of(context)
.extension<CakeTextTheme>()!
.buttonTextColor
.withOpacity(0.5))),
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
),
),
GestureDetector(
onTap: onCopy != null ? () => onCopy!(context) : null,
child: Icon(Icons.copy,
size: 13,
color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.7))),
onTap: onCopy != null ? () => onCopy!(context) : null,
child: Icon(Icons.copy, size: 13, color: Theme.of(context).colorScheme.onSurface),
),
],
),
const SizedBox(height: 4),
Text(value,
style: TextStyle(
fontSize: 16,
Text(
value,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor)),
color: Theme.of(context).colorScheme.onSurface,
),
),
],
),
);
+12 -16
View File
@@ -1,12 +1,7 @@
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
class TrailButton extends StatelessWidget {
TrailButton({
required this.caption,
required this.onPressed,
this.textColor});
TrailButton({required this.caption, required this.onPressed, this.textColor});
final String caption;
final VoidCallback onPressed;
@@ -19,17 +14,18 @@ class TrailButton extends StatelessWidget {
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
child: TextButton(
// FIX-ME: ignored padding
//padding: EdgeInsets.all(0),
child: Text(
caption,
style: TextStyle(
color: textColor ??
Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
// FIX-ME: ignored padding
//padding: EdgeInsets.all(0),
child: Text(
caption,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w600,
fontSize: 14),
),
onPressed: onPressed),
color: textColor ?? Theme.of(context).colorScheme.primary,
height: 1.8,
),
),
onPressed: onPressed,
),
);
}
}
@@ -41,39 +41,42 @@ class ValidatableAnnotatedEditableText extends EditableText {
required this.words,
this.normalizeSeed = false,
TextStyle textStyle = const TextStyle(
color: Colors.black,
backgroundColor: Colors.transparent,
fontWeight: FontWeight.normal,
fontSize: 16),
color: Colors.black,
backgroundColor: Colors.transparent,
fontWeight: FontWeight.normal,
fontSize: 16,
),
TextSelectionControls? selectionControls,
Color? selectionColor,
ValueChanged<String>? onChanged,
ValueChanged<String>? onSubmitted,
}) : super(
maxLines: null,
key: key,
focusNode: focusNode,
controller: controller,
cursorColor: cursorColor,
style: validStyle,
keyboardType: TextInputType.visiblePassword,
autocorrect: false,
autofocus: false,
selectionColor: selectionColor,
selectionControls: selectionControls,
backgroundCursorColor: backgroundCursorColor,
onChanged: onChanged,
onSubmitted: onSubmitted,
toolbarOptions: const ToolbarOptions(
copy: true,
cut: true,
paste: true,
selectAll: true,
),
enableSuggestions: false,
enableInteractiveSelection: true,
showSelectionHandles: true,
showCursor: true);
maxLines: null,
key: key,
focusNode: focusNode,
controller: controller,
cursorColor: cursorColor,
style: validStyle,
keyboardType: TextInputType.visiblePassword,
autocorrect: false,
autofocus: false,
selectionColor: selectionColor,
selectionControls: selectionControls,
backgroundCursorColor: backgroundCursorColor,
onChanged: onChanged,
onSubmitted: onSubmitted,
toolbarOptions: const ToolbarOptions(
copy: true,
cut: true,
paste: true,
selectAll: true,
),
enableSuggestions: false,
enableInteractiveSelection: true,
showSelectionHandles: true,
showCursor: true,
);
final bool normalizeSeed;
final List<String> words;
@@ -81,14 +84,12 @@ class ValidatableAnnotatedEditableText extends EditableText {
final TextStyle invalidStyle;
@override
ValidatableAnnotatedEditableTextState createState() =>
ValidatableAnnotatedEditableTextState();
ValidatableAnnotatedEditableTextState createState() => ValidatableAnnotatedEditableTextState();
}
class ValidatableAnnotatedEditableTextState extends EditableTextState {
@override
ValidatableAnnotatedEditableText get widget =>
super.widget as ValidatableAnnotatedEditableText;
ValidatableAnnotatedEditableText get widget => super.widget as ValidatableAnnotatedEditableText;
List<Annotation> getRanges() {
final result = <Annotation>[];
@@ -100,9 +101,12 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
final ranges = range(word, text);
final isValid = validate(word);
return ranges.map((range) => Annotation(
return ranges.map(
(range) => Annotation(
style: isValid ? widget.validStyle : widget.invalidStyle,
range: range));
range: range,
),
);
})
.expand((e) => e)
.toList();
@@ -114,14 +118,20 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
if (prev == null) {
annotation = Annotation(
range: TextRange(start: 0, end: item.range.start),
style: TextStyle(
color: Colors.black, backgroundColor: Colors.transparent));
range: TextRange(start: 0, end: item.range.start),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
backgroundColor: Colors.transparent,
),
);
} else if (prev.range.end < item.range.start) {
annotation = Annotation(
range: TextRange(start: prev.range.end, end: item.range.start),
style: TextStyle(
color: Colors.red, backgroundColor: Colors.transparent));
range: TextRange(start: prev.range.end, end: item.range.start),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onError,
backgroundColor: Colors.transparent,
),
);
}
if (annotation != null) {
@@ -132,9 +142,15 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
}
if (result.length > 0 && result.last.range.end < text.length) {
result.add(Annotation(
result.add(
Annotation(
range: TextRange(start: result.last.range.end, end: text.length),
style: TextStyle(backgroundColor: Colors.transparent)));
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
backgroundColor: Colors.transparent,
),
),
);
}
return result;
@@ -168,11 +184,16 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
if (ranges.isNotEmpty) {
return TextSpan(
style: widget.style,
children: ranges
.map((item) => TextSpan(
style: item.style, text: item.range.textInside(text)))
.toList());
style: widget.style,
children: ranges
.map(
(item) => TextSpan(
style: item.style,
text: item.range.textInside(text),
),
)
.toList(),
);
}
return TextSpan(style: widget.style, text: text);
+8 -12
View File
@@ -1,6 +1,5 @@
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:flutter/material.dart';
class VulnerableSeedsPopup extends StatelessWidget {
@@ -23,10 +22,8 @@ class VulnerableSeedsPopup extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
gradient: LinearGradient(colors: [
Theme.of(context).extension<DashboardPageTheme>()!.firstGradientBackgroundColor,
Theme.of(context)
.extension<DashboardPageTheme>()!
.secondGradientBackgroundColor,
Theme.of(context).colorScheme.primaryContainer,
Theme.of(context).colorScheme.secondaryContainer,
], begin: Alignment.centerLeft, end: Alignment.centerRight)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
@@ -38,12 +35,12 @@ class VulnerableSeedsPopup extends StatelessWidget {
child: Container(
alignment: Alignment.bottomCenter,
child: DefaultTextStyle(
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
decoration: TextDecoration.none,
fontSize: 24.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
color: Theme.of(context).colorScheme.onSurface,
),
child: Text("Emergency Notice"),
),
@@ -63,13 +60,12 @@ class VulnerableSeedsPopup extends StatelessWidget {
),
child: Text(
"Your Bitcoin wallet(s) below use a legacy seed format that is vulnerable, which MAY result in you losing money from these wallet(s) if no action is taken.\nWe recommend that you IMMEDIATELY create wallet(s) in Cake Wallet and immediately transfer the funds to these wallet(s).\nVulnerable wallet name(s):\n\n[${affectedWalletNames.join(", ")}]\n\nFor assistance, please use the in-app support or email support@cakewallet.com",
style: TextStyle(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
decoration: TextDecoration.none,
fontSize: 16.0,
fontFamily: 'Lato',
color: Theme.of(context)
.extension<DashboardPageTheme>()!
.textColor,
.colorScheme.onSurface,
),
),
)
+20 -22
View File
@@ -1,47 +1,45 @@
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/core/material_base_theme.dart';
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
import 'package:flutter/material.dart';
class WarningBox extends StatelessWidget {
const WarningBox({required this.content, required this.currentTheme, Key? key})
: super(key: key);
const WarningBox({required this.content, required this.currentTheme, Key? key}) : super(key: key);
final String content;
final ThemeBase currentTheme;
final MaterialThemeBase currentTheme;
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: currentTheme.type == ThemeType.dark
? Color.fromRGBO(132, 110, 64, 1)
: Color.fromRGBO(194, 165, 94, 1),
borderRadius: BorderRadius.all(Radius.circular(12)),
border: Border.all(
color: currentTheme.type == ThemeType.dark
? Color.fromRGBO(177, 147, 41, 1)
: Color.fromRGBO(125, 122, 15, 1),
width: 2.0,
)),
color: currentTheme.isDark
? CustomThemeColors.warningContainerColorDark
: CustomThemeColors.warningContainerColorLight,
borderRadius: BorderRadius.all(Radius.circular(12)),
border: Border.all(
color: currentTheme.isDark
? CustomThemeColors.warningOutlineColorDark
: CustomThemeColors.warningOutlineColorLight,
width: 2.0,
),
),
child: Row(
children: [
Icon(
Icons.warning_amber_rounded,
size: 64,
color: Colors.white.withOpacity(0.75),
color: Theme.of(context).colorScheme.onSurface,
),
SizedBox(width: 6),
Expanded(
child: Text(
content,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w800,
color: currentTheme.type == ThemeType.dark
? Colors.white.withOpacity(0.75)
: Colors.white.withOpacity(0.85),
),
style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w800,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
],