Tests / test (push) Canceled after 0s
Build Android (FCM) / build-android-fcm (push) Canceled after 0s
Build Android / build-android (push) Canceled after 0s
Build iOS / build-ios (push) Canceled after 0s
Build Linux / build-linux (push) Canceled after 0s
Build macOS / build-macos (push) Canceled after 0s
Build Windows / build-windows (push) Canceled after 0s
Native crypto / native-crypto (push) Canceled after 0s
Release (main) / android (oneme) (push) Canceled after 0s
Release (main) / android (qlyra) (push) Canceled after 0s
Release (main) / windows (push) Canceled after 0s
Release (main) / linux (push) Canceled after 0s
Release (main) / macos (push) Canceled after 0s
Release (main) / ios (push) Canceled after 0s
Release (main) / release (push) Canceled after 0s
67 lines
1.9 KiB
Dart
67 lines
1.9 KiB
Dart
import '../../models/shared_payload.dart';
|
|
|
|
/// Only one native share is presented at a time. A record is acknowledged
|
|
/// after its screen closes, and released after its uploads stop using files.
|
|
class ShareInbox {
|
|
ShareInbox({
|
|
required this.consume,
|
|
required this.acknowledge,
|
|
required this.release,
|
|
required this.onShare,
|
|
});
|
|
final Future<Object?> Function() consume;
|
|
final Future<void> Function(String) acknowledge;
|
|
final Future<void> Function(String) release;
|
|
final void Function(SharedPayload) onShare;
|
|
String? _activeId;
|
|
bool _completed = false;
|
|
bool _acknowledged = false;
|
|
Future<void> Function()? _waitForRelease;
|
|
bool _requested = false;
|
|
Future<void>? _operation;
|
|
|
|
Future<void> check() {
|
|
_requested = true;
|
|
return _operation ??= _drain().whenComplete(() => _operation = null);
|
|
}
|
|
|
|
Future<void> complete({Future<void> Function()? waitForRelease}) {
|
|
if (_activeId == null) return Future.value();
|
|
_completed = true;
|
|
_waitForRelease ??= waitForRelease;
|
|
return check();
|
|
}
|
|
|
|
Future<void> _drain() async {
|
|
while (_requested) {
|
|
_requested = false;
|
|
final activeId = _activeId;
|
|
if (activeId != null) {
|
|
if (!_completed) return;
|
|
if (!_acknowledged) {
|
|
await acknowledge(activeId);
|
|
_acknowledged = true;
|
|
}
|
|
await _waitForRelease?.call();
|
|
await release(activeId);
|
|
_activeId = null;
|
|
_completed = _acknowledged = false;
|
|
_waitForRelease = null;
|
|
}
|
|
final raw = await consume();
|
|
if (raw is! Map) continue;
|
|
final id = raw['id'];
|
|
if (id is! String || id.isEmpty) continue;
|
|
final payload = SharedPayload.fromMap(raw);
|
|
if (payload == null) {
|
|
await acknowledge(id);
|
|
await release(id);
|
|
_requested = true;
|
|
continue;
|
|
}
|
|
_activeId = id;
|
|
onShare(payload);
|
|
}
|
|
}
|
|
}
|