import 'package:cw_core/wallet_type.dart'; import 'package:flutter/widgets.dart'; import 'dart:math' as math; class AddressFormatter { static Widget buildSegmentedAddress({ required String address, WalletType? walletType, required TextStyle evenTextStyle, TextStyle? oddTextStyle, TextAlign? textAlign, bool shouldTruncate = false, }) { final cleanAddress = address.replaceAll('bitcoincash:', ''); final isMWEB = address.startsWith('ltcmweb'); final chunkSize = walletType != null ? _getChunkSize(walletType) : 4; if (shouldTruncate) { return _buildTruncatedAddress( address: cleanAddress, isMWEB: isMWEB, chunkSize: chunkSize, evenTextStyle: evenTextStyle, oddTextStyle: oddTextStyle ?? evenTextStyle.copyWith(color: evenTextStyle.color!.withAlpha(150)), textAlign: textAlign, ); } else { return _buildFullSegmentedAddress( address: cleanAddress, isMWEB: isMWEB, chunkSize: chunkSize, evenTextStyle: evenTextStyle, oddTextStyle: oddTextStyle ?? evenTextStyle.copyWith(color: evenTextStyle.color!.withAlpha(128)), textAlign: textAlign, ); } } static Widget _buildFullSegmentedAddress({ required String address, required bool isMWEB, required int chunkSize, required TextStyle evenTextStyle, required TextStyle oddTextStyle, TextAlign? textAlign, }) { final chunks = []; if (isMWEB) { const mwebDisplayPrefix = 'ltcmweb'; chunks.add(mwebDisplayPrefix); final startIndex = mwebDisplayPrefix.length; for (int i = startIndex; i < address.length; i += chunkSize) { final chunk = address.substring( i, math.min(i + chunkSize, address.length), ); chunks.add(chunk); } } else { for (int i = 0; i < address.length; i += chunkSize) { final chunk = address.substring( i, math.min(i + chunkSize, address.length), ); chunks.add(chunk); } } final spans = []; for (int i = 0; i < chunks.length; i++) { final style = (i % 2 == 0) ? evenTextStyle : oddTextStyle; spans.add(TextSpan(text: '${chunks[i]} ', style: style)); } return RichText( text: TextSpan(children: spans), textAlign: textAlign ?? TextAlign.start, overflow: TextOverflow.visible, ); } static Widget _buildTruncatedAddress({ required String address, required bool isMWEB, required int chunkSize, required TextStyle evenTextStyle, required TextStyle oddTextStyle, TextAlign? textAlign, }) { if (isMWEB) { const fixedPrefix = 'ltcmweb'; final secondChunkStart = fixedPrefix.length; const chunkSize = 4; final secondChunk = address.substring( secondChunkStart, math.min(secondChunkStart + chunkSize, address.length), ); final lastChunk = address.substring(address.length - chunkSize); final spans = [ TextSpan(text: '$fixedPrefix ', style: evenTextStyle), TextSpan(text: '$secondChunk ', style: oddTextStyle), TextSpan(text: '... ', style: oddTextStyle), TextSpan(text: lastChunk, style: evenTextStyle), ]; return RichText( text: TextSpan(children: spans), textAlign: textAlign ?? TextAlign.start, overflow: TextOverflow.visible, ); } else { final int digitCount = chunkSize; if (address.length <= 2 * digitCount) { return _buildFullSegmentedAddress( address: address, isMWEB: isMWEB, chunkSize: chunkSize, evenTextStyle: evenTextStyle, oddTextStyle: oddTextStyle, textAlign: textAlign, ); } final String firstPart = address.substring(0, digitCount); final String secondPart = address.substring(digitCount, digitCount * 2); final String lastPart = address.substring(address.length - digitCount); final spans = [ TextSpan(text: '$firstPart ', style: evenTextStyle), TextSpan(text: '$secondPart ', style: oddTextStyle), TextSpan(text: '... ', style: oddTextStyle), TextSpan(text: lastPart, style: evenTextStyle), ]; return RichText( text: TextSpan(children: spans), textAlign: textAlign ?? TextAlign.start, overflow: TextOverflow.visible, ); } } static int _getChunkSize(WalletType walletType) { switch (walletType) { case WalletType.monero: case WalletType.wownero: case WalletType.zano: return 6; default: return 4; } } }