add threads example
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
void main() async {
|
||||
final client = Client('qk4nn7rpcn75');
|
||||
|
||||
await client.setUser(
|
||||
User(id: 'wild-breeze-7'),
|
||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoid2lsZC1icmVlemUtNyJ9.VM2EX1EXOfgqa-bTH_3JzeY0T99ngWzWahSauP3dBMo',
|
||||
);
|
||||
|
||||
runApp(
|
||||
StreamChat(
|
||||
client: client,
|
||||
child: MaterialApp(
|
||||
home: ChannelListPage(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class ChannelListPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ChannelListView(
|
||||
filter: {
|
||||
'members': {
|
||||
'\$in': [StreamChat.of(context).user.id],
|
||||
}
|
||||
},
|
||||
sort: [SortOption('last_message_at')],
|
||||
pagination: PaginationParams(
|
||||
limit: 20,
|
||||
),
|
||||
channelWidget: ChannelPage(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelPage extends StatelessWidget {
|
||||
const ChannelPage({
|
||||
Key key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: MessageListView(
|
||||
threadBuilder: (_, message) {
|
||||
return ThreadPage(
|
||||
parent: message,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
MessageInput(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadPage extends StatelessWidget {
|
||||
final Message parent;
|
||||
|
||||
ThreadPage({
|
||||
Key key,
|
||||
this.parent,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: MessageListView(
|
||||
parentMessage: parent,
|
||||
),
|
||||
),
|
||||
MessageInput(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,7 @@ class ChannelListView extends StatefulWidget {
|
||||
this.onChannelTap,
|
||||
this.channelWidget,
|
||||
this.channelPreviewBuilder,
|
||||
}) : assert(channelWidget != null || onChannelTap != null),
|
||||
super(key: key);
|
||||
}) : super(key: key);
|
||||
|
||||
final Map<String, dynamic> filter;
|
||||
final Map<String, dynamic> options;
|
||||
|
||||
@@ -9,7 +9,8 @@ import 'stream_channel.dart';
|
||||
|
||||
typedef MessageBuilder = Widget Function(BuildContext, Message, int index);
|
||||
typedef ParentMessageBuilder = Widget Function(BuildContext, Message);
|
||||
typedef OnThreadSelectCallback = void Function(Message parent);
|
||||
typedef ThreadBuilder = Widget Function(BuildContext context, Message parent);
|
||||
typedef ThreadTapCallback = void Function(Message, Widget);
|
||||
|
||||
class MessageListView extends StatefulWidget {
|
||||
MessageListView({
|
||||
@@ -17,13 +18,15 @@ class MessageListView extends StatefulWidget {
|
||||
MessageBuilder messageBuilder,
|
||||
this.parentMessageBuilder,
|
||||
this.parentMessage,
|
||||
this.onThreadSelect,
|
||||
this.threadBuilder,
|
||||
this.onThreadTap,
|
||||
}) : _messageBuilder = messageBuilder,
|
||||
super(key: key);
|
||||
|
||||
final MessageBuilder _messageBuilder;
|
||||
final ParentMessageBuilder parentMessageBuilder;
|
||||
final OnThreadSelectCallback onThreadSelect;
|
||||
final ThreadBuilder threadBuilder;
|
||||
final ThreadTapCallback onThreadTap;
|
||||
final Message parentMessage;
|
||||
|
||||
@override
|
||||
@@ -38,6 +41,8 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
List<Message> _messages = [];
|
||||
List<Message> _newMessageList = [];
|
||||
|
||||
Function _onThreadTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final streamChannel = StreamChannel.of(context);
|
||||
@@ -74,7 +79,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
previousMessage: null,
|
||||
message: widget.parentMessage.copyWith(replyCount: 0),
|
||||
nextMessage: null,
|
||||
onThreadSelect: widget.onThreadSelect,
|
||||
onThreadTap: _onThreadTap,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
@@ -131,7 +136,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
previousMessage: previousMessage,
|
||||
message: message,
|
||||
nextMessage: nextMessage,
|
||||
onThreadSelect: widget.onThreadSelect,
|
||||
onThreadTap: _onThreadTap,
|
||||
);
|
||||
},
|
||||
childCount: _messages.length + 2,
|
||||
@@ -185,7 +190,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
previousMessage: null,
|
||||
message: message,
|
||||
nextMessage: nextMessage,
|
||||
onThreadSelect: widget.onThreadSelect,
|
||||
onThreadTap: _onThreadTap,
|
||||
),
|
||||
onVisibilityChanged: (visibility) {
|
||||
final topIsVisible = visibility.visibleBounds != Rect.zero;
|
||||
@@ -218,7 +223,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
previousMessage: previousMessage,
|
||||
message: message,
|
||||
nextMessage: null,
|
||||
onThreadSelect: widget.onThreadSelect,
|
||||
onThreadTap: _onThreadTap,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -270,6 +275,32 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_getOnThreadTap();
|
||||
}
|
||||
|
||||
void _getOnThreadTap() {
|
||||
if (widget.onThreadTap != null) {
|
||||
_onThreadTap = (message) {
|
||||
widget.onThreadTap(
|
||||
message,
|
||||
widget.threadBuilder != null
|
||||
? widget.threadBuilder(context, message)
|
||||
: null);
|
||||
};
|
||||
} else {
|
||||
_onThreadTap = (message) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) {
|
||||
return StreamChannel(
|
||||
channelClient: StreamChannel.of(context).channelClient,
|
||||
child: widget.threadBuilder(context, message),
|
||||
);
|
||||
}),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -9,7 +9,6 @@ import 'package:stream_chat_flutter/src/user_avatar.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
import 'message_list_view.dart';
|
||||
import 'stream_chat.dart';
|
||||
|
||||
class MessageWidget extends StatefulWidget {
|
||||
@@ -18,13 +17,13 @@ class MessageWidget extends StatefulWidget {
|
||||
@required this.previousMessage,
|
||||
@required this.message,
|
||||
@required this.nextMessage,
|
||||
this.onThreadSelect,
|
||||
this.onThreadTap,
|
||||
}) : super(key: key);
|
||||
|
||||
final Message previousMessage;
|
||||
final Message message;
|
||||
final Message nextMessage;
|
||||
final OnThreadSelectCallback onThreadSelect;
|
||||
final void Function(Message) onThreadTap;
|
||||
|
||||
@override
|
||||
_MessageWidgetState createState() => _MessageWidgetState();
|
||||
@@ -59,8 +58,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
widget.message.replyCount > 0
|
||||
? GestureDetector(
|
||||
onTap: () {
|
||||
if (widget.onThreadSelect != null) {
|
||||
widget.onThreadSelect(widget.message);
|
||||
if (widget.onThreadTap != null) {
|
||||
widget.onThreadTap(widget.message);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
|
||||
Reference in New Issue
Block a user