Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PE-6789: Release ArDrive v2.54.4 #1864

Merged
merged 9 commits into from
Sep 19, 2024
2 changes: 2 additions & 0 deletions android/fastlane/metadata/android/en-US/changelogs/154.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Improves handling of errors on the assign name flow
- Displays the file(s) size(s) instead of data items or bundle sizes at the upload page
80 changes: 41 additions & 39 deletions lib/arns/presentation/assign_name_bloc/assign_name_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,22 @@ class AssignNameBloc extends Bloc<AssignNameEvent, AssignNameState> {
_arnsRepository = arnsRepository,
super(AssignNameInitial()) {
on<LoadNames>((event, emit) async {
emit(LoadingNames());
try {
emit(LoadingNames());

final walletAddress = await _auth.getWalletAddress();
final walletAddress = await _auth.getWalletAddress();

final names = await _arnsRepository.getAntRecordsForWallet(walletAddress!);
final names =
await _arnsRepository.getAntRecordsForWallet(walletAddress!);

if (names.isEmpty) {
emit(AssignNameEmptyState());
} else {
emit(NamesLoaded(names: names));
if (names.isEmpty) {
emit(AssignNameEmptyState());
} else {
emit(NamesLoaded(names: names));
}
} catch (e) {
logger.e('Failed to load ArNS names', e);
emit(LoadingNamesFailed());
}
});

Expand Down Expand Up @@ -94,41 +100,37 @@ class AssignNameBloc extends Bloc<AssignNameEvent, AssignNameState> {
on<ConfirmSelectionAndUpload>((event, emit) async {
try {
emit(ConfirmingSelection());
try {
if (fileDataTableItem == null) {
throw StateError('File data table item is null');
}

ARNSUndername undername;

if (_selectedUndername == null) {
undername = ARNSUndername(
name: '@',
record: ARNSRecord(
transactionId: fileDataTableItem.dataTxId, ttlSeconds: 3600),
domain: _selectedANTRecord!.domain,
);
} else {
undername = ARNSUndername(
name: _selectedUndername!.name,
record: ARNSRecord(
transactionId: fileDataTableItem.dataTxId,
ttlSeconds: 3600,
),
domain: _selectedANTRecord!.domain,
);
}

await _arnsRepository.setUndernamesToFile(
undername: undername,
fileId: fileDataTableItem.fileId,
driveId: fileDataTableItem.driveId,
processId: _selectedANTRecord!.processId,
if (fileDataTableItem == null) {
throw StateError('File data table item is null');
}

ARNSUndername undername;

if (_selectedUndername == null) {
undername = ARNSUndername(
name: '@',
record: ARNSRecord(
transactionId: fileDataTableItem.dataTxId, ttlSeconds: 3600),
domain: _selectedANTRecord!.domain,
);
} else {
undername = ARNSUndername(
name: _selectedUndername!.name,
record: ARNSRecord(
transactionId: fileDataTableItem.dataTxId,
ttlSeconds: 3600,
),
domain: _selectedANTRecord!.domain,
);
} catch (e) {
logger.e('Failed to set ARNS', e);
}

await _arnsRepository.setUndernamesToFile(
undername: undername,
fileId: fileDataTableItem.fileId,
driveId: fileDataTableItem.driveId,
processId: _selectedANTRecord!.processId,
);

final (address, arAddress) = getAddressesFromArns(
domain: _selectedANTRecord!.domain,
undername: _selectedUndername?.name,
Expand Down
2 changes: 2 additions & 0 deletions lib/arns/presentation/assign_name_bloc/assign_name_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,6 @@ final class LoadingUndernames extends AssignNameState {}

class SelectionFailed extends AssignNameState {}

final class LoadingNamesFailed extends AssignNameState {}

final class EmptySelection extends AssignNameState {}
58 changes: 58 additions & 0 deletions lib/arns/presentation/assign_name_modal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,28 @@ class _AssignArNSNameModalState extends State<_AssignArNSNameModal> {
return const Center(child: CircularProgressIndicator());
} else if (state is AssignNameEmptyState) {
return const _AssignNameEmptyState();
} else if (state is SelectionFailed) {
final colorTokens =
ArDriveTheme.of(context).themeData.colorTokens;
return Center(
child: Text(
'Error assigning ArNS name. Please try again later',
style: typography.paragraphLarge(
color: colorTokens.textMid,
),
),
);
} else if (state is LoadingNamesFailed) {
final colorTokens =
ArDriveTheme.of(context).themeData.colorTokens;
return Center(
child: Text(
'Error fetching ArNS names. Please try again later',
style: typography.paragraphLarge(
color: colorTokens.textMid,
),
),
);
}

return const SizedBox();
Expand Down Expand Up @@ -299,6 +321,42 @@ class _AssignArNSNameModalState extends State<_AssignArNSNameModal> {
return [];
}

if (state is LoadingNamesFailed) {
return [
ModalAction(
action: () {
Navigator.of(context).pop();
},
title: 'Cancel',
),
ModalAction(
action: () {
context
.read<AssignNameBloc>()
.add(const LoadNames(updateARNSRecords: true));
},
title: 'Try again',
),
];
}

if (state is SelectionFailed) {
return [
ModalAction(
action: () {
Navigator.of(context).pop();
},
title: 'Cancel',
),
ModalAction(
action: () {
context.read<AssignNameBloc>().add(ConfirmSelectionAndUpload());
},
title: 'Try again',
),
];
}

late final bool isButtonEnabled;

if (state is NamesLoaded && state.selectedName != null) {
Expand Down
12 changes: 12 additions & 0 deletions lib/blocs/upload/upload_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class UploadCubit extends Cubit<UploadState> {
showArnsCheckbox: showArnsCheckbox,
showArnsNameSelection: false,
loadingArNSNames: true,
totalSize: await _getTotalSize(),
),
);

Expand Down Expand Up @@ -156,6 +157,7 @@ class UploadCubit extends Cubit<UploadState> {
isArConnect: (state as UploadReadyToPrepare).isArConnect,
showArnsCheckbox: showArnsCheckbox,
showArnsNameSelection: false,
totalSize: await _getTotalSize(),
),
);
}
Expand All @@ -176,6 +178,16 @@ class UploadCubit extends Cubit<UploadState> {
}
}

Future<int> _getTotalSize() async {
int size = 0;

for (final file in files) {
size += await file.ioFile.length;
}

return size;
}

void initialScreenNext({required LicenseCategory licenseCategory}) {
if (state is UploadReady) {
final readyState = state as UploadReady;
Expand Down
5 changes: 4 additions & 1 deletion lib/blocs/upload/upload_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class UploadReady extends UploadState {
final bool showArnsNameSelection;
final bool loadingArNSNames;
final bool loadingArNSNamesError;
final int totalSize;

final bool isArConnect;

Expand All @@ -112,6 +113,7 @@ class UploadReady extends UploadState {
required this.showArnsNameSelection,
this.loadingArNSNames = false,
this.loadingArNSNamesError = false,
required this.totalSize,
});

// copyWith
Expand All @@ -129,6 +131,7 @@ class UploadReady extends UploadState {
bool? showArnsNameSelection,
bool? loadingArNSNames,
bool? loadingArNSNamesError,
int? totalSize,
}) {
return UploadReady(
loadingArNSNames: loadingArNSNames ?? this.loadingArNSNames,
Expand All @@ -144,6 +147,7 @@ class UploadReady extends UploadState {
showArnsNameSelection ?? this.showArnsNameSelection,
loadingArNSNamesError:
loadingArNSNamesError ?? this.loadingArNSNamesError,
totalSize: totalSize ?? this.totalSize,
);
}

Expand All @@ -155,7 +159,6 @@ class UploadReady extends UploadState {
loadingArNSNamesError,
loadingArNSNames,
showArnsCheckbox,

];

@override
Expand Down
2 changes: 1 addition & 1 deletion lib/components/upload_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1568,7 +1568,7 @@ class _StatsScreenState extends State<StatsScreen> {
),
TextSpan(
text: filesize(
widget.readyState.paymentInfo.totalSize,
widget.readyState.totalSize,
),
style: typography.paragraphNormal(
fontWeight: ArFontWeight.bold,
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Secure, permanent storage

publish_to: 'none'

version: 2.54.3
version: 2.54.4

environment:
sdk: '>=3.2.0 <4.0.0'
Expand Down
94 changes: 94 additions & 0 deletions test/arns/presentation/assign_name_bloc/assign_name_bloc_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,29 @@ void main() {
walletAddress,
)).called(1);
});

test('emits [LoadingNames, LoadingNamesFailed] when LoadNames is added',
() async {
// Arrange
const walletAddress = 'test_wallet_address';

when(() => mockAuth.getWalletAddress())
.thenAnswer((_) async => walletAddress);
when(() => mockArnsRepository.getAntRecordsForWallet(walletAddress,
update: true)).thenThrow(StateError('Test error'));

// Act
assignNameBloc.add(const LoadNames());

// Assert
await expectLater(
assignNameBloc.stream,
emitsInOrder([
isA<LoadingNames>(),
isA<LoadingNamesFailed>(),
]),
);
});
});

group('SelectName', () {
Expand Down Expand Up @@ -353,5 +376,76 @@ void main() {
},
);
});

blocTest<AssignNameBloc, AssignNameState>(
'emits [ConfirmingSelection, SelectionFailed] when ConfirmSelection is added',
build: () {
when(() => mockFileDataTableItem.dataTxId)
.thenReturn('test_data_tx_id');
when(() => mockFileDataTableItem.fileId).thenReturn('test_file_id');
when(() => mockFileDataTableItem.driveId).thenReturn('test_drive_id');
final antRecords = [
ANTRecord(domain: 'test1.ar', processId: 'process1'),
ANTRecord(domain: 'test2.ar', processId: 'process2'),
];

const walletAddress = 'test_wallet_address';

when(() => mockAuth.getWalletAddress())
.thenAnswer((_) async => walletAddress);
when(() => mockArnsRepository.getAntRecordsForWallet(
walletAddress,
)).thenAnswer((_) async => antRecords);

/// FAILED CALL
when(() => mockArnsRepository.setUndernamesToFile(
undername: any(named: 'undername'),
fileId: any(named: 'fileId'),
driveId: any(named: 'driveId'),
processId: any(named: 'processId'),
)).thenThrow(StateError('Test error'));
when(() => mockArnsRepository.getARNSUndernames(any())).thenAnswer(
(_) async => [
ARNSUndername(
name: 'undername',
domain: 'domain',
record: ARNSRecord(transactionId: 'test_tx_id', ttlSeconds: 3600),
)
],
);
return assignNameBloc;
},
act: (bloc) {
bloc.add(const LoadNames());
bloc.add(
SelectName(ANTRecord(domain: 'domain', processId: 'process_id')));
bloc.add(const LoadUndernames());
bloc.add(SelectUndername(
undername: ARNSUndername(
name: 'undername',
domain: 'domain',
record: ARNSRecord(transactionId: 'test_tx_id', ttlSeconds: 3600),
),
));
bloc.add(ConfirmSelectionAndUpload());
},
expect: () => [
isA<LoadingNames>(),
isA<NamesLoaded>(),
isA<LoadingUndernames>(),
isA<UndernamesLoaded>(),
isA<UndernamesLoaded>(),
isA<ConfirmingSelection>(),
isA<SelectionFailed>(),
],
verify: (_) {
verify(() => mockArnsRepository.setUndernamesToFile(
undername: any(named: 'undername'),
fileId: any(named: 'fileId'),
driveId: any(named: 'driveId'),
processId: any(named: 'processId'),
)).called(1);
},
);
});
}
Loading