mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-01-20 04:21:39 -05:00
59 lines
1.8 KiB
Dart
59 lines
1.8 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:async_tools/async_tools.dart';
|
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
|
|
|
// Mixin that automatically keeps two blocs/cubits in sync with each other
|
|
// Useful for having a BlocMapCubit 'follow' the state of another input cubit.
|
|
// As the state of the input cubit changes, the BlocMapCubit can add/remove
|
|
// mapped Cubits that automatically process the input state reactively.
|
|
//
|
|
// S = Input state type
|
|
// K = Key derived from elements of input state
|
|
// V = Value derived from elements of input state
|
|
abstract mixin class StateFollower<S extends Object, K, V> {
|
|
void follow({
|
|
required S initialInputState,
|
|
required Stream<S> stream,
|
|
}) {
|
|
//
|
|
_lastInputStateMap = getStateMap(initialInputState);
|
|
_subscription = stream.listen(_updateFollow);
|
|
}
|
|
|
|
Future<void> close() async {
|
|
await _subscription.cancel();
|
|
}
|
|
|
|
IMap<K, V> getStateMap(S state);
|
|
Future<void> removeFromState(K key);
|
|
Future<void> updateState(K key, V value);
|
|
|
|
void _updateFollow(S newInputState) {
|
|
_singleStateProcessor.updateState(getStateMap(newInputState),
|
|
closure: (newStateMap) async {
|
|
for (final k in _lastInputStateMap.keys) {
|
|
if (!newStateMap.containsKey(k)) {
|
|
// deleted
|
|
await removeFromState(k);
|
|
}
|
|
}
|
|
for (final newEntry in newStateMap.entries) {
|
|
final v = _lastInputStateMap.get(newEntry.key);
|
|
if (v == null || v != newEntry.value) {
|
|
// added or changed
|
|
await updateState(newEntry.key, newEntry.value);
|
|
}
|
|
}
|
|
|
|
// Keep this state map for the next time
|
|
_lastInputStateMap = newStateMap;
|
|
});
|
|
}
|
|
|
|
late IMap<K, V> _lastInputStateMap;
|
|
final SingleStateProcessor<IMap<K, V>> _singleStateProcessor =
|
|
SingleStateProcessor();
|
|
late final StreamSubscription<S> _subscription;
|
|
}
|