diff --git a/lib/arns/domain/arns_repository.dart b/lib/arns/domain/arns_repository.dart index 8b171a146..8afaccde2 100644 --- a/lib/arns/domain/arns_repository.dart +++ b/lib/arns/domain/arns_repository.dart @@ -32,6 +32,8 @@ abstract class ARNSRepository { Future saveAllFilesWithAssignedNames(); Future> getActiveARNSRecordsForFile(String fileId); Future waitForARNSRecordsToUpdate(); + Future getUndernameByDomainAndName( + String domain, String name); Future getPrimaryName(String address, {bool update = false}); @@ -375,6 +377,26 @@ class _ARNSRepository implements ARNSRepository { await _getARNSUndernamesCompleter!.future; } + @override + Future getUndernameByDomainAndName( + String domain, String name) async { + if (_cachedUndernames.isEmpty) { + await waitForARNSRecordsToUpdate(); + } + + if (_cachedUndernames[domain] == null) { + throw Exception('Domain not cached'); + } + + final undername = _cachedUndernames[domain]![name]; + + if (undername == null) { + throw Exception('Undername not cached'); + } + + return undername; + } + @override Future getPrimaryName(String address, {bool update = false}) async { diff --git a/lib/core/upload/view/blocs/upload_manifest_options_bloc.dart b/lib/core/upload/view/blocs/upload_manifest_options_bloc.dart index 784a3eca9..5de44f443 100644 --- a/lib/core/upload/view/blocs/upload_manifest_options_bloc.dart +++ b/lib/core/upload/view/blocs/upload_manifest_options_bloc.dart @@ -1,7 +1,10 @@ import 'package:ardrive/arns/domain/arns_repository.dart'; +import 'package:ardrive/arns/utils/parse_assigned_names_from_string.dart'; import 'package:ardrive/authentication/ardrive_auth.dart'; import 'package:ardrive/models/models.dart'; +import 'package:ardrive/utils/logger.dart'; import 'package:ario_sdk/ario_sdk.dart'; +import 'package:collection/collection.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -57,6 +60,37 @@ class UploadManifestOptionsBloc on((event, emit) async { final walletAddress = await arDriveAuth.getWalletAddress(); _ants = await arnsRepository.getAntRecordsForWallet(walletAddress!); + + for (var file in manifestFiles) { + if (file.manifest.assignedNames != null && + file.manifest.assignedNames!.isNotEmpty) { + final assignedNames = + parseAssignedNamesFromString(file.manifest.assignedNames!); + final assignedName = assignedNames!.first; + + final (domain, undername) = splitArNSRecordName(assignedName); + + /// For now, we only support adding one name + final antRecord = _ants!.firstWhereOrNull((e) => e.domain == domain); + + if (antRecord != null) { + try { + final existingUndername = await arnsRepository + .getUndernameByDomainAndName(domain, undername ?? '@'); + + add(SelectManifest(manifest: file.manifest)); + add(LinkManifestToUndername( + manifest: file.manifest, + antRecord: antRecord, + undername: existingUndername, + )); + } catch (e) { + logger.e('Error getting undername.', e); + } + } + } + } + emit(_createReadyState()); }); diff --git a/lib/core/upload/view/manifest_options/manifest_options.dart b/lib/core/upload/view/manifest_options/manifest_options.dart index 755957b05..b651b8250 100644 --- a/lib/core/upload/view/manifest_options/manifest_options.dart +++ b/lib/core/upload/view/manifest_options/manifest_options.dart @@ -1,5 +1,6 @@ import 'package:ardrive/components/components.dart'; import 'package:ardrive/core/upload/view/blocs/upload_manifest_options_bloc.dart'; +import 'package:ardrive/utils/logger.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:ario_sdk/ario_sdk.dart'; import 'package:flutter/material.dart'; @@ -31,6 +32,8 @@ class ManifestOptions extends StatelessWidget { final file = manifestFiles.elementAt(index).manifest; final isSelected = selectedManifestIds.contains(file.id); + logger.d('Is selected: $isSelected'); + return _ManifestOptionTile( manifestSelection: manifestFiles.elementAt(index), isSelected: isSelected, @@ -91,21 +94,20 @@ class __ManifestOptionTileState extends State<_ManifestOptionTile> { widget.manifestSelection.undername != null); final hasSelectedAnt = widget.manifestSelection.antRecord != null; - return AnimatedContainer( - duration: const Duration(milliseconds: 300), - decoration: BoxDecoration( - color: colorTokens.containerL2, - borderRadius: BorderRadius.circular(5), - ), - curve: Curves.easeInOut, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - height: isExpanded - ? 168 - : showingName - ? 70 - : 50, - child: GestureDetector( - onTap: () {}, + return SingleChildScrollView( + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), + decoration: BoxDecoration( + color: colorTokens.containerL2, + borderRadius: BorderRadius.circular(5), + ), + curve: Curves.easeInOut, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + height: isExpanded + ? 168 + : showingName + ? 70 + : 50, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceAround, @@ -113,50 +115,47 @@ class __ManifestOptionTileState extends State<_ManifestOptionTile> { Row( mainAxisSize: MainAxisSize.max, children: [ + ArDriveCheckBox( + key: ValueKey(widget.isSelected), + checked: widget.isSelected, + onChange: (value) { + if (value) { + context + .read() + .add(SelectManifest(manifest: file)); + } else { + context + .read() + .add(DeselectManifest(manifest: file)); + } + }, + ), + const SizedBox(width: 16), Expanded( child: Row( + mainAxisSize: MainAxisSize.max, children: [ - Flexible( - flex: 2, - child: Row( - children: [ - ArDriveIcons.manifest( - size: 16, - color: file.isHidden ? hiddenColor : null), - const SizedBox(width: 8), - Text( - file.name, - style: typography.paragraphNormal( - color: file.isHidden ? hiddenColor : null, - ), - ), - if (file.isHidden) ...[ - const SizedBox(width: 8), - Text('(hidden)', - style: typography.paragraphNormal( - color: hiddenColor, - )) - ] - ], - ), - ), - Flexible( - flex: 1, - child: ArDriveCheckBox( - checked: widget.isSelected, - onChange: (value) { - if (value) { - context - .read() - .add(SelectManifest(manifest: file)); - } else { - context - .read() - .add(DeselectManifest(manifest: file)); - } - }, + ArDriveIcons.manifest( + size: 16, + color: file.isHidden ? hiddenColor : null), + const SizedBox(width: 8), + Expanded( + child: Text( + file.name, + style: typography.paragraphNormal( + color: file.isHidden ? hiddenColor : null, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), ), + if (file.isHidden) ...[ + const SizedBox(width: 8), + Text('(hidden)', + style: typography.paragraphNormal( + color: hiddenColor, + )) + ] ], ), ), @@ -168,8 +167,8 @@ class __ManifestOptionTileState extends State<_ManifestOptionTile> { text: !state.arnsNamesLoaded ? 'Loading Names...' : hasSelectedAnt - ? 'Change ArNS' - : 'Add ArNS', + ? 'Change ArNS Name' + : 'Add ArNS Name', typography: typography, isDisabled: isExpanded || !widget.isSelected || @@ -177,7 +176,7 @@ class __ManifestOptionTileState extends State<_ManifestOptionTile> { (state.arnsNamesLoaded && state.ants!.isEmpty), fontStyle: typography.paragraphSmall(), variant: ButtonVariant.primary, - maxWidth: state.arnsNamesLoaded ? 100 : 120, + maxWidth: state.arnsNamesLoaded ? 140 : 160, maxHeight: 30, onPressed: () { context @@ -186,7 +185,6 @@ class __ManifestOptionTileState extends State<_ManifestOptionTile> { }, ), ) - // TODO: Add back when we have the right UI for it ], ), if (showingName) ...[ @@ -197,7 +195,7 @@ class __ManifestOptionTileState extends State<_ManifestOptionTile> { size: 16, color: colorTokens.textHigh, ), - const SizedBox(width: 8), + const SizedBox(width: 18), Flexible( child: Text( getLiteralArNSName(widget.manifestSelection.antRecord!, @@ -216,8 +214,11 @@ class __ManifestOptionTileState extends State<_ManifestOptionTile> { const SizedBox(height: 8), Expanded( flex: 1, - child: AntSelector( - manifestSelection: widget.manifestSelection, + child: Padding( + padding: const EdgeInsets.only(left: 34), + child: AntSelector( + manifestSelection: widget.manifestSelection, + ), ), ), ], diff --git a/packages/ario_sdk/lib/src/utils/get_literal_arns_record_name.dart b/packages/ario_sdk/lib/src/utils/get_literal_arns_record_name.dart index bcd4c8dd6..bba245d23 100644 --- a/packages/ario_sdk/lib/src/utils/get_literal_arns_record_name.dart +++ b/packages/ario_sdk/lib/src/utils/get_literal_arns_record_name.dart @@ -7,3 +7,13 @@ String getLiteralARNSRecordName(ARNSUndername undername) { return '${undername.name}_${undername.domain}'; } +/// Splits an ARNS record name into its literal name and domain. +/// If the name is not in the format [name]_[domain], it returns [name] and null. +(String, String?) splitArNSRecordName(String name) { + if (name.contains('_')) { + return (name.split('_').first, name.split('_').last); + } + + return (name, null); +} +//