Skip to content

Commit

Permalink
Merge branch 'PE-4864-unable-to-download-files-in-safari' into PE-488…
Browse files Browse the repository at this point in the history
…5-use-new-downloader-on-share-file-page
  • Loading branch information
thiagocarvalhodev committed Oct 26, 2023
2 parents 0b5a1f5 + 7c71a45 commit d172c27
Show file tree
Hide file tree
Showing 14 changed files with 167 additions and 37 deletions.
1 change: 1 addition & 0 deletions lib/blocs/file_download/file_download_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:ardrive/core/arfs/entities/arfs_entities.dart';
import 'package:ardrive/core/arfs/repository/arfs_repository.dart';
import 'package:ardrive/core/crypto/crypto.dart';
import 'package:ardrive/download/ardrive_downloader.dart';
import 'package:ardrive/download/limits.dart';
import 'package:ardrive/entities/constants.dart';
import 'package:ardrive/models/models.dart';
import 'package:ardrive/services/services.dart';
Expand Down
1 change: 1 addition & 0 deletions lib/blocs/file_download/file_download_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class FileDownloadAborted extends FileDownloadState {}
enum FileDownloadFailureReason {
unknownError,
fileAboveLimit,
browserDoesNotSupportLargeDownloads,
networkConnectionError,
fileNotFound
}
19 changes: 12 additions & 7 deletions lib/blocs/file_download/personal_file_download_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ class ProfileFileDownloadCubit extends FileDownloadCubit {
_arfsRepository = arfsRepository,
super(FileDownloadStarting());

Future<void> verifyUploadLimitationsAndDownload(SecretKey? cipherKey) async {
if (await AppPlatform.isSafari()) {
if (_file.size > publicDownloadSafariSizeLimit) {
emit(const FileDownloadFailure(
FileDownloadFailureReason.browserDoesNotSupportLargeDownloads));
return;
}
}

download(cipherKey);
}

Future<void> download(SecretKey? cipherKey) async {
try {
final drive = await _arfsRepository.getDriveById(_file.driveId);
Expand Down Expand Up @@ -175,13 +187,6 @@ class ProfileFileDownloadCubit extends FileDownloadCubit {
return;
}

if (progress == 100) {
emit(FileDownloadFinishedWithSuccess(fileName: _file.name));
return;
}

logger.d('Download progress: $progress');

emit(
FileDownloadWithProgress(
fileName: _file.name,
Expand Down
5 changes: 4 additions & 1 deletion lib/blocs/upload/limits.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import 'package:ardrive_utils/ardrive_utils.dart';

final privateFileSizeLimit = const GiB(65).size;

final largeFileUploadSizeThreshold = const MiB(500).size;

final mobilePrivateFileSizeLimit = const GiB(10).size;

final publicFileSafeSizeLimit = const GiB(5).size;
final nonChromeBrowserUploadSafeLimitUsingTurbo = const MiB(500).size;

int bundleSizeLimit(bool isTurbo) =>
int getBundleSizeLimit(bool isTurbo) =>
isTurbo ? turboBundleSizeLimit : d2nBundleSizeLimit;

final d2nBundleSizeLimit = const GiB(65).size;
Expand Down
19 changes: 10 additions & 9 deletions lib/blocs/upload/models/upload_plan.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ class UploadPlan {
required this.maxDataItemCount,
});

static Future<UploadPlan> create(
{required Map<String, FileV2UploadHandle> fileV2UploadHandles,
required Map<String, FileDataItemUploadHandle> fileDataItemUploadHandles,
required Map<String, FolderDataItemUploadHandle>
folderDataItemUploadHandles,
required TurboUploadService turboUploadService,
required int maxDataItemCount,
required bool useTurbo}) async {
static Future<UploadPlan> create({
required Map<String, FileV2UploadHandle> fileV2UploadHandles,
required Map<String, FileDataItemUploadHandle> fileDataItemUploadHandles,
required Map<String, FolderDataItemUploadHandle>
folderDataItemUploadHandles,
required TurboUploadService turboUploadService,
required int maxDataItemCount,
required bool useTurbo,
}) async {
final uploadPlan = UploadPlan._create(
fileV2UploadHandles: fileV2UploadHandles,
maxDataItemCount: maxDataItemCount,
Expand Down Expand Up @@ -59,7 +60,7 @@ class UploadPlan {
}) async {
logger.i(
'Creating bundle handles from data item handles with a max number of files of $maxDataItemCount');
final int maxBundleSize = bundleSizeLimit(useTurbo);
final int maxBundleSize = getBundleSizeLimit(useTurbo);

final folderItems = await NextFitBundlePacker<UploadHandle>(
maxBundleSize: maxBundleSize,
Expand Down
57 changes: 46 additions & 11 deletions lib/blocs/upload/upload_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';

import 'package:ardrive/authentication/ardrive_auth.dart';
import 'package:ardrive/blocs/blocs.dart';
import 'package:ardrive/blocs/upload/limits.dart';
import 'package:ardrive/blocs/upload/models/models.dart';
import 'package:ardrive/blocs/upload/upload_file_checker.dart';
import 'package:ardrive/core/upload/cost_calculator.dart';
Expand Down Expand Up @@ -335,13 +336,12 @@ class UploadCubit extends Cubit<UploadState> {
),
);

_uploadMethod = uploadPreparation.uploadPaymentInfo.defaultPaymentMethod;

logger.d('Upload method: $_uploadMethod');

final paymentInfo = uploadPreparation.uploadPaymentInfo;
final uploadPlansPreparation = uploadPreparation.uploadPlansPreparation;

_uploadMethod = paymentInfo.defaultPaymentMethod;
logger.d('Upload method: $_uploadMethod');

if (await _profileCubit.checkIfWalletMismatch()) {
emit(UploadWalletMismatch());
return;
Expand Down Expand Up @@ -420,6 +420,7 @@ class UploadCubit extends Cubit<UploadState> {
}

bool hasEmittedError = false;
bool hasEmittedWarning = false;

Future<void> startUpload({
required UploadPlan uploadPlanForAr,
Expand Down Expand Up @@ -454,6 +455,23 @@ class UploadCubit extends Cubit<UploadState> {
'Wallet verified. Starting bundle preparation.... Number of bundles: ${uploadPlanForAr.bundleUploadHandles.length}. Number of V2 files: ${uploadPlanForAr.fileV2UploadHandles.length}');

if (configService.config.useNewUploader) {
if (_uploadMethod == UploadMethod.turbo) {
await _verifyIfUploadContainsLargeFilesUsingTurbo();
if (!hasEmittedWarning && kIsWeb && !await AppPlatform.isChrome()) {
emit(
UploadShowingWarning(
reason: UploadWarningReason.fileTooLargeOnNonChromeBrowser,
uploadPlanForAR: uploadPlanForAr,
uploadPlanForTurbo: uploadPlanForTurbo,
),
);
hasEmittedWarning = true;
return;
}
} else {
_containsLargeTurboUpload = false;
}

if (uploadFolders) {
await _uploadFolderUsingArDriveUploader();
return;
Expand Down Expand Up @@ -564,6 +582,7 @@ class UploadCubit extends Cubit<UploadState> {
progress: progress,
controller: uploadController,
uploadMethod: _uploadMethod!,
containsLargeTurboUpload: _containsLargeTurboUpload!,
),
);
},
Expand Down Expand Up @@ -703,11 +722,7 @@ class UploadCubit extends Cubit<UploadState> {
);
}

// TODO: implement this
void retryUploads(UploadController controller) {}

// TODO: implement this
void retryTask(UploadController controller, UploadTask task) {}
bool? _containsLargeTurboUpload;

Future<void> _uploadUsingArDriveUploader() async {
final ardriveUploader = ArDriveUploader(
Expand Down Expand Up @@ -761,7 +776,7 @@ class UploadCubit extends Cubit<UploadState> {
});

uploadController.onProgressChange(
(progress) {
(progress) async {
// TODO: Save as the file is finished the upload

emit(
Expand All @@ -771,6 +786,7 @@ class UploadCubit extends Cubit<UploadState> {
controller: uploadController,
equatableBust: UniqueKey(),
uploadMethod: _uploadMethod!,
containsLargeTurboUpload: _containsLargeTurboUpload!,
),
);
},
Expand Down Expand Up @@ -802,6 +818,19 @@ class UploadCubit extends Cubit<UploadState> {
);
}

Future<void> _verifyIfUploadContainsLargeFilesUsingTurbo() async {
if (_containsLargeTurboUpload == null) {
_containsLargeTurboUpload = false;

for (var file in files) {
if (await file.ioFile.length >= largeFileUploadSizeThreshold) {
_containsLargeTurboUpload = true;
break;
}
}
}
}

Future _saveEntityOnDB(UploadTask task) async {
// Single file only
// TODO: abstract to the database interface.
Expand Down Expand Up @@ -988,7 +1017,11 @@ class UploadCubit extends Cubit<UploadState> {
);

if (fileAboveWarningLimit) {
emit(UploadShowingWarning(reason: UploadWarningReason.fileTooLarge));
emit(UploadShowingWarning(
reason: UploadWarningReason.fileTooLarge,
uploadPlanForAR: null,
uploadPlanForTurbo: null,
));

return;
}
Expand Down Expand Up @@ -1031,6 +1064,7 @@ class UploadCubit extends Cubit<UploadState> {
totalProgress: state.totalProgress,
isCanceling: true,
uploadMethod: _uploadMethod!,
containsLargeTurboUpload: state.containsLargeTurboUpload,
),
);

Expand All @@ -1044,6 +1078,7 @@ class UploadCubit extends Cubit<UploadState> {
totalProgress: state.totalProgress,
isCanceling: false,
uploadMethod: _uploadMethod!,
containsLargeTurboUpload: state.containsLargeTurboUpload,
),
);

Expand Down
11 changes: 10 additions & 1 deletion lib/blocs/upload/upload_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ class UploadInProgressUsingNewUploader extends UploadState {
final bool isCanceling;
final Key? equatableBust;
final UploadMethod uploadMethod;
final bool containsLargeTurboUpload;

UploadInProgressUsingNewUploader({
required this.progress,
Expand All @@ -222,6 +223,7 @@ class UploadInProgressUsingNewUploader extends UploadState {
this.equatableBust,
this.isCanceling = false,
required this.uploadMethod,
required this.containsLargeTurboUpload,
});

@override
Expand All @@ -240,8 +242,14 @@ class UploadWalletMismatch extends UploadState {}

class UploadShowingWarning extends UploadState {
final UploadWarningReason reason;
final UploadPlan? uploadPlanForAR;
final UploadPlan? uploadPlanForTurbo;

UploadShowingWarning({required this.reason});
UploadShowingWarning({
required this.reason,
this.uploadPlanForAR,
this.uploadPlanForTurbo,
});

@override
List<Object> get props => [reason];
Expand All @@ -254,6 +262,7 @@ class CancelD2NUploadWarning extends UploadState {}
enum UploadWarningReason {
/// The user is attempting to upload a file that is too large.
fileTooLarge,
fileTooLargeOnNonChromeBrowser,
}

enum UploadErrors {
Expand Down
22 changes: 20 additions & 2 deletions lib/components/file_download_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Future<void> promptToDownloadProfileFile({
file: arfsFile,
driveDao: context.read<DriveDao>(),
arweave: arweave,
)..download(cipherKey);
)..verifyUploadLimitationsAndDownload(cipherKey);
return showArDriveDialog(
context,
barrierDismissible: false,
Expand Down Expand Up @@ -83,7 +83,7 @@ Future<void> promptToDownloadFileRevision({
file: arfsFile,
driveDao: context.read<DriveDao>(),
arweave: arweave,
)..download(cipherKey);
)..verifyUploadLimitationsAndDownload(cipherKey);

return showArDriveDialog(
context,
Expand Down Expand Up @@ -153,6 +153,9 @@ class FileDownloadDialog extends StatelessWidget {
} else if (state is FileDownloadFailure) {
if (state.reason == FileDownloadFailureReason.unknownError) {
return _fileDownloadFailedDialog(context);
} else if (state.reason ==
FileDownloadFailureReason.browserDoesNotSupportLargeDownloads) {
return _fileDownloadFailedDueToAboveBrowserLimit(context);
}

return _fileDownloadFailedDueToFileAbovePrivateLimit(context);
Expand Down Expand Up @@ -192,6 +195,21 @@ class FileDownloadDialog extends StatelessWidget {
);
}

ArDriveStandardModal _fileDownloadFailedDueToAboveBrowserLimit(
BuildContext context) {
return _modalWrapper(
title: appLocalizationsOf(context).warningEmphasized,
description:
appLocalizationsOf(context).fileFailedToDownloadFileAbovePublicLimit,
actions: [
ModalAction(
action: () => Navigator.pop(context),
title: appLocalizationsOf(context).ok,
),
],
);
}

ArDriveStandardModal _warningToWaitDownloadFinishes(BuildContext context) {
return _modalWrapper(
title: appLocalizationsOf(context).warningEmphasized,
Expand Down
Loading

0 comments on commit d172c27

Please sign in to comment.