remove channels bloc

This commit is contained in:
Salvatore Giordano
2020-04-07 10:14:00 +02:00
parent fa2be8397d
commit dc90e38743
4 changed files with 130 additions and 123 deletions
+28 -19
View File
@@ -50,39 +50,48 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
home: Container( home: Container(
child: StreamChat( child: ChannelListPage(client),
client: client,
child: ChannelListPage(),
),
), ),
); );
} }
} }
class ChannelListPage extends StatelessWidget { class ChannelListPage extends StatelessWidget {
final Client client;
ChannelListPage(this.client);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: PageView( body: PageView(
children: <Widget>[ children: <Widget>[
ChannelListView( StreamChat(
filter: { client: client,
'members': { child: Builder(
'\$in': [StreamChat.of(context).user.id], builder: (context) => ChannelListView(
} filter: {
}, 'members': {
sort: [SortOption('last_message_at')], '\$in': [StreamChat.of(context).user.id],
pagination: PaginationParams( }
limit: 20, },
sort: [SortOption('last_message_at')],
pagination: PaginationParams(
limit: 20,
),
channelWidget: ChannelPage(),
),
), ),
channelWidget: ChannelPage(),
), ),
ChannelListView( StreamChat(
sort: [SortOption('last_message_at')], client: client,
pagination: PaginationParams( child: ChannelListView(
limit: 20, sort: [SortOption('last_message_at')],
pagination: PaginationParams(
limit: 20,
),
channelWidget: ChannelPage(),
), ),
channelWidget: ChannelPage(),
), ),
], ],
), ),
+13 -15
View File
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_flutter/src/channels_bloc.dart';
import '../stream_chat_flutter.dart'; import '../stream_chat_flutter.dart';
import 'channel_preview.dart'; import 'channel_preview.dart';
@@ -100,16 +99,16 @@ class ChannelListView extends StatefulWidget {
} }
class _ChannelListViewState extends State<ChannelListView> class _ChannelListViewState extends State<ChannelListView>
with WidgetsBindingObserver, AutomaticKeepAliveClientMixin { with WidgetsBindingObserver {
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
ChannelsBloc channelsBloc;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); final streamChat = StreamChat.of(context);
return RefreshIndicator( return RefreshIndicator(
onRefresh: () async { onRefresh: () async {
return channelsBloc.queryChannels( return streamChat.queryChannels(
filter: widget.filter, filter: widget.filter,
sortOptions: widget.sort, sortOptions: widget.sort,
paginationParams: widget.pagination, paginationParams: widget.pagination,
@@ -117,7 +116,7 @@ class _ChannelListViewState extends State<ChannelListView>
); );
}, },
child: StreamBuilder<List<Channel>>( child: StreamBuilder<List<Channel>>(
stream: channelsBloc.channelsStream, stream: streamChat.channelsStream,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) { if (snapshot.hasError) {
if (snapshot.error is Error) { if (snapshot.error is Error) {
@@ -165,7 +164,7 @@ class _ChannelListViewState extends State<ChannelListView>
), ),
FlatButton( FlatButton(
onPressed: () { onPressed: () {
channelsBloc.queryChannels( streamChat.queryChannels(
filter: widget.filter, filter: widget.filter,
sortOptions: widget.sort, sortOptions: widget.sort,
paginationParams: widget.pagination, paginationParams: widget.pagination,
@@ -217,7 +216,7 @@ class _ChannelListViewState extends State<ChannelListView>
if (i < channels.length) { if (i < channels.length) {
final channel = channels[i]; final channel = channels[i];
final channelClient = channelsBloc.channels.firstWhere( final channelClient = streamChat.channels.firstWhere(
(c) => c.cid == channel.cid, (c) => c.cid == channel.cid,
orElse: () => null, orElse: () => null,
); );
@@ -287,7 +286,7 @@ class _ChannelListViewState extends State<ChannelListView>
Widget _buildQueryProgressIndicator(context, StreamChatState streamChat) { Widget _buildQueryProgressIndicator(context, StreamChatState streamChat) {
return StreamBuilder<bool>( return StreamBuilder<bool>(
stream: channelsBloc.queryChannelsLoading, stream: streamChat.queryChannelsLoading,
initialData: false, initialData: false,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) { if (snapshot.hasError) {
@@ -322,11 +321,11 @@ class _ChannelListViewState extends State<ChannelListView>
void _listenChannelPagination(StreamChatState streamChat) { void _listenChannelPagination(StreamChatState streamChat) {
if (_scrollController.position.maxScrollExtent == if (_scrollController.position.maxScrollExtent ==
_scrollController.offset) { _scrollController.offset) {
channelsBloc.queryChannels( streamChat.queryChannels(
filter: widget.filter, filter: widget.filter,
sortOptions: widget.sort, sortOptions: widget.sort,
paginationParams: widget.pagination.copyWith( paginationParams: widget.pagination.copyWith(
offset: channelsBloc.channels.length, offset: streamChat.channels.length,
), ),
options: widget.options, options: widget.options,
); );
@@ -336,12 +335,12 @@ class _ChannelListViewState extends State<ChannelListView>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
final streamChat = StreamChat.of(context); final streamChat = StreamChat.of(context);
channelsBloc = ChannelsBloc(streamChat.client);
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
channelsBloc.queryChannels( streamChat.queryChannels(
filter: widget.filter, filter: widget.filter,
sortOptions: widget.sort, sortOptions: widget.sort,
paginationParams: widget.pagination, paginationParams: widget.pagination,
@@ -356,7 +355,7 @@ class _ChannelListViewState extends State<ChannelListView>
@override @override
void didChangeAppLifecycleState(AppLifecycleState state) { void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) { if (state == AppLifecycleState.resumed) {
channelsBloc.queryChannels( StreamChat.of(context).queryChannels(
filter: widget.filter, filter: widget.filter,
sortOptions: widget.sort, sortOptions: widget.sort,
paginationParams: widget.pagination, paginationParams: widget.pagination,
@@ -369,7 +368,6 @@ class _ChannelListViewState extends State<ChannelListView>
@override @override
void dispose() { void dispose() {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
channelsBloc.dispose();
super.dispose(); super.dispose();
} }
-88
View File
@@ -1,88 +0,0 @@
import 'dart:async';
import 'package:rxdart/rxdart.dart';
import 'package:stream_chat/stream_chat.dart';
class ChannelsBloc {
final Client client;
StreamSubscription _newMessagesSubscription;
ChannelsBloc(this.client) {
_newMessagesSubscription = client.on(EventType.messageNew).listen((e) {
final newChannels = List<Channel>.from(channels ?? []);
final index = newChannels.indexWhere((c) => c.cid == e.cid);
if (index > 0) {
final channel = newChannels.removeAt(index);
newChannels.insert(0, channel);
_channelsController.add(newChannels);
}
});
}
/// The current channel list
List<Channel> get channels => _channelsController.value;
/// The current channel list as a stream
Stream<List<Channel>> get channelsStream => _channelsController.stream;
final BehaviorSubject<bool> _queryChannelsLoadingController =
BehaviorSubject.seeded(false);
final BehaviorSubject<List<Channel>> _channelsController =
BehaviorSubject.seeded([]);
/// The stream notifying the state of queryChannel call
Stream<bool> get queryChannelsLoading =>
_queryChannelsLoadingController.stream;
/// Calls [client.queryChannels] updating [queryChannelsLoading] stream
Future<void> queryChannels({
Map<String, dynamic> filter,
List<SortOption> sortOptions,
PaginationParams paginationParams,
Map<String, dynamic> options,
bool onlyOffline = false,
}) async {
if (_queryChannelsLoadingController.value == true) {
return;
}
_queryChannelsLoadingController.sink.add(true);
try {
final clear = paginationParams == null ||
paginationParams.offset == null ||
paginationParams.offset == 0;
final oldChannels = List<Channel>.from(channels);
client
.queryChannels(
filter: filter,
sort: sortOptions,
options: options,
paginationParams: paginationParams,
onlyOffline: onlyOffline,
)
.listen((channels) {
if (clear) {
_channelsController.add(channels);
} else {
final l = oldChannels + channels;
_channelsController.add(l);
}
}, onDone: () {
_queryChannelsLoadingController.sink.add(false);
}, onError: (err, stackTrace) {
print(err);
print(stackTrace);
_queryChannelsLoadingController.addError(err, stackTrace);
});
} catch (err, stackTrace) {
_queryChannelsLoadingController.addError(err, stackTrace);
}
}
void dispose() {
_channelsController.close();
_queryChannelsLoadingController.close();
_newMessagesSubscription.cancel();
}
}
+89 -1
View File
@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
@@ -58,12 +59,15 @@ class StreamChat extends StatefulWidget {
} }
} }
class StreamChatState extends State<StreamChat> with WidgetsBindingObserver { class StreamChatState extends State<StreamChat>
with WidgetsBindingObserver, AutomaticKeepAliveClientMixin {
Client get client => widget.client; Client get client => widget.client;
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context);
final theme = _getTheme(context, widget.streamChatThemeData); final theme = _getTheme(context, widget.streamChatThemeData);
return StreamChatTheme( return StreamChatTheme(
data: theme, data: theme,
@@ -175,9 +179,83 @@ class StreamChatState extends State<StreamChat> with WidgetsBindingObserver {
/// The current user as a stream /// The current user as a stream
Stream<User> get userStream => widget.client.state.userStream; Stream<User> get userStream => widget.client.state.userStream;
/// The current channel list
List<Channel> get channels => _channelsController.value;
/// The current channel list as a stream
Stream<List<Channel>> get channelsStream => _channelsController.stream;
final BehaviorSubject<bool> _queryChannelsLoadingController =
BehaviorSubject.seeded(false);
final BehaviorSubject<List<Channel>> _channelsController =
BehaviorSubject.seeded([]);
/// The stream notifying the state of queryChannel call
Stream<bool> get queryChannelsLoading =>
_queryChannelsLoadingController.stream;
/// Calls [client.queryChannels] updating [queryChannelsLoading] stream
Future<void> queryChannels({
Map<String, dynamic> filter,
List<SortOption> sortOptions,
PaginationParams paginationParams,
Map<String, dynamic> options,
bool onlyOffline = false,
}) async {
if (_queryChannelsLoadingController.value == true) {
return;
}
_queryChannelsLoadingController.sink.add(true);
try {
final clear = paginationParams == null ||
paginationParams.offset == null ||
paginationParams.offset == 0;
final oldChannels = List<Channel>.from(channels);
client
.queryChannels(
filter: filter,
sort: sortOptions,
options: options,
paginationParams: paginationParams,
onlyOffline: onlyOffline,
)
.listen((channels) {
if (clear) {
_channelsController.add(channels);
} else {
final l = oldChannels + channels;
_channelsController.add(l);
}
}, onDone: () {
_queryChannelsLoadingController.sink.add(false);
}, onError: (err, stackTrace) {
print(err);
print(stackTrace);
_queryChannelsLoadingController.addError(err, stackTrace);
});
} catch (err, stackTrace) {
_queryChannelsLoadingController.addError(err, stackTrace);
}
}
StreamSubscription _newMessagesSubscription;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_newMessagesSubscription = client.on(EventType.messageNew).listen((e) {
final newChannels = List<Channel>.from(channels ?? []);
final index = newChannels.indexWhere((c) => c.cid == e.cid);
if (index > 0) {
final channel = newChannels.removeAt(index);
newChannels.insert(0, channel);
_channelsController.add(newChannels);
}
});
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
} }
@@ -196,6 +274,16 @@ class StreamChatState extends State<StreamChat> with WidgetsBindingObserver {
@override @override
void dispose() { void dispose() {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
print('disposeeeeeeeeee');
_channelsController.close();
_queryChannelsLoadingController.close();
_newMessagesSubscription.cancel();
super.dispose(); super.dispose();
} }
@override
bool get wantKeepAlive => true;
} }