diff --git a/CHANGELOG.md b/CHANGELOG.md index 14e93230..2efb89c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ +## 3.0.0-beta17 + +- UI fixes + ## 3.0.0-beta16 - UI fixes - + ## 3.0.0-beta15 - Fix a bug where Safe wallet was confused with SafePal wallet diff --git a/assets/icons/copy_14.svg b/assets/icons/copy_14.svg new file mode 100644 index 00000000..6d477298 --- /dev/null +++ b/assets/icons/copy_14.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/png/2.0x/logo_wc.png b/assets/png/2.0x/logo_wc.png index 1bab24f5..7e942933 100644 Binary files a/assets/png/2.0x/logo_wc.png and b/assets/png/2.0x/logo_wc.png differ diff --git a/assets/png/3.0x/logo_wc.png b/assets/png/3.0x/logo_wc.png index 93f3a954..e6727d45 100644 Binary files a/assets/png/3.0x/logo_wc.png and b/assets/png/3.0x/logo_wc.png differ diff --git a/assets/png/logo_wc.png b/assets/png/logo_wc.png index 0a7c7cff..40496018 100644 Binary files a/assets/png/logo_wc.png and b/assets/png/logo_wc.png differ diff --git a/example/pubspec.lock b/example/pubspec.lock index f981fb23..84d0b0e5 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -724,10 +724,10 @@ packages: dependency: transitive description: name: qr_flutter_wc - sha256: "1939a737eded2bdbcc96fefede3edbfbe252d06ad3bba0195237096a068e4db2" + sha256: a926bf6bcf7d350eea48480e205ccffffca5cc84b5d77fb2b256318693e40d07 url: "https://pub.dev" source: hosted - version: "0.0.1" + version: "0.0.3" rxdart: dependency: transitive description: @@ -1107,7 +1107,7 @@ packages: path: ".." relative: true source: path - version: "3.0.0-beta16" + version: "3.0.0-beta17" web_socket_channel: dependency: transitive description: diff --git a/lib/constants/string_constants.dart b/lib/constants/string_constants.dart index 19581e15..254f5611 100644 --- a/lib/constants/string_constants.dart +++ b/lib/constants/string_constants.dart @@ -1,7 +1,7 @@ class StringConstants { // Request Headers static const X_SDK_TYPE = 'w3m'; - static const X_SDK_VERSION = '3.0.0-beta16'; + static const X_SDK_VERSION = '3.0.0-beta17'; static const X_CORE_SDK_VERSION = 'flutter_v2.1.8'; // UI diff --git a/lib/pages/about_networks.dart b/lib/pages/about_networks.dart index 2fb34407..dcc3bfdd 100644 --- a/lib/pages/about_networks.dart +++ b/lib/pages/about_networks.dart @@ -3,6 +3,7 @@ import 'package:url_launcher/url_launcher_string.dart'; import 'package:web3modal_flutter/constants/key_constants.dart'; import 'package:web3modal_flutter/constants/string_constants.dart'; +import 'package:web3modal_flutter/web3modal_flutter.dart'; import 'package:web3modal_flutter/widgets/buttons/simple_icon_button.dart'; import 'package:web3modal_flutter/widgets/help/help_section.dart'; import 'package:web3modal_flutter/widgets/navigation/navbar.dart'; @@ -51,6 +52,9 @@ class AboutNetworks extends StatelessWidget { ), rightIcon: 'assets/icons/arrow_top_right.svg', title: 'Learn more', + size: BaseButtonSize.small, + iconSize: 12.0, + fontSize: 14.0, ), const SizedBox(height: 8.0), ], diff --git a/lib/pages/connect_wallet_page.dart b/lib/pages/connect_wallet_page.dart index f5fade62..b5a6c11a 100644 --- a/lib/pages/connect_wallet_page.dart +++ b/lib/pages/connect_wallet_page.dart @@ -170,13 +170,22 @@ class _ConnectWalletPageState extends State color: themeColors.error100, ), ) - : Text( - 'Continue in $walletName', - textAlign: TextAlign.center, - style: themeData.textStyles.paragraph500.copyWith( - color: themeColors.foreground100, - ), - ), + : !walletInstalled && + _selectedSegment == SegmentOption.mobile + ? Text( + 'App not installed', + textAlign: TextAlign.center, + style: themeData.textStyles.paragraph500.copyWith( + color: themeColors.foreground100, + ), + ) + : Text( + 'Continue in $walletName', + textAlign: TextAlign.center, + style: themeData.textStyles.paragraph500.copyWith( + color: themeColors.foreground100, + ), + ), const SizedBox.square(dimension: 8.0), errorConnection ? Text( @@ -186,16 +195,19 @@ class _ConnectWalletPageState extends State color: themeColors.foreground200, ), ) - : Text( - webOnlyWallet || - _selectedSegment == SegmentOption.browser - ? 'Open and continue in a new browser tab' - : 'Accept connection request in the wallet', - textAlign: TextAlign.center, - style: themeData.textStyles.small500.copyWith( - color: themeColors.foreground200, - ), - ), + : !walletInstalled && + _selectedSegment == SegmentOption.mobile + ? SizedBox.shrink() + : Text( + webOnlyWallet || + _selectedSegment == SegmentOption.browser + ? 'Open and continue in a new browser tab' + : 'Accept connection request in the wallet', + textAlign: TextAlign.center, + style: themeData.textStyles.small500.copyWith( + color: themeColors.foreground200, + ), + ), const SizedBox.square(dimension: kPadding16), Visibility( visible: isPortrait && @@ -217,7 +229,7 @@ class _ConnectWalletPageState extends State onTap: () => service.connectSelectedWallet( inBrowser: _selectedSegment == SegmentOption.browser, ), - leftIcon: 'assets/icons/arrow_top_right.svg', + rightIcon: 'assets/icons/arrow_top_right.svg', title: 'Open', backgroundColor: Colors.transparent, foregroundColor: themeColors.accent100, @@ -262,8 +274,10 @@ class _ConnectWalletPageState extends State if (!isPortrait) const SizedBox.square(dimension: kPadding8), SimpleIconButton( onTap: () => _copyToClipboard(context), - leftIcon: 'assets/icons/copy.svg', + leftIcon: 'assets/icons/copy_14.svg', + iconSize: 13.0, title: 'Copy link', + fontSize: 14.0, backgroundColor: Colors.transparent, foregroundColor: themeColors.foreground200, overlayColor: MaterialStateProperty.all( diff --git a/lib/pages/qr_code_page.dart b/lib/pages/qr_code_page.dart index 5a40422a..7e849a5a 100644 --- a/lib/pages/qr_code_page.dart +++ b/lib/pages/qr_code_page.dart @@ -1,7 +1,9 @@ +import 'package:event/event.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:web3modal_flutter/constants/key_constants.dart'; +import 'package:web3modal_flutter/services/w3m_service/i_w3m_service.dart'; import 'package:web3modal_flutter/theme/constants.dart'; import 'package:web3modal_flutter/theme/w3m_theme.dart'; import 'package:web3modal_flutter/widgets/buttons/simple_icon_button.dart'; @@ -12,9 +14,46 @@ import 'package:web3modal_flutter/widgets/navigation/navbar.dart'; import 'package:web3modal_flutter/utils/toast/toast_message.dart'; import 'package:web3modal_flutter/utils/toast/toast_utils_singleton.dart'; -class QRCodePage extends StatelessWidget { +class QRCodePage extends StatefulWidget { const QRCodePage() : super(key: Web3ModalKeyConstants.qrCodePageKey); + @override + State createState() => _QRCodePageState(); +} + +class _QRCodePageState extends State { + IW3MService? _service; + Widget? _qrQodeWidget; + // + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) async { + _service = Web3ModalProvider.of(context).service; + _service!.addListener(_rebuildListener); + _service!.onPairingExpire.subscribe(_onPairingExpire); + await _service!.buildConnectionUri(); + _qrQodeWidget = QRCodeWidget( + uri: _service!.wcUri!, + logoPath: 'assets/png/logo_wc.png', + ); + }); + } + + void _rebuildListener() => setState(() {}); + void _onPairingExpire(EventArgs? args) async { + await _service!.buildConnectionUri(); + } + + @override + void dispose() async { + _service!.onPairingExpire.unsubscribe(_onPairingExpire); + _service!.removeListener(_rebuildListener); + _service!.expirePreviousInactivePairings(); + super.dispose(); + } + @override Widget build(BuildContext context) { final themeData = Web3ModalTheme.getDataOf(context); @@ -28,9 +67,9 @@ class QRCodePage extends StatelessWidget { child: Flex( direction: isPortrait ? Axis.vertical : Axis.horizontal, children: [ - const Padding( - padding: EdgeInsets.all(16.0), - child: QRCodeWidget(logoPath: 'assets/png/logo_wc.png'), + Padding( + padding: EdgeInsets.all(kPadding16), + child: _qrQodeWidget ?? SizedBox.shrink(), ), Container( constraints: BoxConstraints( @@ -55,8 +94,10 @@ class QRCodePage extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: kPadding12), child: SimpleIconButton( onTap: () => _copyToClipboard(context), - leftIcon: 'assets/icons/copy.svg', + leftIcon: 'assets/icons/copy_14.svg', + iconSize: 13.0, title: 'Copy link', + fontSize: 14.0, backgroundColor: Colors.transparent, foregroundColor: themeColors.foreground200, overlayColor: MaterialStateProperty.all( diff --git a/lib/services/w3m_service/w3m_service.dart b/lib/services/w3m_service/w3m_service.dart index ee532c51..709b1c54 100644 --- a/lib/services/w3m_service/w3m_service.dart +++ b/lib/services/w3m_service/w3m_service.dart @@ -477,9 +477,11 @@ class W3MService with ChangeNotifier implements IW3MService { '[$runtimeType] error launching wallet. ' '${selectedWalletRedirect?.toString()}', ); - toastUtils.instance.show( - ToastMessage(type: ToastType.error, text: e.message), - ); + if (e.message.toLowerCase() != 'app not installed') { + toastUtils.instance.show( + ToastMessage(type: ToastType.error, text: e.message), + ); + } } catch (e, s) { W3MLoggerUtil.logger.e('[$runtimeType] error launching wallet. $e, $s'); } diff --git a/lib/utils/toast/toast_message.dart b/lib/utils/toast/toast_message.dart index 02e049e6..5c418e94 100644 --- a/lib/utils/toast/toast_message.dart +++ b/lib/utils/toast/toast_message.dart @@ -27,7 +27,7 @@ class ToastMessage { assetColor: themeColors.success100, circleColor: themeColors.success100.withOpacity(0.15), borderColor: Colors.transparent, - padding: 4.0, + padding: 6.0, size: 24.0, ); case ToastType.error: @@ -36,7 +36,7 @@ class ToastMessage { assetColor: themeColors.error100, circleColor: themeColors.error100.withOpacity(0.15), borderColor: Colors.transparent, - padding: 4.0, + padding: 6.0, size: 24.0, ); default: @@ -45,7 +45,7 @@ class ToastMessage { assetColor: themeColors.accent100, circleColor: themeColors.accent100.withOpacity(0.15), borderColor: Colors.transparent, - padding: 4.0, + padding: 6.0, size: 24.0, ); } diff --git a/lib/utils/util.dart b/lib/utils/util.dart index f78fb636..c2122a1f 100644 --- a/lib/utils/util.dart +++ b/lib/utils/util.dart @@ -8,12 +8,12 @@ class Util { return short && value.length > 8 ? '${value.substring(0, 8)}..' : value; } - static String truncate(String value, {int length = 8}) { + static String truncate(String value, {int length = 4}) { if (value.length <= length) { return value; } - return '${value.substring(0, 4)}...${value.substring(value.length - 4)}'; + return '${value.substring(0, length)}...${value.substring(value.length - length)}'; } static List get defaultAvatarColors => [ diff --git a/lib/widgets/buttons/address_button.dart b/lib/widgets/buttons/address_button.dart index 3e6eddd3..cb8cbafb 100644 --- a/lib/widgets/buttons/address_button.dart +++ b/lib/widgets/buttons/address_button.dart @@ -76,12 +76,24 @@ class _AddressButtonState extends State { }, ), ), - icon: W3MAccountAvatar( - service: widget.service, - size: widget.size.height - 12.0, - disabled: widget.onTap == null, + overridePadding: MaterialStateProperty.all( + EdgeInsets.only( + left: 6.0, + right: widget.size == BaseButtonSize.small ? 12.0 : 16.0, + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + W3MAccountAvatar( + service: widget.service, + size: widget.size.height * 0.7, + disabled: widget.onTap == null, + ), + const SizedBox.square(dimension: 4.0), + Text(Util.truncate(_address ?? '')), + ], ), - child: Text(Util.truncate(_address ?? '')), ); } } diff --git a/lib/widgets/buttons/balance_button.dart b/lib/widgets/buttons/balance_button.dart index a10b39cc..e71feb2f 100644 --- a/lib/widgets/buttons/balance_button.dart +++ b/lib/widgets/buttons/balance_button.dart @@ -88,11 +88,23 @@ class _BalanceButtonState extends State { }, ), ), - icon: RoundedIcon( - imageUrl: _tokenImage, - size: widget.size.height - 12.0, + overridePadding: MaterialStateProperty.all( + EdgeInsets.only( + left: 6.0, + right: widget.size == BaseButtonSize.small ? 12.0 : 16.0, + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + RoundedIcon( + imageUrl: _tokenImage, + size: widget.size.height * 0.7, + ), + const SizedBox.square(dimension: 4.0), + Text('$_balance ${_tokenName ?? ''}'), + ], ), - child: Text('$_balance ${_tokenName ?? ''}'), ); } } diff --git a/lib/widgets/buttons/base_button.dart b/lib/widgets/buttons/base_button.dart index d861b532..1dc805b1 100644 --- a/lib/widgets/buttons/base_button.dart +++ b/lib/widgets/buttons/base_button.dart @@ -17,7 +17,7 @@ enum BaseButtonSize { double get iconSize { switch (this) { case small: - return 20.0; + return 16.0; default: return 20.0; } @@ -29,13 +29,11 @@ class BaseButton extends StatelessWidget { super.key, required this.child, required this.size, - this.icon, this.onTap, this.buttonStyle, this.overridePadding, }); final Widget child; - final Widget? icon; final VoidCallback? onTap; final BaseButtonSize size; final ButtonStyle? buttonStyle; @@ -47,19 +45,27 @@ class BaseButton extends StatelessWidget { final textStyle = size == BaseButtonSize.small ? themeData.textStyles.small600 : themeData.textStyles.paragraph600; - return FilledButton.icon( + return FilledButton( onPressed: onTap, + child: child, style: ButtonStyle( textStyle: MaterialStateProperty.all(textStyle), - minimumSize: MaterialStateProperty.all(Size(40.0, size.height)), - maximumSize: MaterialStateProperty.all(Size(1000.0, size.height)), + minimumSize: MaterialStateProperty.all(Size( + size.height, + size.height, + )), + maximumSize: MaterialStateProperty.all(Size( + 1000.0, + size.height, + )), padding: overridePadding ?? MaterialStateProperty.all( - const EdgeInsets.only(left: 8.0, right: 16.0), + const EdgeInsets.only( + left: 16.0, + right: 16.0, + ), ), ).merge(buttonStyle), - label: child, - icon: icon ?? const SizedBox.shrink(), ); } } diff --git a/lib/widgets/buttons/connect_button.dart b/lib/widgets/buttons/connect_button.dart index 4ded1efd..465cb42a 100644 --- a/lib/widgets/buttons/connect_button.dart +++ b/lib/widgets/buttons/connect_button.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:web3modal_flutter/constants/string_constants.dart'; import 'package:web3modal_flutter/services/w3m_service/i_w3m_service.dart'; +import 'package:web3modal_flutter/theme/constants.dart'; import 'package:web3modal_flutter/theme/w3m_theme.dart'; import 'package:web3modal_flutter/widgets/buttons/base_button.dart'; @@ -30,11 +31,7 @@ class ConnectButton extends StatelessWidget { @override Widget build(BuildContext context) { - final themeData = Web3ModalTheme.getDataOf(context); final themeColors = Web3ModalTheme.colorsOf(context); - final textStyle = size == BaseButtonSize.small - ? themeData.textStyles.small600 - : themeData.textStyles.paragraph600; final connecting = state == ConnectButtonState.connecting; final disabled = state == ConnectButtonState.disabled; final connected = state == ConnectButtonState.connected; @@ -81,24 +78,34 @@ class ConnectButton extends StatelessWidget { }, ), ), + overridePadding: MaterialStateProperty.all( + connecting || serviceStatus.isLoading + ? const EdgeInsets.only(left: 6.0, right: 16.0) + : const EdgeInsets.only(left: 16.0, right: 16.0), + ), child: connecting || serviceStatus.isLoading ? Row( mainAxisSize: MainAxisSize.min, children: [ - SizedBox( - height: (textStyle.fontSize ?? 20.0) * 0.8, - width: (textStyle.fontSize ?? 20.0) * 0.8, + Container( + width: size.height * 0.7, + height: size.height * 0.7, + padding: const EdgeInsets.all(kPadding6), child: CircularProgressIndicator( color: themeColors.accent100, - strokeWidth: 2.0, + strokeWidth: size == BaseButtonSize.small ? 1.0 : 1.5, ), ), - const SizedBox.square(dimension: 8.0), + const SizedBox.square(dimension: 4.0), if (connecting) Text( titleOverride ?? StringConstants.connectButtonConnecting), if (serviceStatus.isLoading) - Text(titleOverride ?? StringConstants.connectButtonIdle), + size == BaseButtonSize.small + ? Text(titleOverride ?? + StringConstants.connectButtonIdleShort) + : Text( + titleOverride ?? StringConstants.connectButtonIdle), ], ) : connected diff --git a/lib/widgets/buttons/network_button.dart b/lib/widgets/buttons/network_button.dart index 543805a2..5849fe11 100644 --- a/lib/widgets/buttons/network_button.dart +++ b/lib/widgets/buttons/network_button.dart @@ -4,6 +4,7 @@ import 'package:web3modal_flutter/constants/string_constants.dart'; import 'package:web3modal_flutter/models/w3m_chain_info.dart'; import 'package:web3modal_flutter/services/explorer_service/explorer_service_singleton.dart'; import 'package:web3modal_flutter/services/w3m_service/i_w3m_service.dart'; +import 'package:web3modal_flutter/theme/constants.dart'; import 'package:web3modal_flutter/theme/w3m_theme.dart'; import 'package:web3modal_flutter/utils/asset_util.dart'; import 'package:web3modal_flutter/widgets/buttons/base_button.dart'; @@ -67,24 +68,37 @@ class NetworkButton extends StatelessWidget { }, ), ), - icon: serviceStatus.isLoading - ? SizedBox( - width: 18, - height: 18, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : RoundedIcon( - assetPath: 'assets/icons/network.svg', - imageUrl: imageUrl, - size: size.height - 12.0, - assetColor: themeColors.inverse100, - padding: 6.0, - ), - child: Text( - chainInfo?.chainName ?? - (size == BaseButtonSize.small - ? StringConstants.selectNetworkShort - : StringConstants.selectNetwork), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + serviceStatus.isLoading + ? Container( + width: size.height * 0.7, + height: size.height * 0.7, + padding: const EdgeInsets.all(kPadding6), + child: CircularProgressIndicator( + color: themeColors.accent100, + strokeWidth: size == BaseButtonSize.small ? 1.0 : 1.5, + ), + ) + : RoundedIcon( + assetPath: 'assets/icons/network.svg', + imageUrl: imageUrl, + size: size.height * 0.7, + assetColor: themeColors.inverse100, + padding: size == BaseButtonSize.small ? 5.0 : 6.0, + ), + const SizedBox.square(dimension: 4.0), + Text( + chainInfo?.chainName ?? + (size == BaseButtonSize.small + ? StringConstants.selectNetworkShort + : StringConstants.selectNetwork), + ), + ], + ), + overridePadding: MaterialStateProperty.all( + const EdgeInsets.only(left: 6.0, right: 16.0), ), ); } diff --git a/lib/widgets/buttons/simple_icon_button.dart b/lib/widgets/buttons/simple_icon_button.dart index 5d5f32df..347eea88 100644 --- a/lib/widgets/buttons/simple_icon_button.dart +++ b/lib/widgets/buttons/simple_icon_button.dart @@ -8,7 +8,9 @@ class SimpleIconButton extends StatelessWidget { super.key, required this.onTap, required this.title, + this.fontSize, this.leftIcon, + this.iconSize, this.rightIcon, this.backgroundColor, this.foregroundColor, @@ -18,7 +20,9 @@ class SimpleIconButton extends StatelessWidget { }); final VoidCallback? onTap; final String title; + final double? fontSize; final String? leftIcon, rightIcon; + final double? iconSize; final Color? backgroundColor, foregroundColor; final BaseButtonSize size; final MaterialStateProperty? overlayColor; @@ -55,6 +59,8 @@ class SimpleIconButton extends StatelessWidget { }, ) : null, + padding: + MaterialStateProperty.all(EdgeInsets.all(0.0)), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -70,22 +76,23 @@ class SimpleIconButton extends StatelessWidget { foregroundColor ?? themeColors.inverse100, BlendMode.srcIn, ), - width: 14.0, - height: 14.0, + width: iconSize ?? 14.0, + height: iconSize ?? 14.0, ), - const SizedBox.square(dimension: 6.0), + const SizedBox.square(dimension: 4.0), ], ), Text( title, style: textStyles.paragraph600.copyWith( color: foregroundColor, + fontSize: fontSize, ), ), if (rightIcon != null) Row( children: [ - const SizedBox.square(dimension: 8.0), + const SizedBox.square(dimension: 4.0), SvgPicture.asset( rightIcon!, package: 'web3modal_flutter', @@ -93,13 +100,24 @@ class SimpleIconButton extends StatelessWidget { foregroundColor ?? themeColors.inverse100, BlendMode.srcIn, ), - width: 14.0, - height: 14.0, + width: iconSize ?? 14.0, + height: iconSize ?? 14.0, ), ], ), ], ), + overridePadding: MaterialStateProperty.all( + size == BaseButtonSize.regular + ? EdgeInsets.only( + left: (leftIcon != null) ? 12.0 : 16.0, + right: (rightIcon != null) ? 12.0 : 16.0, + ) + : EdgeInsets.only( + left: (leftIcon != null) ? 10.0 : 12.0, + right: (rightIcon != null) ? 10.0 : 12.0, + ), + ), ); } } diff --git a/lib/widgets/icons/rounded_icon.dart b/lib/widgets/icons/rounded_icon.dart index 80be5d85..881be082 100644 --- a/lib/widgets/icons/rounded_icon.dart +++ b/lib/widgets/icons/rounded_icon.dart @@ -32,8 +32,8 @@ class RoundedIcon extends StatelessWidget { border: Border.fromBorderSide( BorderSide( color: borderColor ?? themeColors.grayGlass005, - width: 2, - strokeAlign: BorderSide.strokeAlignCenter, + width: 1, + strokeAlign: BorderSide.strokeAlignInside, ), ), color: circleColor ?? themeColors.grayGlass015, diff --git a/lib/widgets/lists/grid_items/wallet_grid_item.dart b/lib/widgets/lists/grid_items/wallet_grid_item.dart index 3fd0c759..eb0b73af 100644 --- a/lib/widgets/lists/grid_items/wallet_grid_item.dart +++ b/lib/widgets/lists/grid_items/wallet_grid_item.dart @@ -47,6 +47,7 @@ class WalletGridItem extends StatelessWidget { ), ), ), + const SizedBox(height: 2.0), Padding( padding: const EdgeInsets.only( top: kPadding6, @@ -73,7 +74,6 @@ class WalletGridItem extends StatelessWidget { ], ), ), - const SizedBox(height: 2.0), ], ), ); diff --git a/lib/widgets/lists/list_items/download_wallet_item.dart b/lib/widgets/lists/list_items/download_wallet_item.dart index 8f9950ed..3a934e3e 100644 --- a/lib/widgets/lists/list_items/download_wallet_item.dart +++ b/lib/widgets/lists/list_items/download_wallet_item.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:web3modal_flutter/theme/w3m_theme.dart'; +import 'package:web3modal_flutter/widgets/buttons/base_button.dart'; import 'package:web3modal_flutter/widgets/buttons/simple_icon_button.dart'; import 'package:web3modal_flutter/widgets/web3modal_provider.dart'; import 'package:web3modal_flutter/widgets/lists/list_items/wallet_list_item.dart'; @@ -46,6 +47,9 @@ class DownloadWalletItem extends StatelessWidget { rightIcon: 'assets/icons/chevron_right.svg', backgroundColor: Colors.transparent, foregroundColor: themeColors.accent100, + size: BaseButtonSize.small, + fontSize: 14.0, + iconSize: 12.0, ), ); } diff --git a/lib/widgets/miscellaneous/segmented_control.dart b/lib/widgets/miscellaneous/segmented_control.dart index fc63ca34..ae58e25b 100644 --- a/lib/widgets/miscellaneous/segmented_control.dart +++ b/lib/widgets/miscellaneous/segmented_control.dart @@ -49,7 +49,7 @@ class _SegmentedControlState extends State { ), const SizedBox.square(dimension: 4.0), Text( - 'Native', + 'Mobile', style: themeData.textStyles.small500.copyWith( color: _selectedSegment == SegmentOption.mobile ? themeColors.foreground100 diff --git a/lib/widgets/w3m_account_button.dart b/lib/widgets/w3m_account_button.dart index 6ee4b64b..9d87a1d8 100644 --- a/lib/widgets/w3m_account_button.dart +++ b/lib/widgets/w3m_account_button.dart @@ -60,6 +60,10 @@ class _W3MAccountButtonState extends State { @override Widget build(BuildContext context) { + final themeData = Web3ModalTheme.getDataOf(context); + final textStyle = widget.size == BaseButtonSize.small + ? themeData.textStyles.small600 + : themeData.textStyles.paragraph600; final themeColors = Web3ModalTheme.colorsOf(context); final radiuses = Web3ModalTheme.radiusesOf(context); final borderRadius = radiuses.isSquare() ? 0.0 : widget.size.height / 2; @@ -71,7 +75,7 @@ class _W3MAccountButtonState extends State { size: widget.size, onTap: widget.service.status.isInitialized ? _onTap : null, overridePadding: MaterialStateProperty.all( - const EdgeInsets.only(right: 4.0), + const EdgeInsets.only(left: 4.0, right: 4.0), ), buttonStyle: ButtonStyle( backgroundColor: MaterialStateProperty.resolveWith( @@ -101,81 +105,165 @@ class _W3MAccountButtonState extends State { }, ), ), - icon: BaseButton( - size: BaseButtonSize.small, - onTap: _onTap, - overridePadding: MaterialStateProperty.all( - const EdgeInsets.only(left: 8.0), - ), - buttonStyle: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Colors.transparent), - foregroundColor: MaterialStateProperty.resolveWith( - (states) { - if (states.contains(MaterialState.disabled)) { - return themeColors.grayGlass015; - } - return themeColors.foreground100; - }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + _BalanceButton( + isLoading: widget.service.status.isLoading, + balance: _balance, + tokenName: _tokenName, + tokenImage: _tokenImage, + iconSize: widget.size.iconSize + 4.0, + buttonSize: widget.size, + onTap: _onTap, ), - ), - icon: widget.service.status.isLoading - ? SizedBox( - width: 18, - height: 18, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : RoundedIcon( - imageUrl: _tokenImage, - size: widget.size.iconSize + 4.0, + const SizedBox.square(dimension: 4.0), + Padding( + padding: EdgeInsets.only( + top: widget.size == BaseButtonSize.small ? 4.0 : 0.0, + bottom: widget.size == BaseButtonSize.small ? 4.0 : 0.0, + ), + child: BaseButton( + size: BaseButtonSize.small, + onTap: _onTap, + overridePadding: MaterialStateProperty.all( + EdgeInsets.only( + left: widget.size == BaseButtonSize.small ? 4.0 : 6.0, + right: 8.0, + ), ), - child: Text('$_balance ${_tokenName ?? ''}'), - ), - child: BaseButton( - size: BaseButtonSize.small, - onTap: _onTap, - overridePadding: MaterialStateProperty.all( - const EdgeInsets.only(left: 8.0, right: 8.0), - ), - buttonStyle: ButtonStyle( - backgroundColor: MaterialStateProperty.resolveWith( - (states) { - if (states.contains(MaterialState.disabled)) { - return themeColors.grayGlass005; - } - return themeColors.grayGlass010; - }, - ), - foregroundColor: MaterialStateProperty.resolveWith( - (states) { - if (states.contains(MaterialState.disabled)) { - return themeColors.grayGlass015; - } - return themeColors.foreground175; - }, - ), - shape: MaterialStateProperty.resolveWith( - (states) { - return RoundedRectangleBorder( - side: states.contains(MaterialState.disabled) - ? BorderSide( + buttonStyle: ButtonStyle( + backgroundColor: MaterialStateProperty.resolveWith( + (states) { + if (states.contains(MaterialState.disabled)) { + return themeColors.grayGlass005; + } + return themeColors.grayGlass010; + }, + ), + foregroundColor: MaterialStateProperty.resolveWith( + (states) { + if (states.contains(MaterialState.disabled)) { + return themeColors.grayGlass015; + } + return themeColors.foreground175; + }, + ), + shape: + MaterialStateProperty.resolveWith( + (states) { + return RoundedRectangleBorder( + side: states.contains(MaterialState.disabled) + ? BorderSide( + color: themeColors.grayGlass005, + width: 1.0, + ) + : BorderSide( + color: themeColors.grayGlass010, + width: 1.0, + ), + borderRadius: BorderRadius.circular(innerBorderRadius), + ); + }, + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(widget.size.iconSize), + border: Border.all( color: themeColors.grayGlass005, width: 1.0, - ) - : BorderSide( - color: themeColors.grayGlass010, - width: 1.0, + strokeAlign: BorderSide.strokeAlignInside, ), - borderRadius: BorderRadius.circular(innerBorderRadius), - ); - }, + ), + child: W3MAccountAvatar( + service: widget.service, + size: widget.size.iconSize, + disabled: false, + ), + ), + const SizedBox.square(dimension: 4.0), + Text( + Util.truncate( + _address ?? '', + length: widget.size == BaseButtonSize.small ? 2 : 4, + ), + style: textStyle, + ), + ], + ), + ), ), + ], + ), + ); + } +} + +class _BalanceButton extends StatelessWidget { + const _BalanceButton({ + required this.onTap, + required this.isLoading, + required this.balance, + required this.tokenName, + required this.tokenImage, + required this.iconSize, + required this.buttonSize, + }); + final VoidCallback? onTap; + final bool isLoading; + final String balance; + final String? tokenName; + final String? tokenImage; + final double iconSize; + final BaseButtonSize buttonSize; + + @override + Widget build(BuildContext context) { + final themeColors = Web3ModalTheme.colorsOf(context); + final themeData = Web3ModalTheme.getDataOf(context); + final textStyle = buttonSize == BaseButtonSize.small + ? themeData.textStyles.small600 + : themeData.textStyles.paragraph600; + return BaseButton( + size: BaseButtonSize.small, + onTap: onTap, + overridePadding: MaterialStateProperty.all( + const EdgeInsets.only(left: 2.0), + ), + buttonStyle: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.transparent), + foregroundColor: MaterialStateProperty.resolveWith( + (states) { + if (states.contains(MaterialState.disabled)) { + return themeColors.grayGlass015; + } + return themeColors.foreground100; + }, ), - icon: W3MAccountAvatar( - service: widget.service, - size: widget.size.iconSize, - disabled: false, - ), - child: Text(Util.truncate(_address ?? '')), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + isLoading + ? SizedBox( + width: 18, + height: 18, + child: CircularProgressIndicator(strokeWidth: 1.5), + ) + : RoundedIcon( + imageUrl: tokenImage, + size: iconSize, + ), + const SizedBox.square(dimension: 4.0), + Text( + '$balance ${tokenName ?? ''}', + style: textStyle, + ), + ], ), ); } diff --git a/lib/widgets/w3m_qr_code.dart b/lib/widgets/w3m_qr_code.dart index dd4b04f4..e1262385 100644 --- a/lib/widgets/w3m_qr_code.dart +++ b/lib/widgets/w3m_qr_code.dart @@ -1,54 +1,19 @@ -import 'package:event/event.dart'; import 'package:flutter/material.dart'; import 'package:qr_flutter_wc/qr_flutter_wc.dart'; - -import 'package:web3modal_flutter/services/w3m_service/i_w3m_service.dart'; import 'package:web3modal_flutter/theme/constants.dart'; import 'package:web3modal_flutter/theme/w3m_theme.dart'; import 'package:web3modal_flutter/web3modal_flutter.dart'; import 'package:web3modal_flutter/widgets/miscellaneous/content_loading.dart'; - import 'package:web3modal_flutter/widgets/miscellaneous/responsive_container.dart'; -import 'package:web3modal_flutter/widgets/web3modal_provider.dart'; -class QRCodeWidget extends StatefulWidget { +class QRCodeWidget extends StatelessWidget { const QRCodeWidget({ super.key, + required this.uri, this.logoPath = '', }); - final String logoPath; - - @override - State createState() => _QRCodeWidgetState(); -} - -class _QRCodeWidgetState extends State { - IW3MService? _service; - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback((_) async { - _service = Web3ModalProvider.of(context).service; - _service!.addListener(_rebuildListener); - _service!.onPairingExpire.subscribe(_onPairingExpire); - await _service!.buildConnectionUri(); - }); - } - - void _rebuildListener() => setState(() {}); - void _onPairingExpire(EventArgs? args) async { - await _service!.buildConnectionUri(); - } - - @override - void dispose() async { - _service!.onPairingExpire.unsubscribe(_onPairingExpire); - _service!.removeListener(_rebuildListener); - _service!.expirePreviousInactivePairings(); - super.dispose(); - } + final String logoPath, uri; @override Widget build(BuildContext context) { @@ -70,10 +35,10 @@ class _QRCodeWidgetState extends State { padding: const EdgeInsets.all(16.0), child: AspectRatio( aspectRatio: 1.0, - child: (_service?.wcUri == null) + child: uri.isEmpty ? const ContentLoading() : QrImageView( - data: _service!.wcUri!, + data: uri, version: QrVersions.auto, errorCorrectionLevel: QrErrorCorrectLevel.Q, eyeStyle: const QrEyeStyle( @@ -84,8 +49,8 @@ class _QRCodeWidgetState extends State { dataModuleShape: QrDataModuleShape.circle, color: Colors.black, ), - embeddedImage: widget.logoPath.isNotEmpty - ? AssetImage(widget.logoPath, package: 'web3modal_flutter') + embeddedImage: logoPath.isNotEmpty + ? AssetImage(logoPath, package: 'web3modal_flutter') : null, embeddedImageStyle: QrEmbeddedImageStyle( size: Size(imageSize, imageSize), diff --git a/pubspec.lock b/pubspec.lock index 52fe1b70..064bf677 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -684,10 +684,10 @@ packages: dependency: "direct main" description: name: qr_flutter_wc - sha256: "1939a737eded2bdbcc96fefede3edbfbe252d06ad3bba0195237096a068e4db2" + sha256: a926bf6bcf7d350eea48480e205ccffffca5cc84b5d77fb2b256318693e40d07 url: "https://pub.dev" source: hosted - version: "0.0.1" + version: "0.0.3" rxdart: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4171c372..df1d07f7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: web3modal_flutter description: "WalletConnect Web3Modal: Simple, intuitive wallet login. With this drop-in UI SDK, enable any wallet's users to seamlessly log in to your app and enjoy a unified experience" -version: 3.0.0-beta16 +version: 3.0.0-beta17 repository: https://github.com/WalletConnect/Web3ModalFlutter environment: @@ -21,7 +21,7 @@ dependencies: json_annotation: ^4.8.1 logger: ^2.0.2+1 mockito: ^5.4.2 - qr_flutter_wc: ^0.0.1 + qr_flutter_wc: 0.0.3 shared_preferences: ^2.2.0 shimmer: ^3.0.0 universal_io: ^2.2.0