Line data Source code
1 : // ignore_for_file: public_member_api_docs 2 : part of 'consumer_widget.dart'; 3 : 4 : /// A function that can also listen to providers 5 : /// 6 : /// See also [Consumer] 7 : typedef ConsumerBuilder = Widget Function( 8 : BuildContext context, 9 : BuilderRef ref, 10 : Widget? child, 11 : ); 12 : 13 : /// A widget to listen the events in a SimpleNotifier or StateNotifier 14 : /// 15 : /// [builder] 16 : /// [child] use this to pass a pre-built widget 17 : class Consumer extends ConsumerWidget { 18 1 : const Consumer({ 19 : Key? key, 20 : required this.builder, 21 : this.child, 22 1 : }) : super(key: key); 23 : 24 : /// callback that exposes the [BuilderRef] to decide 25 : /// when the consumer must be rebuilded 26 : final ConsumerBuilder builder; 27 : 28 : /// a pre-cached widget that it won't be 29 : /// rebuilded every time that the builder is called 30 : final Widget? child; 31 : 32 1 : @override 33 : Widget build(BuildContext context, BuilderRef ref) { 34 2 : return builder( 35 : context, 36 : ref, 37 1 : child, 38 : ); 39 : } 40 : } 41 : 42 : extension _ConsumerWatchExtension on ConsumerStatefulElement { 43 2 : N _buildWatcher<N extends StateNotifier<S>, S>({ 44 : required BaseStateNotifierProvider<N, S> providerOrFilter, 45 : required void Function(N notifier) callback, 46 : required String? tag, 47 : required bool isListener, 48 : }) { 49 : // if the widget was rebuilded 50 2 : if (_isExternalBuild) { 51 2 : _clearDependencies(); 52 : } 53 2 : _isExternalBuild = false; 54 2 : final filter = providerOrFilter is FilteredProvider 55 : ? providerOrFilter as FilteredProvider<N, S> 56 : : null; 57 : 58 : late N notifier; 59 : 60 : if (filter != null) { 61 : // If [providerOrFilter] is a value gotten from .select or .when 62 : notifier = switch (filter) { 63 4 : SelectFilteredProvider filter => filter.notifier, 64 4 : WhenFilteredProvider filter => filter.notifier, 65 : } as N; 66 : } else { 67 : // if [providerOrFilter] is a a [StateProvider] 68 2 : notifier = (providerOrFilter as ListeneableProvider).read(tag: tag) as N; 69 : } 70 : 71 : late final Map<StateNotifier, Function> map; 72 : 73 : if (!isListener) { 74 1 : map = _builders; 75 : } else { 76 : map = filter == null 77 1 : ? _listeners 78 : : switch (filter) { 79 2 : SelectFilteredProvider _ => _selectListeners, 80 2 : WhenFilteredProvider _ => _whenListeners, 81 : }; 82 : } 83 : 84 2 : final insideDependencies = map.containsKey(notifier); 85 : 86 : // if there is not a listener for the current provider 87 : if (!insideDependencies) { 88 : // if the data passed to the watch function 89 : // was gotten using the .ids, .select or .when methods 90 : if (filter != null) { 91 2 : filter.reaction = callback; 92 2 : filter.createListener(); 93 4 : map[notifier] = filter.listener; 94 4 : notifier.addListener(filter.listener); 95 : } else { 96 : // ignore: prefer_function_declarations_over_variables 97 4 : final _ListenerCallback listener = (_) => callback(notifier); 98 2 : map[notifier] = listener; 99 2 : notifier.addListener(listener); 100 : } 101 : // add the listener to the current notifier 102 : } 103 : return notifier; // coverage:ignore-line 104 : } 105 : }