Skip to content

Commit

Permalink
Merge branch 'dev' into PE-6873-setup-integration-tests-flutter
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagocarvalhodev committed Nov 22, 2024
2 parents aae8d49 + 0c1d671 commit d14b694
Show file tree
Hide file tree
Showing 19 changed files with 283 additions and 35 deletions.
1 change: 1 addition & 0 deletions android/fastlane/metadata/android/en-US/changelogs/160.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Enable uploads even if contract state retrieval fails
1 change: 1 addition & 0 deletions android/fastlane/metadata/android/en-US/changelogs/164.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added support for uploading custom Arweave manifest files
13 changes: 11 additions & 2 deletions lib/blocs/drive_detail/drive_detail_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,21 @@ class DriveDetailCubit extends Cubit<DriveDetailState> {
_folderSubscription =
Rx.combineLatest3<Drive?, FolderWithContents, ProfileState, void>(
_driveRepository.watchDrive(driveId: driveId),
_driveDao.watchFolderContents(
_driveDao
.watchFolderContents(
driveId,
orderBy: contentOrderBy,
orderingMode: contentOrderingMode,
folderId: folderId,
),
)
.handleError((error, stack) {
logger.e('Error watching folder contents', error, stack);
if (error is DriveNotFoundException) {
emit(DriveDetailLoadNotFound());
}

return null;
}),
_profileCubit.stream.startWith(ProfileCheckingAvailability()),
(drive, folderContents, _) async {
if (isClosed) {
Expand Down
49 changes: 45 additions & 4 deletions lib/blocs/upload/upload_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:ardrive/core/activity_tracker.dart';
import 'package:ardrive/core/upload/domain/repository/upload_repository.dart';
import 'package:ardrive/core/upload/uploader.dart';
import 'package:ardrive/core/upload/view/blocs/upload_manifest_options_bloc.dart';
import 'package:ardrive/entities/constants.dart';
import 'package:ardrive/main.dart';
import 'package:ardrive/manifest/domain/manifest_repository.dart';
import 'package:ardrive/models/forms/cc.dart';
Expand All @@ -21,6 +22,7 @@ import 'package:ardrive/services/config/config_service.dart';
import 'package:ardrive/services/license/license.dart';
import 'package:ardrive/turbo/services/upload_service.dart';
import 'package:ardrive/utils/constants.dart';
import 'package:ardrive/utils/is_custom_manifest.dart';
import 'package:ardrive/utils/logger.dart';
import 'package:ardrive/utils/plausible_event_tracker/plausible_custom_event_properties.dart';
import 'package:ardrive/utils/plausible_event_tracker/plausible_event_tracker.dart';
Expand Down Expand Up @@ -111,6 +113,9 @@ class UploadCubit extends Cubit<UploadState> {

bool _isManifestsUploadCancelled = false;

/// if true, the file will change its content type to `application/x.arweave-manifest+json`
bool _uploadFileAsCustomManifest = false;

void updateManifestSelection(List<ManifestSelection> selections) {
_selectedManifestModels.clear();

Expand All @@ -126,6 +131,11 @@ class UploadCubit extends Cubit<UploadState> {
_manifestUploadMethod = method;
}

void setIsUploadingCustomManifest(bool value) {
_uploadFileAsCustomManifest = value;
emit((state as UploadReady).copyWith(uploadFileAsCustomManifest: value));
}

Future<void> prepareManifestUpload() async {
final manifestModels = _selectedManifestModels
.map((e) => UploadManifestModel(
Expand Down Expand Up @@ -441,6 +451,9 @@ class UploadCubit extends Cubit<UploadState> {
bool showArnsCheckbox = false;

if (_targetDrive.isPublic && _files.length == 1) {
final fileIsACustomManifest =
await isCustomManifest(_files.first.ioFile);

emit(
UploadReady(
params: (state as UploadReadyToPrepare).params,
Expand All @@ -461,6 +474,8 @@ class UploadCubit extends Cubit<UploadState> {
arnsRecords: _ants,
showReviewButtonText: false,
selectedManifestSelections: _selectedManifestModels,
shouldShowCustomManifestCheckbox: fileIsACustomManifest,
uploadFileAsCustomManifest: false,
),
);

Expand All @@ -481,9 +496,11 @@ class UploadCubit extends Cubit<UploadState> {
emit(readyState.copyWith(
loadingArNSNames: false, showArnsCheckbox: showArnsCheckbox));
} catch (e) {
final readyState = state as UploadReady;
emit(readyState.copyWith(
loadingArNSNamesError: true, loadingArNSNames: false));
if (state is UploadReady) {
final readyState = state as UploadReady;
emit(readyState.copyWith(
loadingArNSNamesError: true, loadingArNSNames: false));
}
}
} else {
emit(
Expand All @@ -505,6 +522,9 @@ class UploadCubit extends Cubit<UploadState> {
canShowSettings: showSettings,
showReviewButtonText: false,
selectedManifestSelections: _selectedManifestModels,
uploadFileAsCustomManifest: false,
// only applies for single file uploads
shouldShowCustomManifestCheckbox: false,
),
);
}
Expand Down Expand Up @@ -886,6 +906,10 @@ class UploadCubit extends Cubit<UploadState> {
if (state is UploadReady) {
emit((state as UploadReady).copyWith(arnsRecords: value));
}
}).catchError((e) {
logger.e(
'Error getting ant records for wallet. Proceeding with the upload...',
e);
});

_files
Expand Down Expand Up @@ -1036,7 +1060,9 @@ class UploadCubit extends Cubit<UploadState> {
await _arnsRepository
.getAntRecordsForWallet(_auth.currentUser.walletAddress);
} catch (e) {
logger.e('Error getting ARNS records', e);
logger.e(
'Error getting ant records for wallet. Proceeding with the upload...',
e);
}
}

Expand Down Expand Up @@ -1086,6 +1112,21 @@ class UploadCubit extends Cubit<UploadState> {
return;
}

if (_uploadFileAsCustomManifest) {
final fileWithCustomContentType = await IOFile.fromData(
await _files.first.ioFile.readAsBytes(),
name: _files.first.ioFile.name,
lastModifiedDate: _files.first.ioFile.lastModifiedDate,
contentType: ContentType.manifest,
);

_files.first = UploadFile(
ioFile: fileWithCustomContentType,
parentFolderId: _files.first.parentFolderId,
relativeTo: _files.first.relativeTo,
);
}

_uploadIsInProgress = true;

UploadPlan uploadPlan;
Expand Down
10 changes: 10 additions & 0 deletions lib/blocs/upload/upload_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ class UploadReady extends UploadState {

final bool isArConnect;
final bool showReviewButtonText;
final bool shouldShowCustomManifestCheckbox;
final bool uploadFileAsCustomManifest;

UploadReady({
required this.paymentInfo,
Expand All @@ -136,6 +138,8 @@ class UploadReady extends UploadState {
required this.arnsRecords,
required this.showReviewButtonText,
required this.selectedManifestSelections,
required this.shouldShowCustomManifestCheckbox,
required this.uploadFileAsCustomManifest,
});

// copyWith
Expand All @@ -160,6 +164,8 @@ class UploadReady extends UploadState {
List<ANTRecord>? arnsRecords,
bool? showReviewButtonText,
List<ManifestSelection>? selectedManifestSelections,
bool? shouldShowCustomManifestCheckbox,
bool? uploadFileAsCustomManifest,
}) {
return UploadReady(
loadingArNSNames: loadingArNSNames ?? this.loadingArNSNames,
Expand All @@ -184,6 +190,10 @@ class UploadReady extends UploadState {
showReviewButtonText: showReviewButtonText ?? this.showReviewButtonText,
selectedManifestSelections:
selectedManifestSelections ?? this.selectedManifestSelections,
shouldShowCustomManifestCheckbox: shouldShowCustomManifestCheckbox ??
this.shouldShowCustomManifestCheckbox,
uploadFileAsCustomManifest:
uploadFileAsCustomManifest ?? this.uploadFileAsCustomManifest,
);
}

Expand Down
18 changes: 16 additions & 2 deletions lib/components/upload_form.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// ignore_for_file: use_build_context_synchronously

import 'dart:async';
import 'dart:math';

Expand Down Expand Up @@ -1968,6 +1966,22 @@ class _UploadReadyWidget extends StatelessWidget {
),
),
],
if (state.shouldShowCustomManifestCheckbox) ...[
const SizedBox(height: 8),
ArDriveCheckBox(
title: 'Convert this file to an Arweave manifest.',
checked: state.uploadFileAsCustomManifest,
useNewIcons: true,
titleStyle: typography.paragraphNormal(
fontWeight: ArFontWeight.semiBold,
),
onChange: (value) {
context
.read<UploadCubit>()
.setIsUploadingCustomManifest(value);
},
),
],
],
);
},
Expand Down
6 changes: 5 additions & 1 deletion lib/core/upload/bundle_signer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ class ArweaveBundleTransactionSigner implements BundleTransactionSigner {

logger.i('Adding tip...');

await pstService.addCommunityTipToTx(bundleTx);
try {
await pstService.addCommunityTipToTx(bundleTx);
} catch (e) {
logger.e('Error adding community tip to transaction. Proceeding.', e);
}

logger.i('Tip added');

Expand Down
8 changes: 7 additions & 1 deletion lib/core/upload/cost_calculator.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:ardrive/services/arweave/arweave.dart';
import 'package:ardrive/turbo/turbo.dart';
import 'package:ardrive/utils/logger.dart';
import 'package:ardrive_utils/ardrive_utils.dart';
import 'package:arweave/utils.dart';
import 'package:equatable/equatable.dart';
import 'package:pst/pst.dart';
Expand Down Expand Up @@ -64,7 +65,12 @@ class UploadCostEstimateCalculatorForAR extends ArDriveUploadCostCalculator {
}) async {
final costInAR = await _arweaveService.getPrice(byteSize: totalSize);

final pstFee = await _pstService.getPSTFee(costInAR);
Winston pstFee = Winston(BigInt.zero);
try {
pstFee = await _pstService.getPSTFee(costInAR);
} catch (e) {
logger.e('Error adding community tip to transaction. Proceeding.', e);
}

final totalCostAR = costInAR + pstFee.value;

Expand Down
6 changes: 5 additions & 1 deletion lib/core/upload/transaction_signer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ class ArweaveTransactionSigner implements TransactionSigner {
..addApplicationTags(version: version)
..addUTags();

await pstService.addCommunityTipToTx(dataTx);
try {
await pstService.addCommunityTipToTx(dataTx);
} catch (e) {
logger.e('Error adding community tip to transaction. Proceeding.', e);
}

// Don't include the file's Content-Type tag if it is meant to be private.
if (!isPrivate) {
Expand Down
1 change: 1 addition & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ Future<void> initializeServices({bool deleteDatabase = false}) async {
gatewayUrl: Uri.parse(config.defaultArweaveGatewayForDataRequest.url),
),
ArDriveCrypto(),
_database.driveDao,
configService,
);
_turboUpload = config.useTurboUpload
Expand Down
3 changes: 2 additions & 1 deletion lib/pages/drive_detail/drive_detail_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ class _DriveDetailPageState extends State<DriveDetailPage> {
child: BlocListener<DrivesCubit, DrivesState>(
listener: (context, state) {
if (state is DrivesLoadSuccess) {
if (state.userDrives.isNotEmpty) {
if (state.userDrives.isNotEmpty ||
state.sharedDrives.isNotEmpty) {
final driveDetailState = context.read<DriveDetailCubit>().state;

if (driveDetailState is DriveDetailLoadSuccess &&
Expand Down
32 changes: 23 additions & 9 deletions lib/services/arweave/arweave_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:convert';

import 'package:ardrive/core/crypto/crypto.dart';
import 'package:ardrive/entities/entities.dart';
import 'package:ardrive/models/daos/drive_dao/drive_dao.dart';
import 'package:ardrive/services/arweave/arweave_service_exception.dart';
import 'package:ardrive/services/arweave/error/gateway_error.dart';
import 'package:ardrive/services/arweave/get_segmented_transaction_from_drive_strategy.dart';
Expand Down Expand Up @@ -42,12 +43,13 @@ const kMaxNumberOfTransactionsPerPage = 100;
class ArweaveService {
Arweave client;
final ArDriveCrypto _crypto;

final DriveDao _driveDao;
final ArtemisClient _gql;

ArweaveService(
this.client,
this._crypto,
this._driveDao,
ConfigService configService, {
ArtemisClient? artemisClient,
}) : _gql = artemisClient ??
Expand Down Expand Up @@ -262,6 +264,7 @@ class ArweaveService {

yield licenseComposedQuery.data!.transactions.edges
.map((e) => e.node)
.where((e) => e.tags.any((t) => t.name == 'License'))
.toList();
}
}
Expand Down Expand Up @@ -588,15 +591,26 @@ class ArweaveService {
continue;
}

final driveKey =
driveTx.getTag(EntityTag.drivePrivacy) == DrivePrivacyTag.private
? await _crypto.deriveDriveKey(
wallet,
driveTx.getTag(EntityTag.driveId)!,
password,
)
: null;
SecretKey? driveKey;

if (driveTx.getTag(EntityTag.drivePrivacy) == DrivePrivacyTag.private) {
driveKey = await _driveDao.getDriveKeyFromMemory(
driveTx.getTag(EntityTag.driveId)!,
);

if (driveKey == null) {
driveKey = await _crypto.deriveDriveKey(
wallet,
driveTx.getTag(EntityTag.driveId)!,
password,
);

_driveDao.putDriveKeyInMemory(
driveID: driveTx.getTag(EntityTag.driveId)!,
driveKey: driveKey,
);
}
}
try {
final drive = await DriveEntity.fromTransaction(
driveTx,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
query LicenseComposed($transactionIds: [ID!]) {
transactions(
ids: $transactionIds
tags: [{ name: "License", values: [""], op: NEQ }]
) {
edges {
node {
Expand Down
24 changes: 14 additions & 10 deletions lib/sync/domain/repositories/sync_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -245,16 +245,20 @@ class _SyncRepository implements SyncRepository {

logger.i('Syncing licenses...');

final licenseTxIds = <String>{};
final revisionsToSyncLicense = (await _driveDao
.allFileRevisionsWithLicenseReferencedButNotSynced()
.get())
..retainWhere((rev) => licenseTxIds.add(rev.licenseTxId!));
logger.d('Found ${revisionsToSyncLicense.length} licenses to sync');

await _updateLicenses(
revisionsToSyncLicense: revisionsToSyncLicense,
);
try {
final licenseTxIds = <String>{};
final revisionsToSyncLicense = (await _driveDao
.allFileRevisionsWithLicenseReferencedButNotSynced()
.get())
..retainWhere((rev) => licenseTxIds.add(rev.licenseTxId!));
logger.d('Found ${revisionsToSyncLicense.length} licenses to sync');

await _updateLicenses(
revisionsToSyncLicense: revisionsToSyncLicense,
);
} catch (e) {
logger.e('Error syncing licenses. Proceeding.', e);
}

logger.i('Licenses synced');

Expand Down
Loading

0 comments on commit d14b694

Please sign in to comment.