Line data Source code
1 : import 'package:flutter/foundation.dart'; 2 : import 'package:flutter/material.dart'; 3 : import 'package:rxdart/rxdart.dart'; 4 : import 'package:stream_chat/stream_chat.dart'; 5 : import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; 6 : 7 : /// Widget dedicated to the management of a users list with pagination. 8 : /// 9 : /// [UsersBloc] can be access at anytime by using the static [of] method 10 : /// using Flutter's [BuildContext]. 11 : /// 12 : /// API docs: https://getstream.io/chat/docs/flutter-dart/init_and_users/ 13 : class UsersBloc extends StatefulWidget { 14 : /// Instantiate a new [UsersBloc]. The parameter [child] must be supplied and 15 : /// not null. 16 2 : const UsersBloc({ 17 : required this.child, 18 : Key? key, 19 2 : }) : super(key: key); 20 : 21 : /// The widget child 22 : final Widget child; 23 : 24 2 : @override 25 2 : UsersBlocState createState() => UsersBlocState(); 26 : 27 : /// Use this method to get the current [UsersBlocState] instance 28 1 : static UsersBlocState of(BuildContext context) { 29 : UsersBlocState? state; 30 : 31 1 : state = context.findAncestorStateOfType<UsersBlocState>(); 32 : 33 : assert( 34 1 : state != null, 35 : 'You must have a UsersBloc widget as ancestor', 36 : ); 37 : 38 : return state!; 39 : } 40 : } 41 : 42 : /// The current state of the [UsersBloc] 43 : class UsersBlocState extends State<UsersBloc> 44 : with AutomaticKeepAliveClientMixin { 45 : /// The current users list 46 6 : List<User>? get users => _usersController.valueOrNull; 47 : 48 : /// The current users list as a stream 49 6 : Stream<List<User>> get usersStream => _usersController.stream; 50 : 51 : final _usersController = BehaviorSubject<List<User>>(); 52 : 53 : final _queryUsersLoadingController = BehaviorSubject.seeded(false); 54 : 55 : /// The stream notifying the state of queryUsers call 56 3 : Stream<bool> get queryUsersLoading => _queryUsersLoadingController.stream; 57 : 58 : late StreamChatCoreState _streamChatCore; 59 : 60 : /// The Query Users method allows you to search for users and see if they are 61 : /// online/offline. 62 : /// [API Reference](https://getstream.io/chat/docs/flutter-dart/query_users/?language=dart) 63 2 : Future<void> queryUsers({ 64 : Filter? filter, 65 : List<SortOption>? sort, 66 : Map<String, dynamic>? options, 67 : PaginationParams? pagination, 68 : }) async { 69 4 : final client = _streamChatCore.client; 70 : 71 6 : if (_queryUsersLoadingController.value == true) return; 72 : 73 4 : if (_usersController.hasValue) { 74 4 : _queryUsersLoadingController.add(true); 75 : } 76 : 77 : try { 78 4 : final clear = pagination == null || pagination.offset == 0; 79 : 80 6 : final oldUsers = List<User>.from(users ?? []); 81 : 82 4 : final usersResponse = await client.queryUsers( 83 : filter: filter, 84 : sort: sort, 85 : options: options, 86 : pagination: pagination, 87 : ); 88 : 89 : if (clear) { 90 6 : _usersController.add(usersResponse.users); 91 : } else { 92 4 : final temp = oldUsers + usersResponse.users; 93 4 : _usersController.add(temp); 94 : } 95 8 : if (_usersController.hasValue && _queryUsersLoadingController.value) { 96 4 : _queryUsersLoadingController.add(false); 97 : } 98 : } catch (e, stk) { 99 4 : if (_usersController.hasValue) { 100 2 : _queryUsersLoadingController.addError(e, stk); 101 : } else { 102 4 : _usersController.addError(e, stk); 103 : } 104 : } 105 : } 106 : 107 2 : @override 108 : void didChangeDependencies() { 109 6 : _streamChatCore = StreamChatCore.of(context); 110 2 : super.didChangeDependencies(); 111 : } 112 : 113 2 : @override 114 : Widget build(BuildContext context) { 115 2 : super.build(context); 116 4 : return widget.child; 117 : } 118 : 119 2 : @override 120 : void dispose() { 121 4 : _usersController.close(); 122 4 : _queryUsersLoadingController.close(); 123 2 : super.dispose(); 124 : } 125 : 126 2 : @override 127 : bool get wantKeepAlive => true; 128 : }