diff --git a/packages/komodo_defi_sdk/example/lib/widgets/assets/asset_item.dart b/packages/komodo_defi_sdk/example/lib/widgets/assets/asset_item.dart index 6b4f97d0..92789b17 100644 --- a/packages/komodo_defi_sdk/example/lib/widgets/assets/asset_item.dart +++ b/packages/komodo_defi_sdk/example/lib/widgets/assets/asset_item.dart @@ -38,7 +38,7 @@ class AssetItemWidget extends StatelessWidget { ], ), tileColor: isCompatible ? null : Colors.grey[200], - leading: AssetIcon(asset.id, size: 32), + leading: AssetLogo(asset, size: 32), trailing: _AssetItemTrailing(asset: asset, isEnabled: isCompatible), // ignore: avoid_redundant_argument_values enabled: isCompatible, diff --git a/packages/komodo_ui/lib/komodo_ui.dart b/packages/komodo_ui/lib/komodo_ui.dart index f988f0b5..b98d4749 100644 --- a/packages/komodo_ui/lib/komodo_ui.dart +++ b/packages/komodo_ui/lib/komodo_ui.dart @@ -26,6 +26,7 @@ export 'src/core/inputs/fee_info_input.dart'; export 'src/core/inputs/search_coin_select.dart'; export 'src/core/inputs/searchable_select.dart'; export 'src/defi/asset/asset_icon.dart'; +export 'src/defi/asset/asset_logo.dart'; export 'src/defi/asset/crypto_asset_card.dart'; export 'src/defi/asset/metric_selector.dart'; export 'src/defi/asset/trend_percentage_text.dart'; diff --git a/packages/komodo_ui/lib/src/defi/asset/asset_logo.dart b/packages/komodo_ui/lib/src/defi/asset/asset_logo.dart new file mode 100644 index 00000000..e4c73013 --- /dev/null +++ b/packages/komodo_ui/lib/src/defi/asset/asset_logo.dart @@ -0,0 +1,142 @@ +import 'package:flutter/material.dart'; +import 'package:komodo_defi_types/komodo_defi_types.dart'; + +import 'package:komodo_ui/src/defi/asset/asset_icon.dart'; + +/// A widget that displays an [AssetIcon] with its protocol icon overlaid. +/// +/// Similar to the legacy CoinLogo, but built on top of the new [Asset] +/// and [AssetIcon] APIs. +class AssetLogo extends StatelessWidget { + /// Creates a new [AssetLogo] widget. + /// + /// [asset] is the asset for which the logo should be displayed. + /// [isDisabled] indicates whether the asset is disabled, in which case + /// the icon will be displayed with reduced opacity. + /// [size] is the size of the main asset icon, defaulting to 41 pixels. + /// Example usage: + /// ```dart + /// AssetLogo(asset) + /// ``` + const AssetLogo( + this.asset, { + this.size = 41, + this.isDisabled = false, + super.key, + }); + + /// Asset to display the logo for. + final Asset asset; + + /// Size of the main asset icon. + final double size; + + /// Whether the asset is disabled. Disabled icons are displayed + /// with reduced opacity. + final bool isDisabled; + + @override + Widget build(BuildContext context) { + // Existing komodo-wallet implementation doesn't show protocol icon + // for UTXO assets (like BTC, LTC, etc.) so we follow the same logic here. + final protocolTicker = asset.protocol.subClass.iconTicker; + final shouldShowProtocolIcon = asset.protocol.subClass != CoinSubClass.utxo; + + return Stack( + clipBehavior: Clip.none, + children: [ + AssetIcon(asset.id, size: size, suspended: isDisabled), + if (shouldShowProtocolIcon) + AssetProtocolIcon(protocolTicker: protocolTicker, logoSize: size), + ], + ); + } +} + +/// A widget that displays a protocol icon with a circular border and shadow, +/// positioned absolutely within its parent widget. +/// +/// This widget is typically used to overlay a protocol icon on top of an asset +/// logo to indicate the blockchain protocol or network the asset belongs to. +class AssetProtocolIcon extends StatelessWidget { + /// Creates an [AssetProtocolIcon] widget. + /// + /// The [protocolTicker] and [logoSize] parameters are required. + /// + /// Optional parameters with their default behaviors: + /// - [protocolSizeWithBorder]: Defaults to `logoSize * 0.45` + /// - [protocolBorder]: Defaults to `protocolSizeWithBorder * 0.1` + /// - [protocolLeftPosition]: Defaults to `logoSize * 0.55` + /// - [protocolTopPosition]: Defaults to `logoSize * 0.55` + const AssetProtocolIcon({ + required this.protocolTicker, + required this.logoSize, + this.protocolSizeWithBorder, + this.protocolBorder, + this.protocolLeftPosition, + this.protocolTopPosition, + super.key, + }); + + /// The ticker symbol of the protocol to display as an icon. + final String protocolTicker; + + /// The size of the main logo that this protocol icon will be + /// positioned relative to. + final double logoSize; + + /// The total size of the protocol icon including its border. + /// If null, defaults to `logoSize * 0.45`. + final double? protocolSizeWithBorder; + + /// The thickness of the border around the protocol icon. + /// If null, defaults to `protocolSizeWithBorder * 0.1`. + final double? protocolBorder; + + /// The left position offset for the protocol icon. + /// If null, defaults to `logoSize * 0.55`. + final double? protocolLeftPosition; + + /// The top position offset for the protocol icon. + /// If null, defaults to `logoSize * 0.55`. + final double? protocolTopPosition; + + // Pre-computed values to avoid recalculation in build() + double get _sizeWithBorder => protocolSizeWithBorder ?? logoSize * 0.45; + double get _border => protocolBorder ?? _sizeWithBorder * 0.1; + double get _leftPosition => protocolLeftPosition ?? logoSize * 0.55; + double get _topPosition => protocolTopPosition ?? logoSize * 0.55; + double get _iconSize => _sizeWithBorder - _border; + + @override + Widget build(BuildContext context) { + return Positioned( + left: _leftPosition, + top: _topPosition, + width: _sizeWithBorder, + height: _sizeWithBorder, + child: Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.5), + blurRadius: 2, + ), + ], + ), + child: Container( + width: _iconSize, + height: _iconSize, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Colors.white, + ), + child: AssetIcon.ofTicker(protocolTicker, size: _iconSize), + ), + ), + ); + } +} diff --git a/packages/komodo_ui/lib/src/defi/index.dart b/packages/komodo_ui/lib/src/defi/index.dart index 9cb71d0e..4f6463ba 100644 --- a/packages/komodo_ui/lib/src/defi/index.dart +++ b/packages/komodo_ui/lib/src/defi/index.dart @@ -10,6 +10,7 @@ library komodo_ui.defi; export 'package:decimal/decimal.dart' show Decimal; export 'asset/asset_icon.dart'; +export 'asset/asset_logo.dart'; export 'asset/crypto_asset_card.dart'; export 'asset/metric_selector.dart'; export 'asset/trend_percentage_text.dart';