version bump
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
## 0.2.1-alpha
|
||||
|
||||
- New message widget
|
||||
- Moved some properties from `MessageListView` to `MessageWidget`
|
||||
- Added `MessageDetails` property to `MessageBuilder`
|
||||
- Added example to customize the message using `MessageWidget` (`customize_message_widget.dart`)
|
||||
|
||||
## 0.2.0-alpha+15
|
||||
|
||||
- Add background color in StreamChatTheme
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
/// Fifth step of the [tutorial](https://getstream.io/chat/flutter/tutorial/)
|
||||
///
|
||||
/// Customizing how messages are rendered is another very common use-case that the SDK supports easily.
|
||||
///
|
||||
/// Replace the built-in message component with your own is done by passing it as a builder function to the [MessageListView] widget.
|
||||
///
|
||||
/// The message builder function will get the usual [BuildContext] argument as well as the [Message] object and its position inside the list.
|
||||
///
|
||||
/// If you look at the code you can see that we use [StreamChat.of] to retrieve the current user so that we can style messages own messages in a different way.
|
||||
///
|
||||
/// Since custom widgets and builders are always children of [StreamChat] or part of a [Channel],
|
||||
/// you can use [StreamChat.of], [StreamChannel.of] and [StreamChatTheme.of] to use the API client directly
|
||||
/// or to retrieve outer scope needed such as messages from the [Channel.state].
|
||||
void main() async {
|
||||
final client = Client(
|
||||
'b67pax5b2wdq',
|
||||
logLevel: Level.INFO,
|
||||
);
|
||||
|
||||
await client.setUser(
|
||||
User(id: 'falling-mountain-7'),
|
||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZmFsbGluZy1tb3VudGFpbi03In0.AKgRXHMQQMz6vJAKszXdY8zMFfsAgkoUeZHlI-Szz9E',
|
||||
);
|
||||
|
||||
runApp(MyApp(client));
|
||||
}
|
||||
|
||||
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(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelListPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ChannelsBloc(
|
||||
child: 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(
|
||||
appBar: ChannelHeader(),
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: MessageListView(
|
||||
messageBuilder: _messageBuilder,
|
||||
),
|
||||
),
|
||||
MessageInput(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _messageBuilder(
|
||||
BuildContext context,
|
||||
MessageDetails details,
|
||||
List<Message> messages,
|
||||
) {
|
||||
final message = details.message;
|
||||
final color = details.isMyMessage ? Colors.blueGrey : Colors.blue;
|
||||
return MessageWidget(
|
||||
message: message,
|
||||
messageTheme: details.isMyMessage
|
||||
? StreamChatTheme.of(context).ownMessageTheme
|
||||
: StreamChatTheme.of(context).otherMessageTheme,
|
||||
borderSide: BorderSide(
|
||||
color: color,
|
||||
width: 2,
|
||||
),
|
||||
padding: const EdgeInsets.all(2),
|
||||
attachmentBorderSide: BorderSide(
|
||||
color: color,
|
||||
width: 2,
|
||||
),
|
||||
attachmentPadding: EdgeInsets.all(8),
|
||||
borderRadiusGeometry: BorderRadius.vertical(
|
||||
top: !details.isLastUser ? Radius.circular(16) : Radius.zero,
|
||||
bottom: !details.isNextUser ? Radius.circular(16) : Radius.zero,
|
||||
),
|
||||
showSendingIndicator: DisplayWidget.gone,
|
||||
reverse: false,
|
||||
showUserAvatar:
|
||||
details.isNextUser ? DisplayWidget.hide : DisplayWidget.show,
|
||||
showTimestamp: !details.isNextUser,
|
||||
showUsername: !details.isNextUser,
|
||||
showReactions: false,
|
||||
showReplyIndicator: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ void _initNotifications(Client client) {
|
||||
void main() async {
|
||||
final client = Client(
|
||||
's2dxdhpxd94g',
|
||||
logLevel: Level.SEVERE,
|
||||
logLevel: Level.INFO,
|
||||
showLocalNotification: Platform.isAndroid ? showLocalNotification : null,
|
||||
backgroundKeepAlive: Duration.zero,
|
||||
persistenceEnabled: true,
|
||||
@@ -94,7 +94,7 @@ class MyApp extends StatelessWidget {
|
||||
return MaterialApp(
|
||||
theme: ThemeData.light(),
|
||||
darkTheme: ThemeData.dark(),
|
||||
themeMode: ThemeMode.dark,
|
||||
themeMode: ThemeMode.system,
|
||||
home: Container(
|
||||
child: StreamChat(
|
||||
client: client,
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:stream_chat_flutter/src/attachment_actions.dart';
|
||||
import '../stream_chat_flutter.dart';
|
||||
import 'attachment_error.dart';
|
||||
import 'attachment_title.dart';
|
||||
import 'utils.dart';
|
||||
import 'full_screen_image.dart';
|
||||
|
||||
class GiphyAttachment extends StatelessWidget {
|
||||
final Attachment attachment;
|
||||
@@ -37,39 +37,38 @@ class GiphyAttachment extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
Stack(
|
||||
children: <Widget>[
|
||||
CachedNetworkImage(
|
||||
height: size?.height,
|
||||
width: size?.width,
|
||||
placeholder: (_, __) {
|
||||
return Container(
|
||||
width: size?.width,
|
||||
height: size?.height,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (_) {
|
||||
return FullScreenImage(
|
||||
url: attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl,
|
||||
);
|
||||
}));
|
||||
},
|
||||
imageUrl: attachment.thumbUrl ??
|
||||
attachment.imageUrl ??
|
||||
attachment.assetUrl,
|
||||
errorWidget: (context, url, error) => AttachmentError(
|
||||
attachment: attachment,
|
||||
size: size,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
if (attachment.titleLink != null || attachment.ogScrapeUrl != null)
|
||||
Positioned.fill(
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => launchURL(
|
||||
context,
|
||||
attachment.titleLink ?? attachment.ogScrapeUrl,
|
||||
child: CachedNetworkImage(
|
||||
height: size?.height,
|
||||
width: size?.width,
|
||||
placeholder: (_, __) {
|
||||
return Container(
|
||||
width: size?.width,
|
||||
height: size?.height,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
imageUrl: attachment.thumbUrl ??
|
||||
attachment.imageUrl ??
|
||||
attachment.assetUrl,
|
||||
errorWidget: (context, url, error) => AttachmentError(
|
||||
attachment: attachment,
|
||||
size: size,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (attachment.title != null)
|
||||
|
||||
@@ -74,15 +74,10 @@ class ImageAttachment extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
if (attachment.title != null)
|
||||
Positioned.fill(
|
||||
child: Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Material(
|
||||
child: AttachmentTitle(
|
||||
messageTheme: messageTheme,
|
||||
attachment: attachment,
|
||||
),
|
||||
),
|
||||
Material(
|
||||
child: AttachmentTitle(
|
||||
messageTheme: messageTheme,
|
||||
attachment: attachment,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -23,10 +23,19 @@ typedef ThreadBuilder = Widget Function(BuildContext context, Message parent);
|
||||
typedef ThreadTapCallback = void Function(Message, Widget);
|
||||
|
||||
class MessageDetails {
|
||||
/// True if the message belongs to the current user
|
||||
bool isMyMessage;
|
||||
|
||||
/// True if the user message is the same of the previous message
|
||||
bool isLastUser;
|
||||
|
||||
/// True if the user message is the same of the next message
|
||||
bool isNextUser;
|
||||
|
||||
/// The message
|
||||
Message message;
|
||||
|
||||
/// The index of the message
|
||||
int index;
|
||||
|
||||
MessageDetails(
|
||||
|
||||
@@ -188,9 +188,12 @@ class MessageWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final leftPadding = showUserAvatar != DisplayWidget.gone
|
||||
? messageTheme.avatarTheme.constraints.maxWidth + 22.0
|
||||
var leftPadding = showUserAvatar != DisplayWidget.gone
|
||||
? messageTheme.avatarTheme.constraints.maxWidth + 23.0
|
||||
: 12.0;
|
||||
if (showSendingIndicator == DisplayWidget.gone) {
|
||||
leftPadding -= 7;
|
||||
}
|
||||
return Portal(
|
||||
child: Padding(
|
||||
padding: padding ?? EdgeInsets.all(8),
|
||||
@@ -428,7 +431,7 @@ class MessageWidget extends StatelessWidget {
|
||||
onThreadTap: onThreadTap,
|
||||
showEditMessage: showEditMessage,
|
||||
showReactions: showReactions,
|
||||
showReply: showReplyIndicator,
|
||||
showReply: showReplyIndicator && onThreadTap != null,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
+2
-3
@@ -1,7 +1,7 @@
|
||||
name: stream_chat_flutter
|
||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
||||
version: 0.2.0-alpha+15
|
||||
version: 0.2.1-alpha
|
||||
|
||||
environment:
|
||||
sdk: ">=2.3.0 <3.0.0"
|
||||
@@ -21,8 +21,7 @@ dependencies:
|
||||
file_picker: ^1.9.0+1
|
||||
image_picker: ^0.6.6+1
|
||||
flutter_keyboard_visibility: ^2.0.0
|
||||
stream_chat:
|
||||
path: ../stream_chat_dart
|
||||
stream_chat: ^0.2.0-alpha+9
|
||||
mime: ^0.9.6+3
|
||||
visibility_detector: ^0.1.5
|
||||
http_parser: ^3.1.4
|
||||
|
||||
Reference in New Issue
Block a user