diff --git a/packages/neon/neon_files/lib/blocs/files.dart b/packages/neon/neon_files/lib/blocs/files.dart index d9bee11f..b6da7f78 100644 --- a/packages/neon/neon_files/lib/blocs/files.dart +++ b/packages/neon/neon_files/lib/blocs/files.dart @@ -160,16 +160,12 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta void uploadFile(final List path, final String localPath) { wrapAction( () async { - final file = File(localPath); - // ignore: avoid_slow_async_io - final stat = await file.stat(); final task = FilesUploadTask( path: path, - size: stat.size, - lastModified: stat.modified, + file: File(localPath), ); tasks.add(tasks.value..add(task)); - await _uploadQueue.add(() => task.execute(account.client, file.openRead())); + await _uploadQueue.add(() => task.execute(account.client)); tasks.add(tasks.value..remove(task)); }, disableTimeout: true, @@ -180,17 +176,13 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta final List path, final File file, ) async { - final sink = file.openWrite(); - try { - final task = FilesDownloadTask( - path: path, - ); - tasks.add(tasks.value..add(task)); - await _downloadQueue.add(() => task.execute(account.client, sink)); - tasks.add(tasks.value..remove(task)); - } finally { - await sink.close(); - } + final task = FilesDownloadTask( + path: path, + file: file, + ); + tasks.add(tasks.value..add(task)); + await _downloadQueue.add(() => task.execute(account.client)); + tasks.add(tasks.value..remove(task)); } FilesBrowserBloc getNewFilesBrowserBloc() => FilesBrowserBloc(_requestManager, options, account); diff --git a/packages/neon/neon_files/lib/models/file_details.dart b/packages/neon/neon_files/lib/models/file_details.dart index c999be2c..c0d61b28 100644 --- a/packages/neon/neon_files/lib/models/file_details.dart +++ b/packages/neon/neon_files/lib/models/file_details.dart @@ -29,8 +29,8 @@ class FileDetails { FileDetails.fromUploadTask({ required FilesUploadTask this.task, }) : path = task.path, - size = task.size, - lastModified = task.lastModified, + size = task.stat.size, + lastModified = task.stat.modified, isDirectory = false, etag = null, mimeType = null, diff --git a/packages/neon/neon_files/lib/neon_files.dart b/packages/neon/neon_files/lib/neon_files.dart index 2f01f134..0c0abcd4 100644 --- a/packages/neon/neon_files/lib/neon_files.dart +++ b/packages/neon/neon_files/lib/neon_files.dart @@ -2,7 +2,6 @@ library neon_files; import 'dart:async'; import 'dart:io'; -import 'dart:typed_data'; import 'package:collection/collection.dart'; import 'package:file_icons/file_icons.dart'; diff --git a/packages/neon/neon_files/lib/utils/task.dart b/packages/neon/neon_files/lib/utils/task.dart index 09dcc1dc..3e4c6b47 100644 --- a/packages/neon/neon_files/lib/utils/task.dart +++ b/packages/neon/neon_files/lib/utils/task.dart @@ -3,10 +3,13 @@ part of '../neon_files.dart'; sealed class FilesTask { FilesTask({ required this.path, + required this.file, }); final List path; + final File file; + @protected final streamController = StreamController(); @@ -17,50 +20,38 @@ sealed class FilesTask { class FilesDownloadTask extends FilesTask { FilesDownloadTask({ required super.path, + required super.file, }); - Future execute(final NextcloudClient client, final IOSink sink) async { - final completer = Completer(); - - final response = await client.webdav.getStream(path.join('/')); - var downloaded = 0; - - response.listen((final chunk) async { - sink.add(chunk); - - downloaded += chunk.length; - streamController.add(downloaded / response.contentLength); - - if (downloaded >= response.contentLength) { - completer.complete(); - } - }); - - return completer.future; + Future execute(final NextcloudClient client) async { + await client.webdav.getFile( + path.join('/'), + file, + onProgress: (final progress) { + streamController.add(progress); + }, + ); } } class FilesUploadTask extends FilesTask { FilesUploadTask({ required super.path, - required this.size, - required this.lastModified, + required super.file, }); - final int size; - final DateTime lastModified; - - Future execute(final NextcloudClient client, final Stream> stream) async { - var uploaded = 0; - await client.webdav.putStream( - stream.map((final chunk) { - uploaded += chunk.length; - streamController.add(uploaded / size); + FileStat? _stat; + FileStat get stat => _stat ??= file.statSync(); - return Uint8List.fromList(chunk); - }), + Future execute(final NextcloudClient client) async { + await client.webdav.putFile( + file, + stat, path.join('/'), - lastModified: lastModified, + lastModified: stat.modified, + onProgress: (final progress) { + streamController.add(progress); + }, ); } } diff --git a/packages/nextcloud/lib/src/webdav/client.dart b/packages/nextcloud/lib/src/webdav/client.dart index fa05a74a..88a10b53 100644 --- a/packages/nextcloud/lib/src/webdav/client.dart +++ b/packages/nextcloud/lib/src/webdav/client.dart @@ -187,7 +187,7 @@ class WebDavClient { return putStream( file.openRead().map((final chunk) { uploaded += chunk.length; - onProgress?.call(uploaded / fileStat.size * 100); + onProgress?.call(uploaded / fileStat.size); return Uint8List.fromList(chunk); }), path, @@ -221,7 +221,7 @@ class WebDavClient { response.listen((final chunk) async { sink.add(chunk); downloaded += chunk.length; - onProgress?.call(downloaded / response.contentLength * 100); + onProgress?.call(downloaded / response.contentLength); if (downloaded >= response.contentLength) { completer.complete(); } diff --git a/packages/nextcloud/test/webdav_test.dart b/packages/nextcloud/test/webdav_test.dart index ef7391ec..bf6ac30b 100644 --- a/packages/nextcloud/test/webdav_test.dart +++ b/packages/nextcloud/test/webdav_test.dart @@ -301,7 +301,7 @@ void main() { destination, onProgress: progressValues.add, ); - expect(progressValues, containsAll([100.0, 100.0])); + expect(progressValues, containsAll([1.0, 1.0])); expect(destination.readAsBytesSync(), source.readAsBytesSync()); destinationDir.deleteSync(recursive: true);