Merge branch 'master' into feature/new-ui
This commit is contained in:
@@ -1,3 +1,27 @@
|
|||||||
|
## 0.2.1+2
|
||||||
|
|
||||||
|
- Update llc dependency
|
||||||
|
|
||||||
|
## 0.2.1+1
|
||||||
|
|
||||||
|
- Update llc dependency
|
||||||
|
|
||||||
|
## 0.2.1
|
||||||
|
|
||||||
|
- Better ui components
|
||||||
|
- Add read indicators
|
||||||
|
- Add system messages
|
||||||
|
- Use llc 0.2
|
||||||
|
- Add `ChannelsBloc` widget to manage a list of channels with pagination
|
||||||
|
|
||||||
|
## 0.2.1-alpha+11
|
||||||
|
|
||||||
|
- Update llc dependency
|
||||||
|
|
||||||
|
## 0.2.1-alpha+10
|
||||||
|
|
||||||
|
- Update llc dependency
|
||||||
|
|
||||||
## 0.2.1-alpha+9
|
## 0.2.1-alpha+9
|
||||||
|
|
||||||
- Add read indicators
|
- Add read indicators
|
||||||
|
|||||||
@@ -33,19 +33,11 @@ The example is available under the [example](https://github.com/GetStream/stream
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
dependencies:
|
dependencies:
|
||||||
stream_chat_flutter: ^0.1.19
|
stream_chat_flutter: ^0.2.1
|
||||||
```
|
```
|
||||||
|
|
||||||
You should then run `flutter packages get`
|
You should then run `flutter packages get`
|
||||||
|
|
||||||
### Alpha version
|
|
||||||
|
|
||||||
Use version `^0.2.0-alpha+2` to use the latest available version.
|
|
||||||
|
|
||||||
Note that this is still an alpha version. There may be some bugs, and the API can change in breaking ways.
|
|
||||||
|
|
||||||
Thanks to whoever tries these versions and reports bugs or suggestions.
|
|
||||||
|
|
||||||
### Android
|
### Android
|
||||||
|
|
||||||
All set ✅
|
All set ✅
|
||||||
@@ -86,6 +78,7 @@ Every widget uses the `StreamChat` or `StreamChannel` widgets to manage the stat
|
|||||||
- [MessageWidget](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/MessageWidget-class.html)
|
- [MessageWidget](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/MessageWidget-class.html)
|
||||||
- [StreamChatTheme](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChatTheme-class.html)
|
- [StreamChatTheme](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChatTheme-class.html)
|
||||||
- [ThreadHeader](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ThreadHeader-class.html)
|
- [ThreadHeader](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ThreadHeader-class.html)
|
||||||
|
- ...
|
||||||
|
|
||||||
### Customizing styles
|
### Customizing styles
|
||||||
|
|
||||||
@@ -109,14 +102,13 @@ Out of the box, all chat widgets use their default styling, and there are two wa
|
|||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: theme,
|
theme: theme,
|
||||||
home: Container(
|
builder: (context, child) => StreamChat(
|
||||||
child: StreamChat(
|
child: child,
|
||||||
streamChatThemeData: StreamChatThemeData.fromTheme(theme),
|
client: client,
|
||||||
client: client,
|
streamChatThemeData: StreamChatThemeData.fromTheme(theme),
|
||||||
child: ChannelListPage(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
home: ChannelListPage(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -136,24 +128,23 @@ Out of the box, all chat widgets use their default styling, and there are two wa
|
|||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: theme,
|
theme: theme,
|
||||||
home: Container(
|
builder: (context, child) => StreamChat(
|
||||||
child: StreamChat(
|
child: child,
|
||||||
streamChatThemeData: StreamChatThemeData.fromTheme(theme).copyWith(
|
client: client,
|
||||||
ownMessageTheme: MessageTheme(
|
streamChatThemeData: StreamChatThemeData.fromTheme(theme).copyWith(
|
||||||
messageBackgroundColor: Colors.black,
|
ownMessageTheme: MessageTheme(
|
||||||
messageText: TextStyle(
|
messageBackgroundColor: Colors.black,
|
||||||
color: Colors.white,
|
messageText: TextStyle(
|
||||||
),
|
color: Colors.white,
|
||||||
avatarTheme: AvatarTheme(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
client: client,
|
avatarTheme: AvatarTheme(
|
||||||
child: ChannelListPage(),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
home: ChannelListPage(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class ChannelListPage extends StatelessWidget {
|
|||||||
filter: {
|
filter: {
|
||||||
'members': {
|
'members': {
|
||||||
'\$in': [StreamChat.of(context).user.id],
|
'\$in': [StreamChat.of(context).user.id],
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
channelPreviewBuilder: _channelPreviewBuilder,
|
channelPreviewBuilder: _channelPreviewBuilder,
|
||||||
sort: [SortOption('last_message_at')],
|
sort: [SortOption('last_message_at')],
|
||||||
@@ -73,17 +73,18 @@ class ChannelListPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _channelPreviewBuilder(BuildContext context, Channel channel) {
|
Widget _channelPreviewBuilder(BuildContext context, Channel channel) {
|
||||||
final lastMessage = channel.state.messages.reversed.firstWhere(
|
final lastMessage = channel.state.messages.reversed
|
||||||
(message) => message.type != 'deleted',
|
.firstWhere((message) => !message.isDeleted);
|
||||||
orElse: () => null,
|
|
||||||
);
|
|
||||||
|
|
||||||
final subtitle = (lastMessage == null ? 'nothing yet' : lastMessage.text);
|
final subtitle = (lastMessage == null ? "nothing yet" : lastMessage.text);
|
||||||
final opacity = channel.state.unreadCount > .0 ? 1.0 : 0.5;
|
final opacity = channel.state.unreadCount > .0 ? 1.0 : 0.5;
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: ChannelImage(),
|
leading: ChannelImage(
|
||||||
|
channel: channel,
|
||||||
|
),
|
||||||
title: ChannelName(
|
title: ChannelName(
|
||||||
|
channel: channel,
|
||||||
textStyle:
|
textStyle:
|
||||||
StreamChatTheme.of(context).channelPreviewTheme.title.copyWith(
|
StreamChatTheme.of(context).channelPreviewTheme.title.copyWith(
|
||||||
color: Colors.black.withOpacity(opacity),
|
color: Colors.black.withOpacity(opacity),
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ class ChannelPage extends StatelessWidget {
|
|||||||
) {
|
) {
|
||||||
final message = details.message;
|
final message = details.message;
|
||||||
final color = details.isMyMessage ? Colors.blueGrey : Colors.blue;
|
final color = details.isMyMessage ? Colors.blueGrey : Colors.blue;
|
||||||
|
if (message.isSystem) {
|
||||||
|
return SizedBox();
|
||||||
|
}
|
||||||
return MessageWidget(
|
return MessageWidget(
|
||||||
message: message,
|
message: message,
|
||||||
messageTheme: details.isMyMessage
|
messageTheme: details.isMyMessage
|
||||||
|
|||||||
@@ -44,9 +44,7 @@ class MyApp extends StatelessWidget {
|
|||||||
client: client,
|
client: client,
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
home: Container(
|
home: ChannelListPage(),
|
||||||
child: ChannelListPage(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,6 +157,9 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.arrow_back_ios,
|
Icons.arrow_back_ios,
|
||||||
size: 15,
|
size: 15,
|
||||||
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? Colors.white
|
||||||
|
: Colors.black,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -172,11 +172,7 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
stream: channel.state.messagesStream,
|
stream: channel.state.messagesStream,
|
||||||
initialData: channel.state.messages,
|
initialData: channel.state.messages,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
final messages = snapshot.data;
|
final lastMessage = channel.state.lastMessage;
|
||||||
final lastMessage = messages?.isNotEmpty == true
|
|
||||||
? messages.lastWhere((m) =>
|
|
||||||
!(m.isDeleted && m.status == MessageSendingStatus.FAILED))
|
|
||||||
: null;
|
|
||||||
if (lastMessage == null) {
|
if (lastMessage == null) {
|
||||||
return SizedBox();
|
return SizedBox();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
final _focusNode = FocusNode();
|
final _focusNode = FocusNode();
|
||||||
final List<User> _mentionedUsers = [];
|
final List<User> _mentionedUsers = [];
|
||||||
|
|
||||||
|
final _imagePicker = ImagePicker();
|
||||||
bool _inputEnabled = true;
|
bool _inputEnabled = true;
|
||||||
bool _messageIsPresent = false;
|
bool _messageIsPresent = false;
|
||||||
bool _typingStarted = false;
|
bool _typingStarted = false;
|
||||||
@@ -721,11 +722,13 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (camera) {
|
if (camera) {
|
||||||
|
PickedFile pickedFile;
|
||||||
if (fileType == DefaultAttachmentTypes.image) {
|
if (fileType == DefaultAttachmentTypes.image) {
|
||||||
file = await ImagePicker.pickImage(source: ImageSource.camera);
|
pickedFile = await _imagePicker.getImage(source: ImageSource.camera);
|
||||||
} else if (fileType == DefaultAttachmentTypes.video) {
|
} else if (fileType == DefaultAttachmentTypes.video) {
|
||||||
file = await ImagePicker.pickVideo(source: ImageSource.camera);
|
pickedFile = await _imagePicker.getVideo(source: ImageSource.camera);
|
||||||
}
|
}
|
||||||
|
file = File(pickedFile.path);
|
||||||
} else {
|
} else {
|
||||||
FileType type;
|
FileType type;
|
||||||
if (fileType == DefaultAttachmentTypes.image) {
|
if (fileType == DefaultAttachmentTypes.image) {
|
||||||
|
|||||||
@@ -424,14 +424,14 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
final isNextUser =
|
final isNextUser =
|
||||||
index - 1 >= 0 && message.user.id == messages[index - 1]?.user?.id;
|
index - 1 >= 0 && message.user.id == messages[index - 1]?.user?.id;
|
||||||
|
|
||||||
var channel = StreamChannel.of(context).channel;
|
final channel = StreamChannel.of(context).channel;
|
||||||
final readList = channel.state.read
|
final readList = channel.state?.read
|
||||||
.where((element) => element.user.id != userId)
|
?.where((element) => element.user.id != userId)
|
||||||
.where((read) =>
|
?.where((read) =>
|
||||||
read.lastRead.isAfter(message.createdAt) &&
|
read.lastRead.isAfter(message.createdAt) &&
|
||||||
(index == 0 ||
|
(index == 0 ||
|
||||||
read.lastRead.isBefore(messages[index - 1].createdAt)))
|
read.lastRead.isBefore(messages[index - 1].createdAt)))
|
||||||
.toList();
|
?.toList();
|
||||||
|
|
||||||
final allRead = readList.length == channel.memberCount - 1;
|
final allRead = readList.length == channel.memberCount - 1;
|
||||||
|
|
||||||
@@ -449,7 +449,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
(index == 0 || message.status != MessageSendingStatus.SENT)
|
(index == 0 || message.status != MessageSendingStatus.SENT)
|
||||||
? DisplayWidget.show
|
? DisplayWidget.show
|
||||||
: DisplayWidget.hide,
|
: DisplayWidget.hide,
|
||||||
showTimestamp: !isNextUser || readList.isNotEmpty,
|
showTimestamp: !isNextUser || readList?.isNotEmpty == true,
|
||||||
showEditMessage: isMyMessage,
|
showEditMessage: isMyMessage,
|
||||||
showDeleteMessage: isMyMessage,
|
showDeleteMessage: isMyMessage,
|
||||||
borderSide: isMyMessage ? BorderSide.none : null,
|
borderSide: isMyMessage ? BorderSide.none : null,
|
||||||
|
|||||||
+9
-7
@@ -1,7 +1,9 @@
|
|||||||
name: stream_chat_flutter
|
name: stream_chat_flutter
|
||||||
homepage: https://github.com/GetStream/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.
|
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
||||||
version: 0.2.1-alpha+9
|
version: 0.2.1+2
|
||||||
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.3.0 <3.0.0"
|
sdk: ">=2.3.0 <3.0.0"
|
||||||
@@ -14,14 +16,14 @@ dependencies:
|
|||||||
jiffy: ^3.0.1
|
jiffy: ^3.0.1
|
||||||
flutter_portal: ^0.1.0
|
flutter_portal: ^0.1.0
|
||||||
cached_network_image: ^2.2.0+1
|
cached_network_image: ^2.2.0+1
|
||||||
flutter_markdown: ^0.4.1
|
flutter_markdown: ^0.4.2
|
||||||
url_launcher: ^5.4.10
|
url_launcher: ^5.4.11
|
||||||
video_player: ^0.10.11+1
|
video_player: ^0.10.11+1
|
||||||
chewie: ^0.9.10
|
chewie: ^0.9.10
|
||||||
file_picker: ^1.9.0+1
|
file_picker: ^1.12.0
|
||||||
image_picker: ^0.6.7
|
image_picker: ^0.6.7+2
|
||||||
flutter_keyboard_visibility: ^3.0.0
|
flutter_keyboard_visibility: ^3.2.1
|
||||||
stream_chat: ^0.2.0-alpha+20
|
stream_chat: ^0.2.0+2
|
||||||
mime: ^0.9.6+3
|
mime: ^0.9.6+3
|
||||||
visibility_detector: ^0.1.5
|
visibility_detector: ^0.1.5
|
||||||
line_awesome_icons: ^1.0.4+2
|
line_awesome_icons: ^1.0.4+2
|
||||||
|
|||||||
Reference in New Issue
Block a user