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

v1.4.0 #16

Closed
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f571796
Implement save stream IO (no-firefox)
elliotsayes Feb 16, 2023
6f43f7b
Add support for aborting on failed verification
elliotsayes Feb 16, 2023
dedfa0e
Release writer lock
elliotsayes Feb 16, 2023
72957fc
Remove close on writer
elliotsayes Feb 16, 2023
52a213c
Implement download using StreamSaver.js
elliotsayes Feb 23, 2023
19e6be3
Fix improper closing
elliotsayes Feb 23, 2023
6b49c83
Wait for readyFuture again
elliotsayes Feb 23, 2023
5ce5a5a
Switch to DartIOFileSaver for saveStream:
elliotsayes Feb 23, 2023
870cdae
Add code to find empty files
elliotsayes Feb 24, 2023
d844bfc
ArDriveDownloader uses same download filename...
elliotsayes Feb 24, 2023
cf46631
Better handling of no content-type
elliotsayes Feb 24, 2023
b3a491b
Fix basename bug (oops)
elliotsayes Feb 24, 2023
41e1ad7
Fix extension ..
elliotsayes Feb 24, 2023
9a8d652
Fix wrong arg order (oops)
elliotsayes Feb 24, 2023
21f5a45
Change saveFileStream API to completer
elliotsayes Feb 27, 2023
03482c6
Better abort logic
elliotsayes Feb 27, 2023
3698836
Implement save status stream
elliotsayes Feb 28, 2023
2ae9de2
Rename flag to saveResult
elliotsayes Feb 28, 2023
8a82370
Remove commented code
elliotsayes Mar 22, 2023
d2f71fa
More descriptive exceptions
elliotsayes Mar 22, 2023
2366575
Move empty file finder to path_utils
elliotsayes Mar 22, 2023
9de8d78
Make "test" var name more explicit
elliotsayes Mar 22, 2023
229147e
Clearer name: emptyFile => nonexistentFile
elliotsayes Apr 5, 2023
2631a98
variable name `extension` => `fileExtension`
elliotsayes Apr 5, 2023
dde4cd0
More clear exit condition on while loop
elliotsayes Apr 5, 2023
37294df
Add TODO to catch near-infinite loops
elliotsayes Apr 5, 2023
46f2c11
Work around weird mime behavior?
elliotsayes Apr 5, 2023
5df5b19
Fixed comparison to use lowercase
elliotsayes Apr 6, 2023
abd6e86
feat(save files on app dir)
thiagocarvalhodev Aug 23, 2023
295b3ae
Update fvm_config.json
thiagocarvalhodev Aug 23, 2023
a07b81c
Update pubspec.yaml
thiagocarvalhodev Aug 23, 2023
49ef040
Update pubspec.yaml
thiagocarvalhodev Aug 23, 2023
136d27a
Update web_io.dart
thiagocarvalhodev Aug 23, 2023
3a60e46
feat(IOFolder)
thiagocarvalhodev Sep 26, 2023
080f74c
feat(uploader)
thiagocarvalhodev Oct 3, 2023
3ca5ffd
Update io_folder_test.dart
thiagocarvalhodev Oct 3, 2023
9f0c97d
feat(iofolder)
thiagocarvalhodev Oct 4, 2023
2359255
upgrade deps
thiagocarvalhodev Oct 4, 2023
daef5c6
remove folder tree generation of files
thiagocarvalhodev Oct 4, 2023
7bd6e71
fix lint rules
thiagocarvalhodev Oct 4, 2023
599780a
Merge pull request #10 from elliotsayes/write-file-stream
thiagocarvalhodev Oct 6, 2023
3ce83fd
Merge branch 'dev' into PE-3699-uploads-large-files-for-public-drives
thiagocarvalhodev Oct 6, 2023
5998dfd
add stream saver
thiagocarvalhodev Oct 6, 2023
b42e3dc
Update web_io.dart
thiagocarvalhodev Oct 25, 2023
8c6ac43
Update web_io.dart
thiagocarvalhodev Oct 25, 2023
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
2 changes: 1 addition & 1 deletion .fvm/fvm_config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"flutterSdkVersion": "3.10.0",
"flutterSdkVersion": "3.10.2",
"flavors": {}
}
1 change: 1 addition & 0 deletions lib/ardrive_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export 'src/io_entity.dart';
export 'src/io_exception.dart';
export 'src/io_file.dart';
export 'src/io_folder.dart';
export 'src/mobile/mobile_io.dart';
export 'src/utils/mime_type_utils.dart';
export 'src/utils/path_utils.dart';
export 'src/utils/permissions.dart';
10 changes: 5 additions & 5 deletions lib/src/ardrive_downloader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,24 @@ class ArDriveDownloader {
}

Stream<int> _handleProgress(String taskId) {
ReceivePort _port = ReceivePort();
ReceivePort port = ReceivePort();
StreamController<int> controller = StreamController<int>();

/// Remove previous port and track only one download
IsolateNameServer.removePortNameMapping('downloader_send_port');

IsolateNameServer.registerPortWithName(
_port.sendPort, 'downloader_send_port');
port.sendPort, 'downloader_send_port');

_port.listen((dynamic data) {
DownloadTaskStatus status = DownloadTaskStatus(data[1]);
port.listen((dynamic data) {
DownloadTaskStatus status = DownloadTaskStatus.values[data[1]];
int progress = data[2];

/// only track the progress of current task id
if (status == DownloadTaskStatus.enqueued) {
controller.sink.add(0);
} else if (status == DownloadTaskStatus.running) {
debugPrint('Download progress: ' + progress.toString());
debugPrint('Download progress: $progress');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we get rid of this log?

controller.sink.add(progress);
} else if (status == DownloadTaskStatus.complete) {
controller.sink.add(100);
Expand Down
10 changes: 5 additions & 5 deletions lib/src/cache_storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ class IOCacheStorage {

debugPrint('saving file on local storage');

final _file = File('${cacheDir.path}/${entity.name}');
final file = File('${cacheDir.path}/${entity.name}');

final readStream = File(entity.path).openRead();

final writeStream = await _file.open(mode: FileMode.write);
final writeStream = await file.open(mode: FileMode.write);

await for (List<int> chunk in readStream) {
await writeStream.writeFrom(chunk);
}

await writeStream.close();

return _file.path;
return file.path;
}

Future<IOFile> getFileFromStorage(String fileName) async {
Expand All @@ -32,9 +32,9 @@ class IOCacheStorage {

final cacheDir = await _getCacheDir();

final _file = File('${cacheDir.path}/$fileName');
final file = File('${cacheDir.path}/$fileName');

return adapter.fromFile(_file);
return adapter.fromFile(file);
}

Future<void> freeLocalStorage() async {
Expand Down
3 changes: 2 additions & 1 deletion lib/src/file_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ abstract class FolderProvider {
}

/// Provides multiple `IOFiles` or an `IOFolder`
abstract class MultiFileProvider extends FileProvider with FolderProvider {
abstract class MultiFileProvider extends FileProvider
implements FolderProvider {
Future<List<IOFile>> pickMultipleFiles({
List<String>? allowedExtensions,
required FileSource fileSource,
Expand Down
6 changes: 3 additions & 3 deletions lib/src/io_folder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ class _FileSystemFolder extends IOFolder {
/// `_mountFolderChildren` mounts recursiverly the folder hierarchy. It gets only
/// the current level entities loading only `IOFile` and `IOFolder`
Future<List<IOEntity>> _mountFolderStructure() async {
List<IOEntity> _children = [];
List<IOEntity> children = [];

for (var fs in _folderContent) {
_children.add(await _addFolderNode(fs));
children.add(await _addFolderNode(fs));
}

return _children;
return children;
}

Future<IOEntity> _addFolderNode(FileSystemEntity fsEntity) async {
Expand Down
39 changes: 34 additions & 5 deletions lib/src/mobile/mobile_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ class MobileIO implements ArDriveIO {
}

@override
Future<void> saveFile(IOFile file) async {
Future<void> saveFile(IOFile file, [bool saveOnAppDirectory = false]) async {
try {
await _fileSaver.save(file);
await _fileSaver.save(file, saveOnAppDirectory: saveOnAppDirectory);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can get rid of this try..catch because it's rethrowing and nothing else.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment for the method below.

} catch (e) {
rethrow;
}
Expand All @@ -78,12 +78,24 @@ class MobileIO implements ArDriveIO {
/// This implementation uses the `file_saver` package.
///
/// Throws an `FileSystemPermissionDeniedException` when user deny access to storage
///
/// `saveOnAppDirectory` is not supported on this implementation
class MobileSelectableFolderFileSaver implements FileSaver {
final DartIOFileSaver _dartIOFileSaver;

MobileSelectableFolderFileSaver({DartIOFileSaver? dartIOFileSaver})
: _dartIOFileSaver = dartIOFileSaver ?? DartIOFileSaver();

@override
Future<void> save(IOFile file) async {
Future<void> save(IOFile file, {bool saveOnAppDirectory = false}) async {
await requestPermissions();
await verifyPermissions();

if (saveOnAppDirectory) {
await _dartIOFileSaver.save(file, saveOnAppDirectory: saveOnAppDirectory);
return;
}

await file_saver.FileSaver.instance.saveAs(
name: file.name,
bytes: await file.readAsBytes(),
Expand All @@ -98,7 +110,7 @@ class MobileSelectableFolderFileSaver implements FileSaver {
/// It will save on `getDefaultMobileDownloadDir()`
class DartIOFileSaver implements FileSaver {
@override
Future<void> save(IOFile file) async {
Future<void> save(IOFile file, {bool saveOnAppDirectory = false}) async {
await requestPermissions();
await verifyPermissions();

Expand All @@ -111,13 +123,30 @@ class DartIOFileSaver implements FileSaver {
fileName += '.$fileExtension';
}

if (saveOnAppDirectory) {
await _saveOnAppDir(file, fileName);
return;
}

await _saveOnDownloadsDir(file, fileName);
}

Future<void> _saveOnDownloadsDir(IOFile file, String fileName) async {
/// platform_specific_path/Downloads/
final defaultDownloadDir = await getDefaultMobileDownloadDir();

final newFile = File(defaultDownloadDir + fileName);

await newFile.writeAsBytes(await file.readAsBytes());
}

Future<void> _saveOnAppDir(IOFile file, String fileName) async {
final appDir = await getDefaultAppDir();

final newFile = File(appDir + fileName);

await newFile.writeAsBytes(await file.readAsBytes());
}
}

/// Defines the API for saving `IOFile` on Storage
Expand All @@ -130,5 +159,5 @@ abstract class FileSaver {
'The ${Platform.operatingSystem} platform is not supported');
}

Future<void> save(IOFile file);
Future<void> save(IOFile file, {bool saveOnAppDirectory = false});
}
8 changes: 7 additions & 1 deletion lib/src/utils/path_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ Future<String> getDefaultMobileDownloadDir() async {
}
}

Future<String> getDefaultAppDir() {
return path_provider
.getApplicationDocumentsDirectory()
.then((value) => '${value.path}/');
}

/// Returns the file extension from the file `name`, when having, in other case the extension
/// will be provided by the `contentType`.
///
Expand Down Expand Up @@ -84,7 +90,7 @@ String getFileExtension({

Future<String> _getDefaultIOSDir() async {
final iosDirectory = await path_provider.getApplicationDocumentsDirectory();
final iosDownloadsDirectory = Directory(iosDirectory.path + '/Downloads/');
final iosDownloadsDirectory = Directory('${iosDirectory.path}/Downloads/');

if (!iosDownloadsDirectory.existsSync()) {
iosDownloadsDirectory.createSync();
Expand Down
13 changes: 7 additions & 6 deletions lib/src/web/web_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class WebIO implements ArDriveIO {

@override
Future<void> saveFile(IOFile file) async {
final savePath = await file_selector.getSavePath();
final savePath = await file_selector.getSaveLocation();

if (savePath == null) {
throw EntityPathException();
}
Expand All @@ -59,7 +60,7 @@ class WebIO implements ArDriveIO {
lastModified: file.lastModifiedDate,
mimeType: file.contentType,
name: file.name,
).saveTo(savePath);
).saveTo(savePath.path);
}
}

Expand Down Expand Up @@ -144,11 +145,11 @@ class WebFileSystemProvider implements MultiFileProvider {
class FolderPicker {
Future<void> pickFolderFiles(
Function(Stream<List<IOFile>> stream) getFiles) async {
StreamController<List<IOFile>> _folderController =
StreamController<List<IOFile>> folderController =
StreamController<List<IOFile>>();

/// Set the stream to get the files
getFiles(_folderController.stream);
getFiles(folderController.stream);

final folderInput = FileUploadInputElement();

Expand All @@ -166,10 +167,10 @@ class FolderPicker {

/// To avoid the `IOFileAdapter` imports dart:html, this file will be mounted
/// here.
_folderController.add(files.map((e) => _mountFile(e)).toList());
folderController.add(files.map((e) => _mountFile(e)).toList());

/// Closes to finish the stream with all files
_folderController.close();
folderController.close();
folderInput.removeAttribute('webkitdirectory');
folderInput.remove();
});
Expand Down
21 changes: 11 additions & 10 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: ardrive_io
description: A new Flutter package project.
version: 1.3.0
version: 1.4.0
homepage:
publish_to: none

environment:
sdk: ">=2.15.1 <3.0.0"
flutter: 3.10.0
sdk: '>=3.0.2 <4.0.0'
flutter: 3.13.6

dependencies:
flutter:
Expand All @@ -16,24 +16,25 @@ dependencies:
url: https://github.com/ar-io/flutter_file_picker
ref: master
path_provider: ^2.0.11
permission_handler: ^10.0.0
permission_handler: ^11.0.0
mime: ^1.0.2
equatable: ^2.0.3
file_selector: ^0.9.0
flutter_downloader: ^1.8.3+2
image_picker: ^0.8.5+3
file_selector: ^1.0.1
flutter_downloader: ^1.11.3
image_picker: ^1.0.4
security_scoped_resource: ^0.0.1
file_saver:
git:
url: https://github.com/thiagocarvalhodev/file_saver
ref: fix-extension
device_info_plus: ^8.0.0
device_info_plus: ^9.0.3
async: ^2.9.0
path: ^1.8.3
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^1.0.0
mocktail: ^0.3.0
flutter_lints: ^2.0.3
mocktail: ^1.0.1

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down