Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions lib/src/core/profile_pictures.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,19 @@ const kProfilePictureOptions = <ProfilePictureOption>[
),
];

const _kZnsPrefix = 'zns-';

bool isZnsProfilePictureId(String id) => id.startsWith(_kZnsPrefix);

String _stripZnsPrefix(String id) =>
id.startsWith(_kZnsPrefix) ? id.substring(_kZnsPrefix.length) : id;

ProfilePictureOption? findProfilePictureOption(String id) {
final baseId = _stripZnsPrefix(id);
for (final option in kProfilePictureOptions) {
if (option.id == id) return option;
if (option.id == baseId) return option;
}
if (_legacyKnightIdPattern.hasMatch(id)) {
if (_legacyKnightIdPattern.hasMatch(baseId)) {
return kProfilePictureOptions.first;
}
return null;
Expand Down
3 changes: 2 additions & 1 deletion lib/src/core/widgets/app_profile_picture.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ class AppProfilePicture extends StatelessWidget {
@override
Widget build(BuildContext context) {
final option = resolveProfilePictureOption(profilePictureId);
final isZns = isZnsProfilePictureId(profilePictureId);

return Container(
width: size.dimension,
height: size.dimension,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: context.colors.background.raised,
color: isZns ? const Color(0xFFD4A843) : context.colors.background.raised,
borderRadius: BorderRadius.circular(size.radius),
),
child: Image.asset(
Expand Down
14 changes: 14 additions & 0 deletions lib/src/features/accounts/screens/accounts_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import '../../../providers/account_provider.dart';
import '../../../providers/app_security_provider.dart';
import '../../../providers/sync_provider.dart';
import '../../../providers/wallet_mutation_guard.dart';
import '../../../providers/zns_provider.dart';
import '../widgets/account_name_modal.dart';
import '../widgets/account_profile_picture_modal.dart';
import '../widgets/account_remove_modal.dart';
Expand Down Expand Up @@ -71,6 +72,19 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
await ref.read(accountProvider.notifier).renameAccount(uuid, name);
if (!mounted) return;
_closeModal();
unawaited(_checkZnsEasterEgg(uuid, name));
}

Future<void> _checkZnsEasterEgg(String uuid, String name) async {
final owned = await ref.read(znsResolverProvider).isOwnedByAccount(name, uuid);
if (!mounted || !owned) return;
final account = ref.read(accountProvider).value?.accounts
.where((a) => a.uuid == uuid)
.firstOrNull;
if (account == null) return;
final currentId = account.profilePictureId;
if (currentId.startsWith('zns-')) return;
await ref.read(accountProvider.notifier).updateProfilePicture(uuid, 'zns-$currentId');
}

Future<void> _updateProfilePicture(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import '../../../providers/account_provider.dart';
import '../../../providers/privacy_mode_provider.dart';
import '../../../providers/rpc_endpoint_provider.dart';
import '../../../providers/sync_provider.dart';
import '../../../providers/zns_provider.dart';
import '../../../rust/api/sync.dart' as rust_sync;
import '../../send/widgets/transaction_receipt_view.dart';

Expand Down Expand Up @@ -54,6 +55,8 @@ class _ActivityTransactionStatusScreenState
String? _error;
String? _activeAccountUuid;
bool _messageExpanded = false;
String? _znsName;
int _znsSeq = 0;

@override
void initState() {
Expand All @@ -65,6 +68,7 @@ class _ActivityTransactionStatusScreenState
if (!mounted) return;
ref.read(appLayoutProvider.notifier).setMode(AppLayoutMode.large);
unawaited(_loadTransaction(showLoading: _transaction == null));
_triggerZnsLookup(widget.args.initialDetail?.primaryAddress);
});
}

Expand Down Expand Up @@ -140,6 +144,7 @@ class _ActivityTransactionStatusScreenState
}
_isLoading = false;
});
if (tx != null) _triggerZnsLookup(detail?.primaryAddress);
} catch (e, st) {
log('ActivityTransactionStatus: transaction load failed: $e\n$st');
if (!mounted) return;
Expand Down Expand Up @@ -215,6 +220,23 @@ class _ActivityTransactionStatusScreenState
(expected == 'received' && actual == 'receiving');
}

void _triggerZnsLookup(String? address) {
if (address == null || address.isEmpty) return;
final seq = ++_znsSeq;
setState(() => _znsName = null);
unawaited(_resolveZnsName(address, seq));
}

Future<void> _resolveZnsName(String address, int seq) async {
try {
final name = await ref.read(znsResolverProvider).reverseResolve(address);
if (!mounted || seq != _znsSeq) return;
setState(() => _znsName = name);
} catch (e) {
log('ActivityTransactionStatus: ZNS reverse lookup failed: $e');
}
}

Future<void> _copyTransactionHash() async {
await _copyText(widget.args.txidHex, 'Transaction Hash Copied');
}
Expand Down Expand Up @@ -352,6 +374,7 @@ class _ActivityTransactionStatusScreenState
BuildContext context, {
required String title,
required String address,
String? znsName,
bool useFailedReceiptLayout = false,
bool compactAddress = false,
}) {
Expand All @@ -360,13 +383,27 @@ class _ActivityTransactionStatusScreenState
return TransactionReceiptBlockData(
title: title,
onCopy: () => unawaited(_copyText(trimmedAddress, 'Address Copied')),
child: TransactionReceiptAddressText(
address: trimmedAddress,
highlightEdges: _shouldHighlightAddressEdges(trimmedAddress),
compact: compactAddress,
highlightColor: useFailedReceiptLayout
? colors.text.destructive
: colors.text.success,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (znsName != null) ...[
Text(
znsName,
style: AppTypography.labelMedium.copyWith(
color: colors.text.secondary,
),
),
const SizedBox(height: AppSpacing.xxs),
],
TransactionReceiptAddressText(
address: trimmedAddress,
highlightEdges: _shouldHighlightAddressEdges(trimmedAddress),
compact: compactAddress,
highlightColor: useFailedReceiptLayout
? colors.text.destructive
: colors.text.success,
),
],
),
);
}
Expand All @@ -390,6 +427,7 @@ class _ActivityTransactionStatusScreenState
context,
title: 'To',
address: primaryAddress,
znsName: _znsName,
useFailedReceiptLayout: useFailedReceiptLayout,
compactAddress: compactAddress,
);
Expand Down
5 changes: 4 additions & 1 deletion lib/src/features/send/screens/send_review_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class SendReviewArgs {
required this.feeZatoshi,
required this.needsSaplingParams,
this.memo,
this.resolvedName,
});

final BigInt proposalId;
Expand All @@ -48,8 +49,10 @@ class SendReviewArgs {
final BigInt feeZatoshi;
final bool needsSaplingParams;
final String? memo;
final String? resolvedName;

bool get isShielded => addressType == 'unified' || addressType == 'sapling';
String get recipientLabel => resolvedName != null ? 'To: $resolvedName' : 'To';
}

class KeystoneBroadcastArgs {
Expand Down Expand Up @@ -578,7 +581,7 @@ class _SendReviewReceiptCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_SendReviewFieldTitle(
label: 'To',
label: args.recipientLabel,
rightLabel: _SendReviewCopyAction(onTap: onCopyAddress),
),
const SizedBox(height: AppSpacing.xs),
Expand Down
Loading