Files
tatuchat/lib/utils/stream_extension.dart
Welton Moura 0037b0b9cf
Some checks failed
Main Deploy Workflow / deploy_web (push) Has been cancelled
Main Deploy Workflow / deploy_playstore_internal (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
Initial commit
2026-09-11 15:59:56 -03:00

54 lines
1.7 KiB
Dart

// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
//
// SPDX-License-Identifier: AGPL-3.0-or-later
import 'dart:async';
extension StreamExtension on Stream {
/// Returns a new Stream which outputs only `true` for every update of the original
/// stream, ratelimited by the Duration t
Stream<bool> rateLimit(Duration t) {
final controller = StreamController<bool>();
Timer? timer;
var gotMessage = false;
// as we call our inline-defined function recursively we need to make sure that the
// variable exists prior of creating the function. Silly dart.
Function? onMessage;
// callback to determine if we should send out an update
onMessage = () {
// do nothing if it is already closed
if (controller.isClosed) {
return;
}
if (timer == null) {
// if we don't have a timer yet, send out the update and start a timer
gotMessage = false;
controller.add(true);
timer = Timer(t, () {
// the timer has ended...delete it and, if we got a message, re-run the
// method to send out an update!
timer = null;
if (gotMessage) {
onMessage?.call();
}
});
} else {
// set that we got a message
gotMessage = true;
}
};
final subscription = listen(
(_) => onMessage?.call(),
onDone: controller.close,
onError: (e, s) => controller.addError(e, s),
);
// add proper cleanup to the subscription and the controller, to not memory leak
controller.onCancel = () {
subscription.cancel();
controller.close();
};
return controller.stream;
}
}