Files
IKAR/lib/core/share/shared_file_uploads.dart

44 lines
1.2 KiB
Dart

import 'dart:async';
/// Keeps incoming share files alive until every recipient finishes uploading.
class SharedFileUploads {
static final instance = SharedFileUploads();
final Map<String, int> _users = {};
final Map<String, Completer<void>> _idle = {};
void Function() retain(Iterable<String> paths) {
final files = paths.toSet();
for (final path in files) {
_users[path] = (_users[path] ?? 0) + 1;
_idle.putIfAbsent(path, Completer<void>.new);
}
var released = false;
return () {
if (released) return;
released = true;
for (final path in files) {
final remaining = _users[path]! - 1;
if (remaining == 0) {
_users.remove(path);
_idle.remove(path)!.complete();
} else {
_users[path] = remaining;
}
}
};
}
Future<T> use<T>(Iterable<String> paths, Future<T> Function() upload) {
final release = retain(paths);
return Future<T>.sync(upload).whenComplete(release);
}
Future<void> waitUntilIdle(Iterable<String> paths) async {
await Future.wait([
for (final path in paths.toSet())
if (_idle[path] case final pending?) pending.future,
]);
}
}