extension AsValueListenable on Stream { /// Converts a [Stream] to a [ValueListenable] /// /// The internal [StreamSubscription] is cancelled when /// all listeners added to [ValueListenable] are removed. /// Keep this in mind as this could cause issues with /// single-subscription streams. ValueListenable asValueListenable(T initialValue) { return _StreamValueListenable(this, initialValue); } } class _StreamValueListenable extends ValueNotifier { _StreamValueListenable(this.stream, T initialValue) : super(initialValue); final Stream stream; StreamSubscription subscription; @override void addListener(VoidCallback listener) { subscription ??= stream.listen((event) { value = event; }); super.addListener(listener); } @override void removeListener(VoidCallback listener) { super.removeListener(listener); if (!hasListeners && subscription != null) { subscription.cancel(); subscription = null; } } }