Browse Source

Merge pull request #584 from nextcloud/refactor/files-task-progress

Refactor/files task progress
pull/601/head
Kate 1 year ago committed by GitHub
parent
commit
afb8895d5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      packages/neon/neon_files/lib/blocs/files.dart
  2. 4
      packages/neon/neon_files/lib/models/file_details.dart
  3. 1
      packages/neon/neon_files/lib/neon_files.dart
  4. 55
      packages/neon/neon_files/lib/utils/task.dart
  5. 4
      packages/nextcloud/lib/src/webdav/client.dart
  6. 2
      packages/nextcloud/test/webdav_test.dart

16
packages/neon/neon_files/lib/blocs/files.dart

@ -160,16 +160,12 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
void uploadFile(final List<String> path, final String localPath) { void uploadFile(final List<String> path, final String localPath) {
wrapAction( wrapAction(
() async { () async {
final file = File(localPath);
// ignore: avoid_slow_async_io
final stat = await file.stat();
final task = FilesUploadTask( final task = FilesUploadTask(
path: path, path: path,
size: stat.size, file: File(localPath),
lastModified: stat.modified,
); );
tasks.add(tasks.value..add(task)); 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)); tasks.add(tasks.value..remove(task));
}, },
disableTimeout: true, disableTimeout: true,
@ -180,17 +176,13 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
final List<String> path, final List<String> path,
final File file, final File file,
) async { ) async {
final sink = file.openWrite();
try {
final task = FilesDownloadTask( final task = FilesDownloadTask(
path: path, path: path,
file: file,
); );
tasks.add(tasks.value..add(task)); tasks.add(tasks.value..add(task));
await _downloadQueue.add(() => task.execute(account.client, sink)); await _downloadQueue.add(() => task.execute(account.client));
tasks.add(tasks.value..remove(task)); tasks.add(tasks.value..remove(task));
} finally {
await sink.close();
}
} }
FilesBrowserBloc getNewFilesBrowserBloc() => FilesBrowserBloc(_requestManager, options, account); FilesBrowserBloc getNewFilesBrowserBloc() => FilesBrowserBloc(_requestManager, options, account);

4
packages/neon/neon_files/lib/models/file_details.dart

@ -29,8 +29,8 @@ class FileDetails {
FileDetails.fromUploadTask({ FileDetails.fromUploadTask({
required FilesUploadTask this.task, required FilesUploadTask this.task,
}) : path = task.path, }) : path = task.path,
size = task.size, size = task.stat.size,
lastModified = task.lastModified, lastModified = task.stat.modified,
isDirectory = false, isDirectory = false,
etag = null, etag = null,
mimeType = null, mimeType = null,

1
packages/neon/neon_files/lib/neon_files.dart

@ -2,7 +2,6 @@ library neon_files;
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:file_icons/file_icons.dart'; import 'package:file_icons/file_icons.dart';

55
packages/neon/neon_files/lib/utils/task.dart

@ -3,10 +3,13 @@ part of '../neon_files.dart';
sealed class FilesTask { sealed class FilesTask {
FilesTask({ FilesTask({
required this.path, required this.path,
required this.file,
}); });
final List<String> path; final List<String> path;
final File file;
@protected @protected
final streamController = StreamController<double>(); final streamController = StreamController<double>();
@ -17,50 +20,38 @@ sealed class FilesTask {
class FilesDownloadTask extends FilesTask { class FilesDownloadTask extends FilesTask {
FilesDownloadTask({ FilesDownloadTask({
required super.path, required super.path,
required super.file,
}); });
Future execute(final NextcloudClient client, final IOSink sink) async { Future execute(final NextcloudClient client) async {
final completer = Completer(); await client.webdav.getFile(
path.join('/'),
final response = await client.webdav.getStream(path.join('/')); file,
var downloaded = 0; onProgress: (final progress) {
streamController.add(progress);
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;
} }
} }
class FilesUploadTask extends FilesTask { class FilesUploadTask extends FilesTask {
FilesUploadTask({ FilesUploadTask({
required super.path, required super.path,
required this.size, required super.file,
required this.lastModified,
}); });
final int size; FileStat? _stat;
final DateTime lastModified; FileStat get stat => _stat ??= file.statSync();
Future execute(final NextcloudClient client, final Stream<List<int>> stream) async {
var uploaded = 0;
await client.webdav.putStream(
stream.map((final chunk) {
uploaded += chunk.length;
streamController.add(uploaded / size);
return Uint8List.fromList(chunk); Future execute(final NextcloudClient client) async {
}), await client.webdav.putFile(
file,
stat,
path.join('/'), path.join('/'),
lastModified: lastModified, lastModified: stat.modified,
onProgress: (final progress) {
streamController.add(progress);
},
); );
} }
} }

4
packages/nextcloud/lib/src/webdav/client.dart

@ -187,7 +187,7 @@ class WebDavClient {
return putStream( return putStream(
file.openRead().map((final chunk) { file.openRead().map((final chunk) {
uploaded += chunk.length; uploaded += chunk.length;
onProgress?.call(uploaded / fileStat.size * 100); onProgress?.call(uploaded / fileStat.size);
return Uint8List.fromList(chunk); return Uint8List.fromList(chunk);
}), }),
path, path,
@ -221,7 +221,7 @@ class WebDavClient {
response.listen((final chunk) async { response.listen((final chunk) async {
sink.add(chunk); sink.add(chunk);
downloaded += chunk.length; downloaded += chunk.length;
onProgress?.call(downloaded / response.contentLength * 100); onProgress?.call(downloaded / response.contentLength);
if (downloaded >= response.contentLength) { if (downloaded >= response.contentLength) {
completer.complete(); completer.complete();
} }

2
packages/nextcloud/test/webdav_test.dart

@ -301,7 +301,7 @@ void main() {
destination, destination,
onProgress: progressValues.add, onProgress: progressValues.add,
); );
expect(progressValues, containsAll([100.0, 100.0])); expect(progressValues, containsAll([1.0, 1.0]));
expect(destination.readAsBytesSync(), source.readAsBytesSync()); expect(destination.readAsBytesSync(), source.readAsBytesSync());
destinationDir.deleteSync(recursive: true); destinationDir.deleteSync(recursive: true);

Loading…
Cancel
Save