add doc
@@ -14,7 +14,6 @@ import 'stream_channel.dart';
|
||||
/// It shows the current [Channel] information.
|
||||
///
|
||||
/// ```dart
|
||||
///
|
||||
/// class MyApp extends StatelessWidget {
|
||||
/// final Client client;
|
||||
/// final Channel channel;
|
||||
@@ -36,7 +35,6 @@ import 'stream_channel.dart';
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// Usually you would use this widget as an [AppBar] inside a [Scaffold].
|
||||
@@ -52,9 +50,14 @@ import 'stream_channel.dart';
|
||||
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme] and on its [ChannelTheme.channelHeaderTheme] property.
|
||||
/// Modify it to change the widget appearance.
|
||||
class ChannelHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
/// True if this header shows the leading back button
|
||||
final bool showBackButton;
|
||||
|
||||
/// Callback to call when pressing the back button.
|
||||
/// By default it calls [Navigator.pop]
|
||||
final VoidCallback onBackPressed;
|
||||
|
||||
/// Creates a channel header
|
||||
ChannelHeader({
|
||||
Key key,
|
||||
this.showBackButton = true,
|
||||
|
||||
@@ -3,6 +3,45 @@ import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// It shows the current [Channel] image.
|
||||
///
|
||||
/// ```dart
|
||||
/// class MyApp extends StatelessWidget {
|
||||
/// final Client client;
|
||||
/// final Channel channel;
|
||||
///
|
||||
/// MyApp(this.client, this.channel);
|
||||
///
|
||||
/// @override
|
||||
/// Widget build(BuildContext context) {
|
||||
/// return MaterialApp(
|
||||
/// debugShowCheckedModeBanner: false,
|
||||
/// home: StreamChat(
|
||||
/// client: client,
|
||||
/// child: StreamChannel(
|
||||
/// channel: channel,
|
||||
/// child: Center(
|
||||
/// child: ChannelImage(
|
||||
/// channel: channel,
|
||||
/// ),
|
||||
/// ),
|
||||
/// ),
|
||||
/// ),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// The widget uses a [StreamBuilder] to render the channel information image as soon as it updates.
|
||||
///
|
||||
/// By default the widget radius size is 40x40 pixels.
|
||||
/// Set the property [size] to set a custom dimension.
|
||||
///
|
||||
/// The widget renders the ui based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget appearance.
|
||||
class ChannelImage extends StatelessWidget {
|
||||
const ChannelImage({
|
||||
Key key,
|
||||
@@ -10,7 +49,10 @@ class ChannelImage extends StatelessWidget {
|
||||
this.size = 40,
|
||||
}) : super(key: key);
|
||||
|
||||
/// The channel to show the image of
|
||||
final Channel channel;
|
||||
|
||||
/// The diameter of the image
|
||||
final double size;
|
||||
|
||||
@override
|
||||
|
||||
@@ -6,9 +6,45 @@ import 'channel_preview.dart';
|
||||
import 'stream_channel.dart';
|
||||
import 'stream_chat.dart';
|
||||
|
||||
/// Callback called when tapping on a channel
|
||||
typedef ChannelTapCallback = void Function(Channel, Widget);
|
||||
|
||||
/// Builder used to create a custom [ChannelPreview] from a [Channel]
|
||||
typedef ChannelPreviewBuilder = Widget Function(BuildContext, Channel);
|
||||
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// It shows the list of current channels.
|
||||
///
|
||||
/// ```dart
|
||||
/// 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(),
|
||||
/// ),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
/// Make sure to have a [StreamChat] ancestor in order to provide the information about the channels.
|
||||
/// The widget uses a [ListView.custom] to render the list of channels.
|
||||
///
|
||||
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget appearance.
|
||||
class ChannelListView extends StatefulWidget {
|
||||
ChannelListView({
|
||||
Key key,
|
||||
@@ -21,12 +57,38 @@ class ChannelListView extends StatefulWidget {
|
||||
this.channelPreviewBuilder,
|
||||
}) : super(key: key);
|
||||
|
||||
/// The query filters to use.
|
||||
/// You can query on any of the custom fields you've defined on the [Channel].
|
||||
/// You can also filter other built-in channel fields.
|
||||
final Map<String, dynamic> filter;
|
||||
|
||||
/// Query channels options.
|
||||
///
|
||||
/// state: if true returns the Channel state
|
||||
/// watch: if true listen to changes to this Channel in real time.
|
||||
final Map<String, dynamic> options;
|
||||
|
||||
/// The sorting used for the channels matching the filters.
|
||||
/// Sorting is based on field and direction, multiple sorting options can be provided.
|
||||
/// You can sort based on last_updated, last_message_at, updated_at, created_at or member_count.
|
||||
/// Direction can be ascending or descending.
|
||||
final List<SortOption> sort;
|
||||
|
||||
/// Pagination parameters
|
||||
/// limit: the number of channels to return (max is 30)
|
||||
/// offset: the offset (max is 1000)
|
||||
/// message_limit: how many messages should be included to each channel
|
||||
final PaginationParams pagination;
|
||||
|
||||
/// Function called when tapping on a channel
|
||||
/// By default it calls [Navigator.push] building a [MaterialPageRoute]
|
||||
/// with the widget [channelWidget] as child.
|
||||
final ChannelTapCallback onChannelTap;
|
||||
|
||||
/// Widget used when opening a channel
|
||||
final Widget channelWidget;
|
||||
|
||||
/// Builder used to create a custom channel preview
|
||||
final ChannelPreviewBuilder channelPreviewBuilder;
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
|
||||
/// It shows the current [Channel] name using a [Text] widget.
|
||||
///
|
||||
/// The widget uses a [StreamBuilder] to render the channel information image as soon as it updates.
|
||||
class ChannelName extends StatelessWidget {
|
||||
const ChannelName({
|
||||
Key key,
|
||||
@@ -8,7 +11,10 @@ class ChannelName extends StatelessWidget {
|
||||
this.textStyle,
|
||||
}) : super(key: key);
|
||||
|
||||
/// The channel to show the name of
|
||||
final Channel channel;
|
||||
|
||||
/// The style of the text displayed
|
||||
final TextStyle textStyle;
|
||||
|
||||
@override
|
||||
|
||||
@@ -6,8 +6,22 @@ import 'package:stream_chat/stream_chat.dart';
|
||||
import '../stream_chat_flutter.dart';
|
||||
import 'channel_name.dart';
|
||||
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// It shows the current [Channel] preview.
|
||||
///
|
||||
/// The widget uses a [StreamBuilder] to render the channel information image as soon as it updates.
|
||||
///
|
||||
/// Usually you don't use this widget as it's the default channel preview used by [ChannelListView].
|
||||
///
|
||||
/// The widget renders the ui based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget appearance.
|
||||
class ChannelPreview extends StatelessWidget {
|
||||
/// Function called when tapping this widget
|
||||
final void Function(Channel) onTap;
|
||||
|
||||
/// Channel displayed
|
||||
final Channel channel;
|
||||
|
||||
ChannelPreview({
|
||||
|
||||
@@ -5,10 +5,51 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/message_list_view.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
import 'stream_channel.dart';
|
||||
|
||||
/// 
|
||||
/// 
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// Widget used to enter the message and add attachments
|
||||
///
|
||||
/// ```dart
|
||||
/// class ChannelPage extends StatelessWidget {
|
||||
/// const ChannelPage({
|
||||
/// Key key,
|
||||
/// }) : super(key: key);
|
||||
///
|
||||
/// @override
|
||||
/// Widget build(BuildContext context) {
|
||||
/// return Scaffold(
|
||||
/// appBar: ChannelHeader(),
|
||||
/// body: Column(
|
||||
/// children: <Widget>[
|
||||
/// Expanded(
|
||||
/// child: MessageListView(
|
||||
/// threadBuilder: (_, parentMessage) {
|
||||
/// return ThreadPage(
|
||||
/// parent: parentMessage,
|
||||
/// );
|
||||
/// },
|
||||
/// ),
|
||||
/// ),
|
||||
/// MessageInput(),
|
||||
/// ],
|
||||
/// ),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// You usually put this widget in the same page of a [MessageListView] as the bottom widget.
|
||||
///
|
||||
/// The widget renders the ui based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget appearance.
|
||||
class MessageInput extends StatefulWidget {
|
||||
MessageInput({
|
||||
Key key,
|
||||
@@ -16,7 +57,10 @@ class MessageInput extends StatefulWidget {
|
||||
this.parentMessage,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Function called after sending the message
|
||||
final void Function(Message) onMessageSent;
|
||||
|
||||
/// Parent message in case of a thread
|
||||
final Message parentMessage;
|
||||
|
||||
@override
|
||||
|
||||
@@ -13,6 +13,46 @@ typedef ParentMessageBuilder = Widget Function(BuildContext, Message);
|
||||
typedef ThreadBuilder = Widget Function(BuildContext context, Message parent);
|
||||
typedef ThreadTapCallback = void Function(Message, Widget);
|
||||
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// It shows the list of messages of the current channel.
|
||||
///
|
||||
/// ```dart
|
||||
/// class ChannelPage extends StatelessWidget {
|
||||
/// const ChannelPage({
|
||||
/// Key key,
|
||||
/// }) : super(key: key);
|
||||
///
|
||||
/// @override
|
||||
/// Widget build(BuildContext context) {
|
||||
/// return Scaffold(
|
||||
/// appBar: ChannelHeader(),
|
||||
/// body: Column(
|
||||
/// children: <Widget>[
|
||||
/// Expanded(
|
||||
/// child: MessageListView(
|
||||
/// threadBuilder: (_, parentMessage) {
|
||||
/// return ThreadPage(
|
||||
/// parent: parentMessage,
|
||||
/// );
|
||||
/// },
|
||||
/// ),
|
||||
/// ),
|
||||
/// MessageInput(),
|
||||
/// ],
|
||||
/// ),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
/// Make sure to have a [StreamChannel] ancestor in order to provide the information about the channels.
|
||||
/// The widget uses a [ListView.custom] to render the list of channels.
|
||||
///
|
||||
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget appearance.
|
||||
class MessageListView extends StatefulWidget {
|
||||
MessageListView({
|
||||
Key key,
|
||||
@@ -23,10 +63,20 @@ class MessageListView extends StatefulWidget {
|
||||
this.onThreadTap,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Function used to build a custom message widget
|
||||
final MessageBuilder messageBuilder;
|
||||
|
||||
/// Function used to build a custom parent message widget
|
||||
final ParentMessageBuilder parentMessageBuilder;
|
||||
|
||||
/// Function used to build a custom thread widget
|
||||
final ThreadBuilder threadBuilder;
|
||||
|
||||
/// Function called when tapping on a thread
|
||||
/// By default it calls [Navigator.push] using the widget built using [threadBuilder]
|
||||
final ThreadTapCallback onThreadTap;
|
||||
|
||||
/// Parent message in case of a thread
|
||||
final Message parentMessage;
|
||||
|
||||
@override
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/message_list_view.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_channel.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
||||
@@ -16,6 +17,15 @@ import 'package:video_player/video_player.dart';
|
||||
|
||||
import 'stream_chat.dart';
|
||||
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// It shows a message with reactions, replies and user avatar.
|
||||
///
|
||||
/// Usually you don't use this widget as it's the default message widget used by [MessageListView].
|
||||
///
|
||||
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget appearance.
|
||||
class MessageWidget extends StatefulWidget {
|
||||
const MessageWidget({
|
||||
Key key,
|
||||
@@ -26,10 +36,19 @@ class MessageWidget extends StatefulWidget {
|
||||
this.isParent = false,
|
||||
}) : super(key: key);
|
||||
|
||||
final Message previousMessage;
|
||||
/// This message
|
||||
final Message message;
|
||||
|
||||
/// The previous message
|
||||
final Message previousMessage;
|
||||
|
||||
/// The next message
|
||||
final Message nextMessage;
|
||||
|
||||
/// The function called when tapping on replies
|
||||
final void Function(Message) onThreadTap;
|
||||
|
||||
/// True if this is the parent of the thread being showed
|
||||
final bool isParent;
|
||||
|
||||
@override
|
||||
|
||||
@@ -4,6 +4,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
|
||||
/// Widget used to provide information about the channel to the widget tree
|
||||
///
|
||||
/// Use [StreamChannel.of] to get the current [StreamChannelState] instance.
|
||||
class StreamChannel extends StatefulWidget {
|
||||
StreamChannel({
|
||||
Key key,
|
||||
@@ -16,6 +19,7 @@ class StreamChannel extends StatefulWidget {
|
||||
final Widget child;
|
||||
final Channel channel;
|
||||
|
||||
/// Use this method to get the current [StreamChannelState] instance
|
||||
static StreamChannelState of(BuildContext context) {
|
||||
StreamChannelState streamChannelState;
|
||||
|
||||
@@ -34,17 +38,19 @@ class StreamChannel extends StatefulWidget {
|
||||
}
|
||||
|
||||
class StreamChannelState extends State<StreamChannel> {
|
||||
StreamChannelState();
|
||||
|
||||
/// Current channel
|
||||
Channel get channel => widget.channel;
|
||||
|
||||
/// Current channel state stream
|
||||
Stream<ChannelState> get channelStateStream =>
|
||||
widget.channel.state.channelStateStream;
|
||||
|
||||
final BehaviorSubject<bool> _queryMessageController = BehaviorSubject();
|
||||
|
||||
/// The stream notifying the state of queryMessage call
|
||||
Stream<bool> get queryMessage => _queryMessageController.stream;
|
||||
|
||||
/// Calls [channel.query] updating [queryMessage] stream
|
||||
void queryMessages() {
|
||||
_queryMessageController.add(true);
|
||||
|
||||
@@ -67,6 +73,7 @@ class StreamChannelState extends State<StreamChannel> {
|
||||
});
|
||||
}
|
||||
|
||||
/// Calls [channel.getReplies] updating [queryMessage] stream
|
||||
Future<void> getReplies(String parentId) async {
|
||||
_queryMessageController.add(true);
|
||||
print('PARENT $parentId');
|
||||
|
||||
@@ -6,6 +6,27 @@ import 'package:rxdart/rxdart.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
/// Widget used to provide information about the chat to the widget tree
|
||||
///
|
||||
/// class MyApp extends StatelessWidget {
|
||||
/// final Client client;
|
||||
///
|
||||
/// MyApp(this.client);
|
||||
///
|
||||
/// @override
|
||||
/// Widget build(BuildContext context) {
|
||||
/// return MaterialApp(
|
||||
/// home: Container(
|
||||
/// child: StreamChat(
|
||||
/// client: client,
|
||||
/// child: ChannelListPage(),
|
||||
/// ),
|
||||
/// ),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// Use [StreamChat.of] to get the current [StreamChatState] instance.
|
||||
class StreamChat extends StatefulWidget {
|
||||
final Client client;
|
||||
final Widget child;
|
||||
@@ -23,6 +44,7 @@ class StreamChat extends StatefulWidget {
|
||||
@override
|
||||
StreamChatState createState() => StreamChatState();
|
||||
|
||||
/// Use this method to get the current [StreamChatState] instance
|
||||
static StreamChatState of(BuildContext context) {
|
||||
StreamChatState streamChatState;
|
||||
|
||||
@@ -162,22 +184,28 @@ class StreamChatState extends State<StreamChat> {
|
||||
}));
|
||||
}
|
||||
|
||||
/// The current user
|
||||
User get user => widget.client.state.user;
|
||||
|
||||
/// The current user as a stream
|
||||
Stream<User> get userStream => widget.client.state.userStream;
|
||||
|
||||
/// The current channel list
|
||||
final List<Channel> channels = [];
|
||||
|
||||
/// The current channel list as a stream
|
||||
Stream<List<Channel>> get channelsStream => _channelsController.stream;
|
||||
|
||||
final BehaviorSubject<List<Channel>> _channelsController = BehaviorSubject();
|
||||
|
||||
final List<Channel> channels = [];
|
||||
|
||||
final BehaviorSubject<bool> _queryChannelsLoadingController =
|
||||
BehaviorSubject.seeded(false);
|
||||
|
||||
/// 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,
|
||||
@@ -204,6 +232,7 @@ class StreamChatState extends State<StreamChat> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear the current channel list
|
||||
void clearChannels() {
|
||||
channels.clear();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/channel_header.dart';
|
||||
import 'package:stream_chat_flutter/src/channel_preview.dart';
|
||||
import 'package:stream_chat_flutter/src/message_input.dart';
|
||||
|
||||
/// Inherited widget providing the [StreamChatThemeData] to the widget tree
|
||||
class StreamChatTheme extends InheritedWidget {
|
||||
final StreamChatThemeData data;
|
||||
|
||||
@@ -17,20 +21,36 @@ class StreamChatTheme extends InheritedWidget {
|
||||
return data != old.data;
|
||||
}
|
||||
|
||||
/// Use this method to get the current [StreamChatThemeData] instance
|
||||
static StreamChatThemeData of(BuildContext context) {
|
||||
return context.dependOnInheritedWidgetOfExactType<StreamChatTheme>().data;
|
||||
}
|
||||
}
|
||||
|
||||
/// Theme data
|
||||
class StreamChatThemeData {
|
||||
/// Primary color of the chat widgets
|
||||
final Color primaryColor;
|
||||
|
||||
/// Secondary color of the chat widgets
|
||||
final Color secondaryColor;
|
||||
|
||||
/// Accent color of the chat widgets
|
||||
final Color accentColor;
|
||||
|
||||
/// Theme of the [ChannelPreview]
|
||||
final ChannelPreviewTheme channelPreviewTheme;
|
||||
|
||||
/// Theme of the chat widgets dedicated to a channel
|
||||
final ChannelTheme channelTheme;
|
||||
|
||||
/// Theme of the current user messages
|
||||
final MessageTheme ownMessageTheme;
|
||||
|
||||
/// Theme of other users messages
|
||||
final MessageTheme otherMessageTheme;
|
||||
|
||||
/// Create a theme from scratch
|
||||
StreamChatThemeData({
|
||||
this.primaryColor,
|
||||
this.secondaryColor,
|
||||
@@ -41,6 +61,7 @@ class StreamChatThemeData {
|
||||
this.ownMessageTheme,
|
||||
});
|
||||
|
||||
/// Create a theme from a Material [Theme]
|
||||
factory StreamChatThemeData.fromTheme(ThemeData theme) {
|
||||
final defaultTheme = getDefaultTheme(theme);
|
||||
|
||||
@@ -67,6 +88,7 @@ class StreamChatThemeData {
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a copy of [StreamChatThemeData] with specified attributes overridden.
|
||||
StreamChatThemeData copyWith({
|
||||
Color primaryColor,
|
||||
Color secondaryColor,
|
||||
@@ -141,6 +163,7 @@ class StreamChatThemeData {
|
||||
this.otherMessageTheme,
|
||||
);
|
||||
|
||||
/// Get the default Stream Chat theme
|
||||
static StreamChatThemeData getDefaultTheme(ThemeData theme) {
|
||||
final accentColor = Color(0xff006cff);
|
||||
return StreamChatThemeData(
|
||||
@@ -245,11 +268,21 @@ class StreamChatThemeData {
|
||||
}
|
||||
}
|
||||
|
||||
/// Channel theme data
|
||||
class ChannelTheme {
|
||||
/// Theme of the [ChannelHeader] widget
|
||||
final ChannelHeaderTheme channelHeaderTheme;
|
||||
|
||||
/// IconTheme of the send button in [MessageInput]
|
||||
final IconThemeData messageInputButtonIconTheme;
|
||||
|
||||
/// Theme of the send button in [MessageInput]
|
||||
final ButtonThemeData messageInputButtonTheme;
|
||||
|
||||
/// Gradient of [MessageInput]
|
||||
final Gradient inputGradient;
|
||||
|
||||
/// Background color of [MessageInput]
|
||||
final Color inputBackground;
|
||||
|
||||
ChannelTheme({
|
||||
@@ -260,6 +293,7 @@ class ChannelTheme {
|
||||
this.inputGradient,
|
||||
});
|
||||
|
||||
/// Creates a copy of [ChannelTheme] with specified attributes overridden.
|
||||
ChannelTheme copyWith({
|
||||
ChannelHeaderTheme channelHeaderTheme,
|
||||
IconThemeData messageInputButtonIconTheme,
|
||||
|
||||
@@ -2,9 +2,64 @@ import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// It shows the current thread information.
|
||||
///
|
||||
/// ```dart
|
||||
/// class ThreadPage extends StatelessWidget {
|
||||
/// final Message parent;
|
||||
///
|
||||
/// ThreadPage({
|
||||
/// Key key,
|
||||
/// this.parent,
|
||||
/// }) : super(key: key);
|
||||
///
|
||||
/// @override
|
||||
/// Widget build(BuildContext context) {
|
||||
/// return Scaffold(
|
||||
/// appBar: ThreadHeader(
|
||||
/// parent: parent,
|
||||
/// ),
|
||||
/// body: Column(
|
||||
/// children: <Widget>[
|
||||
/// Expanded(
|
||||
/// child: MessageListView(
|
||||
/// parentMessage: parent,
|
||||
/// ),
|
||||
/// ),
|
||||
/// MessageInput(
|
||||
/// parentMessage: parent,
|
||||
/// ),
|
||||
/// ],
|
||||
/// ),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Usually you would use this widget as an [AppBar] inside a [Scaffold].
|
||||
/// However you can also use it as a normal widget.
|
||||
///
|
||||
/// Make sure to have a [StreamChannel] ancestor in order to provide the information about the channel.
|
||||
/// Every part of the widget uses a [StreamBuilder] to render the channel information as soon as it updates.
|
||||
///
|
||||
/// By default the widget shows a backButton that calls [Navigator.pop].
|
||||
/// You can disable this button using the [showBackButton] property of just override the behaviour
|
||||
/// with [onBackPressed].
|
||||
///
|
||||
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme] and on its [ChannelTheme.channelHeaderTheme] property.
|
||||
/// Modify it to change the widget appearance.
|
||||
class ThreadHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
/// True if this header shows the leading back button
|
||||
final bool showBackButton;
|
||||
|
||||
/// Callback to call when pressing the back button.
|
||||
/// By default it calls [Navigator.pop]
|
||||
final VoidCallback onBackPressed;
|
||||
|
||||
/// The message parent of this thread
|
||||
final Message parent;
|
||||
|
||||
ThreadHeader({
|
||||
|
||||
@@ -30,9 +30,15 @@ class UserAvatar extends StatelessWidget {
|
||||
imageUrl: user.extraData['image'],
|
||||
errorWidget: (_, __, ___) {
|
||||
return Center(
|
||||
child: Text(user.extraData?.containsKey('name') ?? false
|
||||
? user.extraData['name'][0]
|
||||
: ''),
|
||||
child: Text(
|
||||
user.extraData?.containsKey('name') ?? false
|
||||
? user.extraData['name'][0]
|
||||
: '',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
fit: BoxFit.cover,
|
||||
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 209 KiB |
|
After Width: | Height: | Size: 294 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 337 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
|
After Width: | Height: | Size: 10 KiB |