Merge remote-tracking branch 'origin/develop' into feat/localization

# Conflicts:
#	packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart
#	packages/stream_chat_flutter/lib/src/channel_name.dart
#	packages/stream_chat_flutter/lib/src/message_search_item.dart
#	packages/stream_chat_flutter/lib/src/message_widget.dart
This commit is contained in:
xsahil03x
2021-07-28 15:18:09 +05:30
67 changed files with 723 additions and 252 deletions
+6
View File
@@ -1,8 +1,14 @@
## Upcoming ## Upcoming
🔄 Changed
- `client.user` is now deprecated in favor of `client.currentUser`.
- `client.userStream` is now deprecated in favor of `client.currentUserStream`.
🐞 Fixed 🐞 Fixed
- [#563](https://github.com/GetStream/stream-chat-flutter/issues/563): `Channel.stopWatching()` not working - [#563](https://github.com/GetStream/stream-chat-flutter/issues/563): `Channel.stopWatching()` not working
- [#575](https://github.com/GetStream/stream-chat-flutter/issues/575): Wrong `OwnUser.*`
## 2.0.0 ## 2.0.0
+1 -1
View File
@@ -245,5 +245,5 @@ class _MessageViewState extends State<MessageView> {
/// Helper extension for quickly retrieving /// Helper extension for quickly retrieving
/// the current user id from a [StreamChatClient]. /// the current user id from a [StreamChatClient].
extension on StreamChatClient { extension on StreamChatClient {
String get uid => state.user!.id; String get uid => state.currentUser!.id;
} }
@@ -65,12 +65,12 @@ class Channel {
/// Returns true if the channel is muted /// Returns true if the channel is muted
bool get isMuted => bool get isMuted =>
_client.state.user?.channelMutes _client.state.currentUser?.channelMutes
.any((element) => element.channel.cid == cid) == .any((element) => element.channel.cid == cid) ==
true; true;
/// Returns true if the channel is muted as a stream /// Returns true if the channel is muted as a stream
Stream<bool>? get isMutedStream => _client.state.userStream Stream<bool>? get isMutedStream => _client.state.currentUserStream
.map((event) => .map((event) =>
event!.channelMutes.any((element) => element.channel.cid == cid) == event!.channelMutes.any((element) => element.channel.cid == cid) ==
true) true)
@@ -382,7 +382,7 @@ class Channel {
// ignore: parameter_assignments // ignore: parameter_assignments
message = message.copyWith( message = message.copyWith(
createdAt: message.createdAt, createdAt: message.createdAt,
user: _client.state.user, user: _client.state.currentUser,
quotedMessage: quotedMessage, quotedMessage: quotedMessage,
status: MessageSendingStatus.sending, status: MessageSendingStatus.sending,
attachments: message.attachments.map( attachments: message.attachments.map(
@@ -693,7 +693,7 @@ class Channel {
_checkInitialized(); _checkInitialized();
final messageId = message.id; final messageId = message.id;
final now = DateTime.now(); final now = DateTime.now();
final user = _client.state.user; final user = _client.state.currentUser;
final latestReactions = [...message.latestReactions ?? <Reaction>[]]; final latestReactions = [...message.latestReactions ?? <Reaction>[]];
if (enforceUnique) { if (enforceUnique) {
@@ -750,7 +750,7 @@ class Channel {
Future<EmptyResponse> deleteReaction( Future<EmptyResponse> deleteReaction(
Message message, Reaction reaction) async { Message message, Reaction reaction) async {
final type = reaction.type; final type = reaction.type;
final user = _client.state.user; final user = _client.state.currentUser;
final reactionCounts = {...message.reactionCounts ?? <String, int>{}}; final reactionCounts = {...message.reactionCounts ?? <String, int>{}};
if (reactionCounts.containsKey(type)) { if (reactionCounts.containsKey(type)) {
@@ -1314,7 +1314,7 @@ class ChannelClientState {
void _computeInitialUnread() { void _computeInitialUnread() {
final userRead = channelState.read.firstWhereOrNull( final userRead = channelState.read.firstWhereOrNull(
(r) => r.user.id == _channel._client.state.user?.id, (r) => r.user.id == _channel._client.state.currentUser?.id,
); );
if (userRead != null) { if (userRead != null) {
unreadCount = userRead.unreadMessages; unreadCount = userRead.unreadMessages;
@@ -1431,7 +1431,7 @@ class ChannelClientState {
void _listenReactionDeleted() { void _listenReactionDeleted() {
_subscriptions.add(_channel.on(EventType.reactionDeleted).listen((event) { _subscriptions.add(_channel.on(EventType.reactionDeleted).listen((event) {
final userId = _channel.client.state.user!.id; final userId = _channel.client.state.currentUser!.id;
final message = event.message!.copyWith( final message = event.message!.copyWith(
ownReactions: [...event.message!.latestReactions!] ownReactions: [...event.message!.latestReactions!]
..removeWhere((it) => it.userId != userId), ..removeWhere((it) => it.userId != userId),
@@ -1442,7 +1442,7 @@ class ChannelClientState {
void _listenReactions() { void _listenReactions() {
_subscriptions.add(_channel.on(EventType.reactionNew).listen((event) { _subscriptions.add(_channel.on(EventType.reactionNew).listen((event) {
final userId = _channel.client.state.user!.id; final userId = _channel.client.state.currentUser!.id;
final message = event.message!.copyWith( final message = event.message!.copyWith(
ownReactions: [...event.message!.latestReactions!] ownReactions: [...event.message!.latestReactions!]
..removeWhere((it) => it.userId != userId), ..removeWhere((it) => it.userId != userId),
@@ -1458,7 +1458,7 @@ class ChannelClientState {
EventType.reactionUpdated, EventType.reactionUpdated,
) )
.listen((event) { .listen((event) {
final userId = _channel.client.state.user!.id; final userId = _channel.client.state.currentUser!.id;
final message = event.message!.copyWith( final message = event.message!.copyWith(
ownReactions: [...event.message!.latestReactions!] ownReactions: [...event.message!.latestReactions!]
..removeWhere((it) => it.userId != userId), ..removeWhere((it) => it.userId != userId),
@@ -1552,7 +1552,7 @@ class ChannelClientState {
if (userReadIndex != null && userReadIndex != -1) { if (userReadIndex != null && userReadIndex != -1) {
final userRead = readList.removeAt(userReadIndex); final userRead = readList.removeAt(userReadIndex);
if (userRead.user.id == _channel._client.state.user!.id) { if (userRead.user.id == _channel._client.state.currentUser!.id) {
unreadCount = 0; unreadCount = 0;
} }
readList.add(Read( readList.add(Read(
@@ -1642,11 +1642,12 @@ class ChannelClientState {
int get unreadCount => _unreadCountController.value; int get unreadCount => _unreadCountController.value;
bool _countMessageAsUnread(Message message) { bool _countMessageAsUnread(Message message) {
final userId = _channel.client.state.user?.id; final userId = _channel.client.state.currentUser?.id;
final userIsMuted = _channel.client.state.user?.mutes.firstWhereOrNull( final userIsMuted =
(m) => m.user.id == message.user?.id, _channel.client.state.currentUser?.mutes.firstWhereOrNull(
) != (m) => m.user.id == message.user?.id,
null; ) !=
null;
return message.silent != true && return message.silent != true &&
message.shadowed != true && message.shadowed != true &&
message.user?.id != userId && message.user?.id != userId &&
@@ -1795,7 +1796,7 @@ class ChannelClientState {
(event) { (event) {
if (event.user != null) { if (event.user != null) {
final user = event.user!; final user = event.user!;
if (user.id != _channel.client.state.user?.id) { if (user.id != _channel.client.state.currentUser?.id) {
_typings[user] = event; _typings[user] = event;
_typingEventsController.add(_typings); _typingEventsController.add(_typings);
} }
@@ -1808,7 +1809,7 @@ class ChannelClientState {
(event) { (event) {
if (event.user != null) { if (event.user != null) {
final user = event.user!; final user = event.user!;
if (user.id != _channel.client.state.user?.id) { if (user.id != _channel.client.state.currentUser?.id) {
_typings.remove(event.user); _typings.remove(event.user);
_typingEventsController.add(_typings); _typingEventsController.add(_typings);
} }
+31 -17
View File
@@ -316,7 +316,7 @@ class StreamChatClient {
); );
final ownUser = OwnUser.fromUser(user); final ownUser = OwnUser.fromUser(user);
state.user = ownUser; state.currentUser = ownUser;
if (!connectWebSocket) { if (!connectWebSocket) {
return ownUser; return ownUser;
@@ -332,7 +332,7 @@ class StreamChatClient {
} catch (e, stk) { } catch (e, stk) {
if (e is StreamWebSocketError && e.isRetriable) { if (e is StreamWebSocketError && e.isRetriable) {
final event = await _chatPersistenceClient?.getConnectionInfo(); final event = await _chatPersistenceClient?.getConnectionInfo();
if (event != null) return event.me?.merge(ownUser) ?? ownUser; if (event != null) return ownUser.merge(event.me);
} }
logger.severe('error connecting user : ${ownUser.id}', e, stk); logger.severe('error connecting user : ${ownUser.id}', e, stk);
rethrow; rethrow;
@@ -342,12 +342,12 @@ class StreamChatClient {
/// Creates a new WebSocket connection with the current user. /// Creates a new WebSocket connection with the current user.
Future<OwnUser> openConnection() async { Future<OwnUser> openConnection() async {
assert( assert(
state.user != null, state.currentUser != null,
'User is not set on client, ' 'User is not set on client, '
'use `connectUser` or `connectAnonymousUser` instead', 'use `connectUser` or `connectAnonymousUser` instead',
); );
final user = state.user!; final user = state.currentUser!;
logger.info('Opening web-socket connection for ${user.id}'); logger.info('Opening web-socket connection for ${user.id}');
@@ -371,7 +371,7 @@ class StreamChatClient {
try { try {
final event = await _ws.connect(user); final event = await _ws.connect(user);
return event.me?.merge(user) ?? user; return user.merge(event.me);
} catch (e, stk) { } catch (e, stk) {
logger.severe('error connecting ws', e, stk); logger.severe('error connecting ws', e, stk);
rethrow; rethrow;
@@ -386,7 +386,7 @@ class StreamChatClient {
void closeConnection() { void closeConnection() {
if (wsConnectionStatus == ConnectionStatus.disconnected) return; if (wsConnectionStatus == ConnectionStatus.disconnected) return;
logger.info('Closing web-socket connection for ${state.user?.id}'); logger.info('Closing web-socket connection for ${state.currentUser?.id}');
_wsConnectionStatus = ConnectionStatus.disconnected; _wsConnectionStatus = ConnectionStatus.disconnected;
_connectionStatusSubscription?.cancel(); _connectionStatusSubscription?.cancel();
@@ -397,7 +397,7 @@ class StreamChatClient {
void _handleHealthCheckEvent(Event event) { void _handleHealthCheckEvent(Event event) {
final user = event.me; final user = event.me;
if (user != null) state.user = user; if (user != null) state.currentUser = user;
final connectionId = event.connectionId; final connectionId = event.connectionId;
if (connectionId != null) { if (connectionId != null) {
@@ -1298,7 +1298,7 @@ class StreamChatClient {
/// If [flushChatPersistence] is true the client deletes all offline /// If [flushChatPersistence] is true the client deletes all offline
/// user's data. /// user's data.
Future<void> disconnectUser({bool flushChatPersistence = false}) async { Future<void> disconnectUser({bool flushChatPersistence = false}) async {
logger.info('Disconnecting user : ${state.user?.id}'); logger.info('Disconnecting user : ${state.currentUser?.id}');
// resetting state // resetting state
state.dispose(); state.dispose();
@@ -1344,7 +1344,7 @@ class ClientState {
.where((event) => event.me != null) .where((event) => event.me != null)
.map((e) => e.me) .map((e) => e.me)
.listen((user) { .listen((user) {
_userController.add(user); _currentUserController.add(user);
final totalUnreadCount = user?.totalUnreadCount; final totalUnreadCount = user?.totalUnreadCount;
if (totalUnreadCount != null) { if (totalUnreadCount != null) {
_totalUnreadCountController.add(totalUnreadCount); _totalUnreadCountController.add(totalUnreadCount);
@@ -1394,8 +1394,8 @@ class ClientState {
void _listenUserUpdated() { void _listenUserUpdated() {
_subscriptions.add(_client.on(EventType.userUpdated).listen((event) { _subscriptions.add(_client.on(EventType.userUpdated).listen((event) {
if (event.user!.id == user!.id) { if (event.user!.id == currentUser!.id) {
user = OwnUser.fromJson(event.user!.toJson()); currentUser = OwnUser.fromJson(event.user!.toJson());
} }
updateUser(event.user); updateUser(event.user);
})); }));
@@ -1418,8 +1418,8 @@ class ClientState {
final StreamChatClient _client; final StreamChatClient _client;
/// Update user information /// Update user information
set user(OwnUser? user) { set currentUser(OwnUser? user) {
_userController.add(user); _currentUserController.add(user);
} }
/// Update all the [users] with the provided [userList] /// Update all the [users] with the provided [userList]
@@ -1436,10 +1436,24 @@ class ClientState {
void updateUser(User? user) => updateUsers([user]); void updateUser(User? user) => updateUsers([user]);
/// The current user /// The current user
OwnUser? get user => _userController.valueOrNull; OwnUser? get currentUser => _currentUserController.valueOrNull;
/// The current user as a stream /// The current user as a stream
Stream<OwnUser?> get userStream => _userController.stream; Stream<OwnUser?> get currentUserStream => _currentUserController.stream;
// coverage:ignore-start
/// The current user
@Deprecated('Use `.currentUser` instead, Will be removed in future releases')
OwnUser? get user => _currentUserController.valueOrNull;
/// The current user as a stream
@Deprecated(
'Use `.currentUserStream` instead, Will be removed in future releases',
)
Stream<OwnUser?> get userStream => _currentUserController.stream;
// coverage:ignore-end
/// The current user /// The current user
Map<String, User> get users => _usersController.value; Map<String, User> get users => _usersController.value;
@@ -1471,7 +1485,7 @@ class ClientState {
} }
final _channelsController = BehaviorSubject<Map<String, Channel>>.seeded({}); final _channelsController = BehaviorSubject<Map<String, Channel>>.seeded({});
final _userController = BehaviorSubject<OwnUser?>(); final _currentUserController = BehaviorSubject<OwnUser?>();
final _usersController = BehaviorSubject<Map<String, User>>.seeded({}); final _usersController = BehaviorSubject<Map<String, User>>.seeded({});
final _unreadChannelsController = BehaviorSubject<int>.seeded(0); final _unreadChannelsController = BehaviorSubject<int>.seeded(0);
final _totalUnreadCountController = BehaviorSubject<int>.seeded(0); final _totalUnreadCountController = BehaviorSubject<int>.seeded(0);
@@ -1479,7 +1493,7 @@ class ClientState {
/// Call this method to dispose this object /// Call this method to dispose this object
void dispose() { void dispose() {
_subscriptions.forEach((s) => s.cancel()); _subscriptions.forEach((s) => s.cancel());
_userController.close(); _currentUserController.close();
_unreadChannelsController.close(); _unreadChannelsController.close();
_totalUnreadCountController.close(); _totalUnreadCountController.close();
channels.values.forEach((c) => c.dispose()); channels.values.forEach((c) => c.dispose());
@@ -155,7 +155,7 @@ void main() {
group('`.openConnection`', () { group('`.openConnection`', () {
test('should throw if state does not contain user', () async { test('should throw if state does not contain user', () async {
expect(client.state.user, isNull); expect(client.state.currentUser, isNull);
try { try {
await client.openConnection(); await client.openConnection();
} catch (e) { } catch (e) {
@@ -164,7 +164,7 @@ void main() {
}); });
test('should throw if connection is already in progress', () async { test('should throw if connection is already in progress', () async {
expect(client.state.user, isNull); expect(client.state.currentUser, isNull);
try { try {
await client.connectAnonymousUser(); await client.connectAnonymousUser();
await client.openConnection(); await client.openConnection();
@@ -179,7 +179,7 @@ void main() {
}); });
test('should throw if connection is already available', () async { test('should throw if connection is already available', () async {
expect(client.state.user, isNull); expect(client.state.currentUser, isNull);
try { try {
await client.connectAnonymousUser(); await client.connectAnonymousUser();
// waiting 300ms for `wsConnectionStatusStream` to emit // waiting 300ms for `wsConnectionStatusStream` to emit
@@ -799,7 +799,7 @@ void main() {
}); });
test('`.disconnectUser` should reset state and user', () async { test('`.disconnectUser` should reset state and user', () async {
expect(client.state.user, isNotNull); expect(client.state.currentUser, isNotNull);
expect(client.wsConnectionStatus, ConnectionStatus.connected); expect(client.wsConnectionStatus, ConnectionStatus.connected);
expectLater( expectLater(
@@ -810,7 +810,7 @@ void main() {
await client.disconnectUser(); await client.disconnectUser();
expect(client.state.user, isNull); expect(client.state.currentUser, isNull);
expect(client.wsConnectionStatus, ConnectionStatus.disconnected); expect(client.wsConnectionStatus, ConnectionStatus.disconnected);
}); });
}); });
+1 -1
View File
@@ -89,7 +89,7 @@ class FakeChatApi extends Fake implements StreamChatApi {
class FakeClientState extends Fake implements ClientState { class FakeClientState extends Fake implements ClientState {
@override @override
OwnUser? get user => OwnUser(id: 'test-user-id'); OwnUser? get currentUser => OwnUser(id: 'test-user-id');
@override @override
int totalUnreadCount = 0; int totalUnreadCount = 0;
@@ -4,6 +4,12 @@
- Added `MessageListView.paginationLimit` - Added `MessageListView.paginationLimit`
- Allow the various ListView widgets to be themed via ThemeData classes - Allow the various ListView widgets to be themed via ThemeData classes
- Added `bottomRowBuilder` and `deletedBottomRowBuilder` that build a widget below a `MessageWidget`
🔄 Changed
- `StreamChat.of(context).user` is now deprecated in favor of `StreamChat.of(context).currentUser`.
- `StreamChat.of(context).userStream` is now deprecated in favor of `StreamChat.of(context).currentUserStream`.
🐞 Fixed 🐞 Fixed
@@ -103,7 +103,7 @@ class ChannelListPage extends StatelessWidget {
: null, : null,
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user!.id], [StreamChat.of(context).currentUser!.id],
), ),
sort: const [SortOption('last_message_at')], sort: const [SortOption('last_message_at')],
pagination: const PaginationParams( pagination: const PaginationParams(
@@ -80,7 +80,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user!.id], [StreamChat.of(context).currentUser!.id],
), ),
sort: const [SortOption('last_message_at')], sort: const [SortOption('last_message_at')],
pagination: const PaginationParams( pagination: const PaginationParams(
@@ -81,7 +81,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user!.id], [StreamChat.of(context).currentUser!.id],
), ),
channelPreviewBuilder: _channelPreviewBuilder, channelPreviewBuilder: _channelPreviewBuilder,
// sort: [SortOption('last_message_at')], // sort: [SortOption('last_message_at')],
@@ -66,7 +66,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user!.id], [StreamChat.of(context).currentUser!.id],
), ),
sort: const [SortOption('last_message_at')], sort: const [SortOption('last_message_at')],
pagination: const PaginationParams( pagination: const PaginationParams(
@@ -72,7 +72,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user!.id], [StreamChat.of(context).currentUser!.id],
), ),
sort: const [SortOption('last_message_at')], sort: const [SortOption('last_message_at')],
pagination: const PaginationParams( pagination: const PaginationParams(
@@ -115,7 +115,8 @@ class ChannelPage extends StatelessWidget {
MessageWidget _, MessageWidget _,
) { ) {
final message = details.message; final message = details.message;
final isCurrentUser = StreamChat.of(context).user!.id == message.user!.id; final isCurrentUser =
StreamChat.of(context).currentUser!.id == message.user!.id;
final textAlign = isCurrentUser ? TextAlign.right : TextAlign.left; final textAlign = isCurrentUser ? TextAlign.right : TextAlign.left;
final color = isCurrentUser ? Colors.blueGrey : Colors.blue; final color = isCurrentUser ? Colors.blueGrey : Colors.blue;
@@ -99,7 +99,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user!.id], [StreamChat.of(context).currentUser!.id],
), ),
sort: const [SortOption('last_message_at')], sort: const [SortOption('last_message_at')],
pagination: const PaginationParams( pagination: const PaginationParams(
@@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart'; import 'package:shimmer/shimmer.dart';
import 'package:stream_chat_flutter/src/attachment/attachment_widget.dart'; import 'package:stream_chat_flutter/src/attachment/attachment_widget.dart';
import 'package:stream_chat_flutter/src/visible_footnote.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
import 'package:stream_chat_flutter/src/extension.dart'; import 'package:stream_chat_flutter/src/extension.dart';
@@ -217,36 +218,11 @@ class GiphyAttachment extends AttachmentWidget {
), ),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Align( const Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row( child: VisibleFootnote(),
mainAxisSize: MainAxisSize.min,
children: [
StreamSvgIcon.eye(
color: StreamChatTheme.of(context)
.colorTheme
.textHighEmphasis
.withOpacity(0.5),
size: 16,
),
const SizedBox(
width: 8,
),
Text(
context.translations.onlyVisibleToYouText,
style: StreamChatTheme.of(context)
.textTheme
.footnote
.copyWith(
color: StreamChatTheme.of(context)
.colorTheme
.textHighEmphasis
.withOpacity(0.5)),
),
],
),
), ),
), ),
], ],
@@ -139,7 +139,8 @@ class AttachmentActionsModal extends StatelessWidget {
); );
}, },
), ),
if (StreamChat.of(context).user?.id == message.user?.id) if (StreamChat.of(context).currentUser?.id ==
message.user?.id)
_buildButton( _buildButton(
context, context,
context.translations.deleteLabel.capitalize(), context.translations.deleteLabel.capitalize(),
@@ -141,7 +141,7 @@ class ChannelAvatar extends StatelessWidget {
return child; return child;
} }
final currentUser = streamChat.user!; final currentUser = streamChat.currentUser!;
final otherMembers = channel.state!.members final otherMembers = channel.state!.members
.where((it) => it.userId != currentUser.id) .where((it) => it.userId != currentUser.id)
.toList(growable: false); .toList(growable: false);
@@ -149,7 +149,7 @@ class ChannelAvatar extends StatelessWidget {
// our own space, no other members // our own space, no other members
if (otherMembers.isEmpty) { if (otherMembers.isEmpty) {
return BetterStreamBuilder<User>( return BetterStreamBuilder<User>(
stream: streamChat.client.state.userStream.map((it) => it!), stream: streamChat.client.state.currentUserStream.map((it) => it!),
initialData: currentUser, initialData: currentUser,
builder: (context, user) => UserAvatar( builder: (context, user) => UserAvatar(
borderRadius: borderRadius ?? previewTheme?.borderRadius, borderRadius: borderRadius ?? previewTheme?.borderRadius,
@@ -28,8 +28,8 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
final members = channel.state?.members ?? []; final members = channel.state?.members ?? [];
final userAsMember = final userAsMember = members
members.firstWhere((e) => e.user?.id == _streamChatState.user?.id); .firstWhere((e) => e.user?.id == _streamChatState.currentUser?.id);
final isOwner = userAsMember.role == 'owner'; final isOwner = userAsMember.role == 'owner';
return Material( return Material(
@@ -248,7 +248,7 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
); );
if (res == true) { if (res == true) {
final channel = _streamChannelState.channel; final channel = _streamChannelState.channel;
final user = _streamChatState.user; final user = _streamChatState.currentUser;
if (user != null) { if (user != null) {
await channel.removeMembers([user.id]); await channel.removeMembers([user.id]);
} }
@@ -71,7 +71,7 @@ class ChannelInfo extends StatelessWidget {
.subtitle, .subtitle,
); );
} else { } else {
final userId = StreamChat.of(context).user?.id; final userId = StreamChat.of(context).currentUser?.id;
final otherMember = members?.firstWhereOrNull( final otherMember = members?.firstWhereOrNull(
(element) => element.userId != userId, (element) => element.userId != userId,
); );
@@ -96,7 +96,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _client = client ?? StreamChat.of(context).client; final _client = client ?? StreamChat.of(context).client;
final user = _client.state.user; final user = _client.state.currentUser;
return ConnectionStatusBuilder( return ConnectionStatusBuilder(
statusBuilder: (context, status) { statusBuilder: (context, status) {
var statusString = ''; var statusString = '';
@@ -553,7 +553,7 @@ class _ChannelListViewState extends State<ChannelListView> {
'owner', 'owner',
].contains(channel.state!.members ].contains(channel.state!.members
.firstWhereOrNull( .firstWhereOrNull(
(m) => m.userId == channel.client.state.user?.id) (m) => m.userId == channel.client.state.currentUser?.id)
?.role)) ?.role))
IconSlideAction( IconSlideAction(
color: backgroundColor, color: backgroundColor,
@@ -49,8 +49,8 @@ class ChannelName extends StatelessWidget {
if (extraData['name'] != null) { if (extraData['name'] != null) {
title = extraData['name']; title = extraData['name'];
} else { } else {
final otherMembers = final otherMembers = members
members?.where((member) => member.userId != client.user!.id); ?.where((member) => member.userId != client.currentUser!.id);
if (otherMembers?.length == 1) { if (otherMembers?.length == 1) {
if (otherMembers!.first.user != null) { if (otherMembers!.first.user != null) {
title = otherMembers.first.user!.name; title = otherMembers.first.user!.name;
@@ -102,7 +102,7 @@ class ChannelPreview extends StatelessWidget {
if (members?.isEmpty == true || if (members?.isEmpty == true ||
members?.any((Member e) => members?.any((Member e) =>
e.user!.id == e.user!.id ==
channel.client.state.user?.id) != channel.client.state.currentUser?.id) !=
true) { true) {
return const SizedBox(); return const SizedBox();
} }
@@ -125,7 +125,7 @@ class ChannelPreview extends StatelessWidget {
(m) => !m.isDeleted && m.shadowed != true, (m) => !m.isDeleted && m.shadowed != true,
); );
if (lastMessage?.user?.id == if (lastMessage?.user?.id ==
streamChatState.user?.id) { streamChatState.currentUser?.id) {
return Padding( return Padding(
padding: const EdgeInsets.only(right: 4), padding: const EdgeInsets.only(right: 4),
child: SendingIndicator( child: SendingIndicator(
@@ -134,7 +134,8 @@ class ChannelPreview extends StatelessWidget {
isMessageRead: channel.state!.read isMessageRead: channel.state!.read
?.where((element) => ?.where((element) =>
element.user.id != element.user.id !=
channel.client.state.user!.id) channel
.client.state.currentUser!.id)
.where((element) => element.lastRead .where((element) => element.lastRead
.isAfter(lastMessage.createdAt)) .isAfter(lastMessage.createdAt))
.isNotEmpty == .isNotEmpty ==
@@ -0,0 +1,258 @@
import 'dart:math';
import 'dart:ui';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
/// Fallback user avatar with a polygon gradient overlayed with text
class GradientAvatar extends StatefulWidget {
/// Constructor for [GradientAvatar]
const GradientAvatar({
Key? key,
required this.name,
required this.userId,
}) : super(key: key);
/// Name of user to shorten and display
final String name;
/// ID of user to be used for key
final String userId;
@override
_GradientAvatarState createState() => _GradientAvatarState();
}
class _GradientAvatarState extends State<GradientAvatar> {
@override
Widget build(BuildContext context) => Center(
child: RepaintBoundary(
child: CustomPaint(
painter: DemoPainter(
widget.userId,
getShortenedName(widget.name),
DefaultTextStyle.of(context).style.fontFamily ?? 'Roboto',
),
child: const SizedBox.expand(),
),
),
);
String getShortenedName(String name) {
var parts = name.split(' ')..removeWhere((e) => e == '');
if (parts.length > 2) {
parts = parts.take(2).toList();
}
var result = '';
for (var i = 0; i < parts.length; i++) {
result = result + parts[i][0].toUpperCase();
}
return result;
}
}
/// Painter for bg polygon gradient
class DemoPainter extends CustomPainter {
/// Constructor for [DemoPainter]
DemoPainter(
this.userId,
this.username,
this.fontFamily,
);
/// Init grid row count
static const int rowCount = 5;
/// Init grid column count
static const int columnCount = 5;
/// User ID used for key
String userId;
/// User name to display
String username;
/// Font family to use
String fontFamily;
@override
void paint(Canvas canvas, Size size) {
final rowUnit = size.width / columnCount;
final columnUnit = size.height / rowCount;
final rand = Random(userId.length);
final squares = <Offset4>[];
final points = <Offset>{};
final gradient = colorGradients[rand.nextInt(colorGradients.length)];
for (var i = 0; i < rowCount; i++) {
for (var j = 0; j < columnCount; j++) {
final off1 = Offset(rowUnit * j, columnUnit * i);
final off2 = Offset(rowUnit * (j + 1), columnUnit * i);
final off3 = Offset(rowUnit * (j + 1), columnUnit * (i + 1));
final off4 = Offset(rowUnit * j, columnUnit * (i + 1));
points.addAll([off1, off2, off3, off4]);
final pointsList = points.toList();
final p1 = pointsList.indexOf(off1);
final p2 = pointsList.indexOf(off2);
final p3 = pointsList.indexOf(off3);
final p4 = pointsList.indexOf(off4);
squares.add(
Offset4(p1, p2, p3, p4, i, j, rowCount, columnCount, gradient));
}
}
final list = transformPoints(points, size);
squares.forEach((e) => e.draw(canvas, list));
final smallerSide = size.width > size.height ? size.width : size.height;
final textSize = smallerSide / 3;
final dxShift = (username.length == 2 ? 1.45 : 0.9) * textSize / 2;
final dyShift = (username.length == 2 ? 1.0 : 1.65) * textSize / 2;
final fontSize = username.length == 2 ? textSize : textSize * 1.5;
TextPainter(
text: TextSpan(
text: username,
style: TextStyle(
fontFamily: fontFamily,
fontSize: fontSize,
fontWeight: FontWeight.w500,
color: Colors.white.withOpacity(0.7),
),
),
textAlign: TextAlign.center,
textDirection: TextDirection.ltr)
..layout(maxWidth: size.width)
..paint(
canvas,
Offset(
(size.width / 2) - dxShift,
(size.height / 2) - dyShift,
),
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
/// Transforms initial grid into a polygon grid
List<Offset> transformPoints(Set<Offset> points, Size size) {
final transformedList = <Offset>[];
final orgList = points.toList();
final rand = Random(userId.length);
for (var i = 0; i < points.length; i++) {
final orgDx = orgList[i].dx;
final orgDy = orgList[i].dy;
if (orgDx == 0 ||
orgDy == 0 ||
orgDx == size.width ||
orgDy == size.height) {
transformedList.add(Offset(orgDx, orgDy));
continue;
}
final sign1 = rand.nextInt(2) == 1 ? 1 : -1;
final sign2 = rand.nextInt(2) == 1 ? 1 : -1;
final dx = 0.6 * sign1 * rand.nextInt(size.width ~/ columnCount);
final dy = 0.6 * sign2 * rand.nextInt(size.height ~/ rowCount);
transformedList.add(Offset(orgDx + dx, orgDy + dy));
}
return transformedList;
}
}
/// Class for storing and drawing four points of a polygon
class Offset4 {
/// Constructor for [Offset4]
Offset4(
this.p1,
this.p2,
this.p3,
this.p4,
this.row,
this.column,
this.rowSize,
this.colSize,
this.gradient,
);
/// Point 1
int p1;
/// Point 2
int p2;
/// Point 3
int p3;
/// Point 4
int p4;
/// Position of polygon on grid
int row;
/// Position of polygon on grid
int column;
/// Max row size
int rowSize;
/// Max col size
int colSize;
/// Gradient to be applied to polygon
List<Color> gradient;
/// Draw the polygon on canvas
void draw(Canvas canvas, List<Offset> points) {
final paint = Paint()
..color = Color.fromARGB(255, Random().nextInt(255),
Random().nextInt(255), Random().nextInt(255))
..shader = ui.Gradient.linear(
points[p1],
points[p3],
gradient,
);
final backgroundPath = Path()
..moveTo(points[p1].dx, points[p1].dy)
..lineTo(points[p2].dx, points[p2].dy)
..lineTo(points[p3].dx, points[p3].dy)
..lineTo(points[p4].dx, points[p4].dy)
..lineTo(points[p1].dx, points[p1].dy)
..close();
canvas.drawPath(backgroundPath, paint);
}
}
/// Gradient list for polygons
const colorGradients = [
[Color(0xffffafbd), Color(0xffffc3a0)],
[Color(0xff2193b0), Color(0xff6dd5ed)],
[Color(0xffcc2b5e), Color(0xff753a88)],
[Color(0xffee9ca7), Color(0xffffdde1)],
[Color(0xff42275a), Color(0xff734b6d)],
[Color(0xffde6262), Color(0xffffb88c)],
[Color(0xff56ab2f), Color(0xffa8e063)],
[Color(0xff614385), Color(0xff516395)],
[Color(0xffeacda3), Color(0xffd6ae7b)],
[Color(0xff02aab0), Color(0xff00cdac)],
];
@@ -101,7 +101,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
Widget _showMessageOptionsModal() { Widget _showMessageOptionsModal() {
final mediaQueryData = MediaQuery.of(context); final mediaQueryData = MediaQuery.of(context);
final size = mediaQueryData.size; final size = mediaQueryData.size;
final user = StreamChat.of(context).user; final user = StreamChat.of(context).currentUser;
final roughMaxSize = 2 * size.width / 3; final roughMaxSize = 2 * size.width / 3;
var messageTextLength = widget.message.text!.length; var messageTextLength = widget.message.text!.length;
@@ -704,7 +704,8 @@ class _MessageListViewState extends State<MessageListView> {
final unreadCount = snapshot.data!.item2; final unreadCount = snapshot.data!.item2;
final showUnreadCount = unreadCount > 0 && final showUnreadCount = unreadCount > 0 &&
streamChannel!.channel.state!.members.any((e) => streamChannel!.channel.state!.members.any((e) =>
e.userId == streamChannel!.channel.client.state.user!.id); e.userId ==
streamChannel!.channel.client.state.currentUser!.id);
return Positioned( return Positioned(
bottom: 8, bottom: 8,
right: 8, right: 8,
@@ -810,9 +811,10 @@ class _MessageListViewState extends State<MessageListView> {
Widget buildParentMessage( Widget buildParentMessage(
Message message, Message message,
) { ) {
final isMyMessage = message.user!.id == StreamChat.of(context).user!.id; final isMyMessage =
message.user!.id == StreamChat.of(context).currentUser!.id;
final isOnlyEmoji = message.text!.isOnlyEmoji; final isOnlyEmoji = message.text!.isOnlyEmoji;
final currentUser = StreamChat.of(context).user; final currentUser = StreamChat.of(context).currentUser;
final members = StreamChannel.of(context).channel.state?.members ?? []; final members = StreamChannel.of(context).channel.state?.members ?? [];
final currentUserMember = final currentUserMember =
members.firstWhereOrNull((e) => e.user!.id == currentUser!.id); members.firstWhereOrNull((e) => e.user!.id == currentUser!.id);
@@ -897,7 +899,7 @@ class _MessageListViewState extends State<MessageListView> {
); );
} }
final userId = StreamChat.of(context).user!.id; final userId = StreamChat.of(context).currentUser!.id;
final isMyMessage = message.user!.id == userId; final isMyMessage = message.user!.id == userId;
final nextMessage = index - 1 >= 0 ? messages[index - 1] : null; final nextMessage = index - 1 >= 0 ? messages[index - 1] : null;
final isNextUserSame = final isNextUserSame =
@@ -960,7 +962,7 @@ class _MessageListViewState extends State<MessageListView> {
? BorderSide.none ? BorderSide.none
: null; : null;
final currentUser = StreamChat.of(context).user; final currentUser = StreamChat.of(context).currentUser;
final members = StreamChannel.of(context).channel.state?.members ?? []; final members = StreamChannel.of(context).channel.state?.members ?? [];
final currentUserMember = final currentUserMember =
members.firstWhere((e) => e.user!.id == currentUser!.id); members.firstWhere((e) => e.user!.id == currentUser!.id);
@@ -1166,7 +1168,7 @@ class _MessageListViewState extends State<MessageListView> {
_topPaginationActive = false; _topPaginationActive = false;
} }
if (event.message!.user!.id == if (event.message!.user!.id ==
streamChannel!.channel.client.state.user!.id) { streamChannel!.channel.client.state.currentUser!.id) {
WidgetsBinding.instance!.addPostFrameCallback((_) { WidgetsBinding.instance!.addPostFrameCallback((_) {
_scrollController?.jumpTo( _scrollController?.jumpTo(
index: 0, index: 0,
@@ -43,7 +43,7 @@ class MessageReactionsModal extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final size = MediaQuery.of(context).size; final size = MediaQuery.of(context).size;
final user = StreamChat.of(context).user; final user = StreamChat.of(context).currentUser;
final roughMaxSize = 2 * size.width / 3; final roughMaxSize = 2 * size.width / 3;
var messageTextLength = message.text!.length; var messageTextLength = message.text!.length;
@@ -50,7 +50,7 @@ class MessageSearchItem extends StatelessWidget {
title: Row( title: Row(
children: [ children: [
Text( Text(
user.id == StreamChat.of(context).user?.id user.id == StreamChat.of(context).currentUser?.id
? context.translations.youText ? context.translations.youText
: user.name, : user.name,
style: chatThemeData.channelPreviewTheme.title, style: chatThemeData.channelPreviewTheme.title,
@@ -92,6 +92,8 @@ class MessageWidget extends StatefulWidget {
this.userAvatarBuilder, this.userAvatarBuilder,
this.editMessageInputBuilder, this.editMessageInputBuilder,
this.textBuilder, this.textBuilder,
this.bottomRowBuilder,
this.deletedBottomRowBuilder,
this.onReturnAction, this.onReturnAction,
Map<String, AttachmentBuilder>? customAttachmentBuilders, Map<String, AttachmentBuilder>? customAttachmentBuilders,
this.readList, this.readList,
@@ -275,6 +277,12 @@ class MessageWidget extends StatefulWidget {
/// Function called on long press /// Function called on long press
final void Function(BuildContext, Message)? onMessageActions; final void Function(BuildContext, Message)? onMessageActions;
/// Widget builder for building a bottom row below the message
final Widget Function(BuildContext, Message)? bottomRowBuilder;
/// Widget builder for building a bottom row below a deleted message
final Widget Function(BuildContext, Message)? deletedBottomRowBuilder;
/// Widget builder for building user avatar /// Widget builder for building user avatar
final Widget Function(BuildContext, User)? userAvatarBuilder; final Widget Function(BuildContext, User)? userAvatarBuilder;
@@ -410,6 +418,8 @@ class MessageWidget extends StatefulWidget {
Widget Function(BuildContext, Message)? editMessageInputBuilder, Widget Function(BuildContext, Message)? editMessageInputBuilder,
Widget Function(BuildContext, Message)? textBuilder, Widget Function(BuildContext, Message)? textBuilder,
Widget Function(BuildContext, Message)? usernameBuilder, Widget Function(BuildContext, Message)? usernameBuilder,
Widget Function(BuildContext, Message)? bottomRowBuilder,
Widget Function(BuildContext, Message)? deletedBottomRowBuilder,
void Function(BuildContext, Message)? onMessageActions, void Function(BuildContext, Message)? onMessageActions,
Message? message, Message? message,
MessageTheme? messageTheme, MessageTheme? messageTheme,
@@ -463,6 +473,9 @@ class MessageWidget extends StatefulWidget {
editMessageInputBuilder ?? this.editMessageInputBuilder, editMessageInputBuilder ?? this.editMessageInputBuilder,
textBuilder: textBuilder ?? this.textBuilder, textBuilder: textBuilder ?? this.textBuilder,
usernameBuilder: usernameBuilder ?? this.usernameBuilder, usernameBuilder: usernameBuilder ?? this.usernameBuilder,
bottomRowBuilder: bottomRowBuilder ?? this.bottomRowBuilder,
deletedBottomRowBuilder:
deletedBottomRowBuilder ?? this.deletedBottomRowBuilder,
onMessageActions: onMessageActions ?? this.onMessageActions, onMessageActions: onMessageActions ?? this.onMessageActions,
message: message ?? this.message, message: message ?? this.message,
messageTheme: messageTheme ?? this.messageTheme, messageTheme: messageTheme ?? this.messageTheme,
@@ -782,7 +795,11 @@ class _MessageWidgetState extends State<MessageWidget>
bottom: bottom:
isPinned && widget.showPinHighlight ? 6.0 : 0.0, isPinned && widget.showPinHighlight ? 6.0 : 0.0,
), ),
child: _bottomRow, child: widget.bottomRowBuilder?.call(
context,
widget.message,
) ??
_bottomRow,
), ),
if (isFailedState) if (isFailedState)
Positioned( Positioned(
@@ -810,7 +827,7 @@ class _MessageWidgetState extends State<MessageWidget>
} }
Widget _buildQuotedMessage() { Widget _buildQuotedMessage() {
final isMyMessage = widget.message.user?.id == _streamChat.user?.id; final isMyMessage = widget.message.user?.id == _streamChat.currentUser?.id;
final onTap = widget.message.quotedMessage?.isDeleted != true && final onTap = widget.message.quotedMessage?.isDeleted != true &&
widget.onQuotedMessageTap != null widget.onQuotedMessageTap != null
? () => widget.onQuotedMessageTap!(widget.message.quotedMessageId) ? () => widget.onQuotedMessageTap!(widget.message.quotedMessageId)
@@ -830,22 +847,11 @@ class _MessageWidgetState extends State<MessageWidget>
Widget get _bottomRow { Widget get _bottomRow {
if (isDeleted) { if (isDeleted) {
final chatThemeData = _streamChatTheme; return widget.deletedBottomRowBuilder?.call(
return Row( context,
mainAxisSize: MainAxisSize.min, widget.message,
children: [ ) ??
StreamSvgIcon.eye( const Offstage();
color: chatThemeData.colorTheme.textLowEmphasis,
size: 16,
),
const SizedBox(width: 8),
Text(
context.translations.onlyVisibleToYouText,
style: chatThemeData.textTheme.footnote
.copyWith(color: chatThemeData.colorTheme.textLowEmphasis),
),
],
);
} }
final children = <Widget>[]; final children = <Widget>[];
@@ -993,7 +999,7 @@ class _MessageWidgetState extends State<MessageWidget>
Widget _buildReactionIndicator( Widget _buildReactionIndicator(
BuildContext context, BuildContext context,
) { ) {
final ownId = _streamChat.user!.id; final ownId = _streamChat.currentUser!.id;
final reactionsMap = <String, Reaction>{}; final reactionsMap = <String, Reaction>{};
widget.message.latestReactions?.forEach((element) { widget.message.latestReactions?.forEach((element) {
if (!reactionsMap.containsKey(element.type) || if (!reactionsMap.containsKey(element.type) ||
@@ -1054,10 +1060,10 @@ class _MessageWidgetState extends State<MessageWidget>
showReactionPickerIndicator: widget.showReactions && showReactionPickerIndicator: widget.showReactions &&
(widget.message.status == MessageSendingStatus.sent), (widget.message.status == MessageSendingStatus.sent),
showPinHighlight: false, showPinHighlight: false,
showUserAvatar: showUserAvatar: widget.message.user!.id ==
widget.message.user!.id == channel.client.state.user!.id channel.client.state.currentUser!.id
? DisplayWidget.gone ? DisplayWidget.gone
: DisplayWidget.show, : DisplayWidget.show,
), ),
onCopyTap: (message) => onCopyTap: (message) =>
Clipboard.setData(ClipboardData(text: message.text)), Clipboard.setData(ClipboardData(text: message.text)),
@@ -1118,7 +1124,7 @@ class _MessageWidgetState extends State<MessageWidget>
(widget.message.status == MessageSendingStatus.sent), (widget.message.status == MessageSendingStatus.sent),
showPinHighlight: false, showPinHighlight: false,
showUserAvatar: showUserAvatar:
widget.message.user!.id == channel.client.state.user!.id widget.message.user!.id == channel.client.state.currentUser!.id
? DisplayWidget.gone ? DisplayWidget.gone
: DisplayWidget.show, : DisplayWidget.show,
), ),
@@ -1279,7 +1285,7 @@ class _MessageWidgetState extends State<MessageWidget>
Widget _buildPinnedMessage(Message message) { Widget _buildPinnedMessage(Message message) {
final pinnedBy = message.pinnedBy!; final pinnedBy = message.pinnedBy!;
final currentUser = _streamChat.user!; final currentUser = _streamChat.currentUser!;
return Padding( return Padding(
padding: const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 8),
@@ -123,7 +123,7 @@ class ReactionBubble extends StatelessWidget {
); );
final chatThemeData = StreamChatTheme.of(context); final chatThemeData = StreamChatTheme.of(context);
final userId = StreamChat.of(context).user?.id; final userId = StreamChat.of(context).currentUser?.id;
return Padding( return Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 4, horizontal: 4,
@@ -126,11 +126,25 @@ class StreamChatState extends State<StreamChat> {
return defaultTheme.merge(themeData); return defaultTheme.merge(themeData);
} }
// coverage:ignore-start
/// The current user /// The current user
User? get user => widget.client.state.user; @Deprecated('Use `.currentUser` instead, Will be removed in future releases')
User? get user => widget.client.state.currentUser;
/// The current user as a stream /// The current user as a stream
Stream<User?> get userStream => widget.client.state.userStream; @Deprecated(
'Use `.currentUserStream` instead, Will be removed in future releases',
)
Stream<User?> get userStream => widget.client.state.currentUserStream;
// coverage:ignore-end
/// The current user
User? get currentUser => widget.client.state.currentUser;
/// The current user as a stream
Stream<User?> get currentUserStream => widget.client.state.currentUserStream;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@@ -1,12 +1,11 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/src/channel_header.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/channel_preview.dart';
import 'package:stream_chat_flutter/src/extension.dart'; import 'package:stream_chat_flutter/src/extension.dart';
import 'package:stream_chat_flutter/src/gradient_avatar.dart';
import 'package:stream_chat_flutter/src/message_input.dart'; import 'package:stream_chat_flutter/src/message_input.dart';
import 'package:stream_chat_flutter/src/reaction_icon.dart'; import 'package:stream_chat_flutter/src/reaction_icon.dart';
import 'package:stream_chat_flutter/src/utils.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
@@ -310,10 +309,9 @@ class StreamChatThemeData {
colorTheme: colorTheme, colorTheme: colorTheme,
primaryIconTheme: iconTheme, primaryIconTheme: iconTheme,
defaultUserImage: (context, user) => Center( defaultUserImage: (context, user) => Center(
child: CachedNetworkImage( child: GradientAvatar(
filterQuality: FilterQuality.high, name: user.name,
imageUrl: getRandomPicUrl(user), userId: user.id,
fit: BoxFit.cover,
), ),
), ),
channelPreviewTheme: channelPreviewTheme, channelPreviewTheme: channelPreviewTheme,
@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
/// Widget for displaying a footnote
class VisibleFootnote extends StatelessWidget {
/// Constructor for creating a [VisibleFootnote]
const VisibleFootnote({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final chatThemeData = StreamChatTheme.of(context);
return Row(
mainAxisSize: MainAxisSize.min,
children: [
StreamSvgIcon.eye(
color: chatThemeData.colorTheme.textLowEmphasis,
size: 16,
),
const SizedBox(width: 8),
Text(
'Only visible to you',
style: chatThemeData.textTheme.footnote
.copyWith(color: chatThemeData.colorTheme.textLowEmphasis),
),
],
);
}
}
@@ -15,6 +15,7 @@ export 'src/deleted_message.dart';
export 'src/full_screen_media.dart'; export 'src/full_screen_media.dart';
export 'src/gallery_footer.dart'; export 'src/gallery_footer.dart';
export 'src/gallery_header.dart'; export 'src/gallery_header.dart';
export 'src/gradient_avatar.dart';
export 'src/info_tile.dart'; export 'src/info_tile.dart';
export 'src/localization/stream_chat_localizations.dart'; export 'src/localization/stream_chat_localizations.dart';
export 'src/localization/translations.dart' show DefaultTranslations; export 'src/localization/translations.dart' show DefaultTranslations;
@@ -44,3 +45,4 @@ export 'src/user_item.dart';
export 'src/user_list_view.dart'; export 'src/user_list_view.dart';
export 'src/user_list_view.dart'; export 'src/user_list_view.dart';
export 'src/utils.dart'; export 'src/utils.dart';
export 'src/visible_footnote.dart';
@@ -1,9 +1,35 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:golden_toolkit/golden_toolkit.dart'; import 'package:golden_toolkit/golden_toolkit.dart';
Future<void> testExecutable(FutureOr<void> Function() testMain) async { Future<void> testExecutable(FutureOr<void> Function() testMain) async {
await loadAppFonts(); await loadAppFonts();
goldenFileComparator =
CustomGoldenFileComparator(Uri.parse('test/src/goldens'));
return testMain(); return testMain();
} }
class CustomGoldenFileComparator extends LocalFileComparator {
CustomGoldenFileComparator(Uri testFile) : super(testFile);
@override
Future<bool> compare(Uint8List imageBytes, Uri golden) async {
final result = await GoldenFileComparator.compareLists(
imageBytes,
await getGoldenBytes(golden),
);
if (!result.passed && result.diffPercent > 0.05) {
final error = await generateFailureOutput(result, golden, basedir);
throw FlutterError(error);
}
return true;
}
@override
Future<void> update(Uri golden, Uint8List imageBytes) =>
super.update(golden, imageBytes);
}
@@ -35,7 +35,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -77,7 +77,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id2')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id2'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -119,7 +119,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -160,7 +160,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -207,7 +207,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -254,7 +254,7 @@ void main() {
when(() => mockChannel.updateMessage(any())) when(() => mockChannel.updateMessage(any()))
.thenAnswer((_) async => UpdateMessageResponse()); .thenAnswer((_) async => UpdateMessageResponse());
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final message = Message( final message = Message(
text: 'test', text: 'test',
@@ -308,7 +308,7 @@ void main() {
when(() => mockChannel.updateMessage(any())) when(() => mockChannel.updateMessage(any()))
.thenAnswer((_) async => UpdateMessageResponse()); .thenAnswer((_) async => UpdateMessageResponse());
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final message = Message( final message = Message(
text: 'test', text: 'test',
@@ -357,7 +357,7 @@ void main() {
when(() => mockChannel.deleteMessage(any())) when(() => mockChannel.deleteMessage(any()))
.thenAnswer((_) async => EmptyResponse()); .thenAnswer((_) async => EmptyResponse());
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final message = Message( final message = Message(
user: User( user: User(
@@ -399,7 +399,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final imageDownloader = MockAttachmentDownloader(); final imageDownloader = MockAttachmentDownloader();
@@ -454,7 +454,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final fileDownloader = MockAttachmentDownloader(); final fileDownloader = MockAttachmentDownloader();
@@ -18,8 +18,9 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(user); when(() => clientState.currentUser).thenReturn(user);
when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => clientState.currentUserStream)
.thenAnswer((_) => Stream.value(user));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -82,8 +83,9 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(user); when(() => clientState.currentUser).thenReturn(user);
when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => clientState.currentUserStream)
.thenAnswer((_) => Stream.value(user));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -149,8 +151,9 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(user); when(() => clientState.currentUser).thenReturn(user);
when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => clientState.currentUserStream)
.thenAnswer((_) => Stream.value(user));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -217,8 +220,9 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(user); when(() => clientState.currentUser).thenReturn(user);
when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => clientState.currentUserStream)
.thenAnswer((_) => Stream.value(user));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -293,8 +297,9 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(user); when(() => clientState.currentUser).thenReturn(user);
when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => clientState.currentUserStream)
.thenAnswer((_) => Stream.value(user));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -360,8 +365,9 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(user); when(() => clientState.currentUser).thenReturn(user);
when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => clientState.currentUserStream)
.thenAnswer((_) => Stream.value(user));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -17,7 +17,7 @@ void main() {
final channelState = MockChannelState(); final channelState = MockChannelState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({ when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
@@ -56,7 +56,7 @@ void main() {
final channelState = MockChannelState(); final channelState = MockChannelState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({ when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
@@ -135,7 +135,7 @@ void main() {
final currentUser = OwnUser(id: 'user-id'); final currentUser = OwnUser(id: 'user-id');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(currentUser); when(() => clientState.currentUser).thenReturn(currentUser);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({ when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
@@ -207,7 +207,7 @@ void main() {
final channelState = MockChannelState(); final channelState = MockChannelState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({ when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
@@ -13,7 +13,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => client.wsConnectionStatusStream) when(() => client.wsConnectionStatusStream)
.thenAnswer((_) => Stream.value(ConnectionStatus.connected)); .thenAnswer((_) => Stream.value(ConnectionStatus.connected));
@@ -30,7 +30,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final userAvatar = tester.widget<UserAvatar>(find.byType(UserAvatar)); final userAvatar = tester.widget<UserAvatar>(find.byType(UserAvatar));
expect(userAvatar.user, clientState.user); expect(userAvatar.user, clientState.currentUser);
expect(find.byType(StreamNeumorphicButton), findsOneWidget); expect(find.byType(StreamNeumorphicButton), findsOneWidget);
expect(find.text('Stream Chat'), findsOneWidget); expect(find.text('Stream Chat'), findsOneWidget);
}, },
@@ -43,7 +43,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => client.wsConnectionStatusStream) when(() => client.wsConnectionStatusStream)
.thenAnswer((_) => Stream.value(ConnectionStatus.disconnected)); .thenAnswer((_) => Stream.value(ConnectionStatus.disconnected));
@@ -72,7 +72,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => client.wsConnectionStatusStream) when(() => client.wsConnectionStatusStream)
.thenAnswer((_) => Stream.value(ConnectionStatus.connecting)); .thenAnswer((_) => Stream.value(ConnectionStatus.connecting));
@@ -101,7 +101,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => client.wsConnectionStatusStream) when(() => client.wsConnectionStatusStream)
.thenAnswer((_) => Stream.value(ConnectionStatus.connecting)); .thenAnswer((_) => Stream.value(ConnectionStatus.connecting));
@@ -139,7 +139,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => client.wsConnectionStatusStream) when(() => client.wsConnectionStatusStream)
.thenAnswer((_) => Stream.value(ConnectionStatus.connecting)); .thenAnswer((_) => Stream.value(ConnectionStatus.connecting));
@@ -173,7 +173,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => client.wsConnectionStatusStream) when(() => client.wsConnectionStatusStream)
.thenAnswer((_) => Stream.value(ConnectionStatus.connecting)); .thenAnswer((_) => Stream.value(ConnectionStatus.connecting));
@@ -16,7 +16,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -18,8 +18,9 @@ void main() {
when(() => channel.cid).thenReturn('cid'); when(() => channel.cid).thenReturn('cid');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(user); when(() => clientState.currentUser).thenReturn(user);
when(() => clientState.userStream).thenAnswer((_) => Stream.value(user)); when(() => clientState.currentUserStream)
.thenAnswer((_) => Stream.value(user));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -13,7 +13,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: StreamChat( home: StreamChat(
@@ -14,7 +14,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: StreamChat( home: StreamChat(
@@ -46,7 +46,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -99,7 +99,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -152,7 +152,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -17,7 +17,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

@@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:golden_toolkit/golden_toolkit.dart';
import 'package:mocktail/mocktail.dart';
import 'package:stream_chat_flutter/src/gradient_avatar.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'mocks.dart';
void main() {
testWidgets(
'control test',
(WidgetTester tester) async {
final client = MockClient();
final clientState = MockClientState();
when(() => client.state).thenReturn(clientState);
when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidget(
MaterialApp(
home: StreamChat(
client: client,
child: const Scaffold(
body: Center(
child: SizedBox(
width: 100,
height: 100,
child: GradientAvatar(name: 'demo user', userId: 'demo123'),
),
),
),
),
),
);
expect(find.byType(GradientAvatar), findsOneWidget);
},
);
testGoldens(
'golden test for the name "demo user"',
(WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 100,
height: 100,
child: GradientAvatar(name: 'demo user', userId: 'demo123'),
),
),
),
),
);
await screenMatchesGolden(tester, 'gradient_avatar_0');
},
);
testGoldens(
'golden test for the name "demo"',
(WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 100,
height: 100,
child: GradientAvatar(name: 'demo', userId: 'demo1'),
),
),
),
),
);
await screenMatchesGolden(tester, 'gradient_avatar_1');
},
);
testGoldens(
'control special character test',
(WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 100,
height: 100,
child: GradientAvatar(
name: 'd123@/d de:\$as',
userId: 'demo123',
),
),
),
),
),
);
await screenMatchesGolden(tester, 'gradient_avatar_2');
},
);
testGoldens(
'control special character test 2',
(WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 100,
height: 100,
child: GradientAvatar(name: '123@/d \$as', userId: 'demo123'),
),
),
),
),
);
await screenMatchesGolden(tester, 'gradient_avatar_3');
},
);
}
@@ -16,7 +16,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -14,7 +14,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: StreamChat( home: StreamChat(
@@ -44,7 +44,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: StreamChat( home: StreamChat(
@@ -20,7 +20,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -66,7 +66,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -117,7 +117,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -172,7 +172,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -218,7 +218,7 @@ void main() {
final clientState = MockClientState(); final clientState = MockClientState();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -265,7 +265,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -314,7 +314,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -364,7 +364,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -414,7 +414,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.sendMessage(any())) when(() => channel.sendMessage(any()))
.thenAnswer((_) async => SendMessageResponse()); .thenAnswer((_) async => SendMessageResponse());
@@ -464,7 +464,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.updateMessage(any())) when(() => channel.updateMessage(any()))
.thenAnswer((_) async => UpdateMessageResponse()); .thenAnswer((_) async => UpdateMessageResponse());
@@ -514,7 +514,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -568,7 +568,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => client.flagMessage(any())) when(() => client.flagMessage(any()))
.thenThrow(StreamChatNetworkError(ChatErrorCode.internalSystemError)); .thenThrow(StreamChatNetworkError(ChatErrorCode.internalSystemError));
@@ -624,7 +624,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => client.flagMessage(any())) when(() => client.flagMessage(any()))
.thenThrow(StreamChatNetworkError(ChatErrorCode.inputError)); .thenThrow(StreamChatNetworkError(ChatErrorCode.inputError));
@@ -680,7 +680,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final themeData = ThemeData(); final themeData = ThemeData();
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -734,7 +734,7 @@ void main() {
final channel = MockChannel(); final channel = MockChannel();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.deleteMessage(any())) when(() => channel.deleteMessage(any()))
.thenThrow(StreamChatNetworkError(ChatErrorCode.internalSystemError)); .thenThrow(StreamChatNetworkError(ChatErrorCode.internalSystemError));
@@ -16,7 +16,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -16,7 +16,7 @@ void main() {
final themeData = ThemeData(); final themeData = ThemeData();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -61,7 +61,7 @@ void main() {
final themeData = ThemeData(); final themeData = ThemeData();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
@@ -21,7 +21,7 @@ void main() {
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -66,7 +66,7 @@ void main() {
final streamTheme = StreamChatThemeData.fromTheme(themeData); final streamTheme = StreamChatThemeData.fromTheme(themeData);
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -80,7 +80,7 @@ void main() {
}); });
const messageText = ''' const messageText = '''
a message. a message.
with multiple lines with multiple lines
and a list: and a list:
- a. okasd - a. okasd
@@ -6,32 +6,8 @@ import 'package:stream_chat_flutter/src/reaction_bubble.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'mocks.dart'; import 'mocks.dart';
import 'simple_frame.dart';
void main() { void main() {
testGoldens(
'it should show no reactions',
(WidgetTester tester) async {
await tester.pumpWidgetBuilder(
SimpleFrame(
child: StreamChatTheme(
data: StreamChatThemeData(),
child: const SizedBox(
child: ReactionBubble(
reactions: [],
borderColor: Colors.black,
backgroundColor: Colors.white,
maskColor: Colors.white,
),
),
),
),
surfaceSize: const Size(100, 100),
);
await screenMatchesGolden(tester, 'reaction_bubble_0');
},
);
testGoldens( testGoldens(
'it should show a like - light theme', 'it should show a like - light theme',
(WidgetTester tester) async { (WidgetTester tester) async {
@@ -40,7 +16,7 @@ void main() {
final themeData = ThemeData.light(); final themeData = ThemeData.light();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
final theme = StreamChatThemeData.fromTheme(themeData); final theme = StreamChatThemeData.fromTheme(themeData);
await tester.pumpWidgetBuilder( await tester.pumpWidgetBuilder(
@@ -77,7 +53,7 @@ void main() {
final theme = StreamChatThemeData.fromTheme(themeData); final theme = StreamChatThemeData.fromTheme(themeData);
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidgetBuilder( await tester.pumpWidgetBuilder(
StreamChat( StreamChat(
@@ -114,7 +90,7 @@ void main() {
final theme = StreamChatThemeData.fromTheme(themeData); final theme = StreamChatThemeData.fromTheme(themeData);
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidgetBuilder( await tester.pumpWidgetBuilder(
StreamChat( StreamChat(
@@ -159,7 +135,7 @@ void main() {
final theme = StreamChatThemeData.fromTheme(themeData); final theme = StreamChatThemeData.fromTheme(themeData);
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidgetBuilder( await tester.pumpWidgetBuilder(
StreamChat( StreamChat(
@@ -203,7 +179,7 @@ void main() {
final themeData = ThemeData(); final themeData = ThemeData();
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
await tester.pumpWidgetBuilder( await tester.pumpWidgetBuilder(
StreamChat( StreamChat(
@@ -17,7 +17,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -68,7 +68,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -120,7 +120,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -16,7 +16,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -81,7 +81,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -16,7 +16,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -16,7 +16,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.lastMessageAt).thenReturn(lastMessageAt); when(() => channel.lastMessageAt).thenReturn(lastMessageAt);
when(() => channel.state).thenReturn(channelState); when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client); when(() => channel.client).thenReturn(client);
@@ -58,7 +58,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => clientState.channels).thenReturn({ when(() => clientState.channels).thenReturn({
channel.cid!: channel, channel.cid!: channel,
}); });
@@ -98,7 +98,7 @@ void main() {
final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); final lastMessageAt = DateTime.parse('2020-06-22 12:00:00');
when(() => client.state).thenReturn(clientState); when(() => client.state).thenReturn(clientState);
when(() => clientState.user).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => clientState.channels).thenReturn({ when(() => clientState.channels).thenReturn({
channel.cid!: channel, channel.cid!: channel,
}); });
@@ -1,8 +1,15 @@
## Upcoming ## Upcoming
🛑️ Breaking Changes from `2.0.0`
- Changed default message filter of `MessageListCore`
✅ Added ✅ Added
- Added `MessageListCore.paginationLimit` - Added `MessageListCore.paginationLimit`
🔄 Changed
- `StreamChatCore.of(context).user` is now deprecated in favor of `StreamChatCore.of(context).currentUser`.
- `StreamChatCore.of(context).userStream` is now deprecated in favor of `StreamChatCore.of(context).currentUserStream`.
## 2.0.0 ## 2.0.0
🛑️ Breaking Changes from `1.5.3` 🛑️ Breaking Changes from `1.5.3`
@@ -87,7 +87,7 @@ class HomeScreen extends StatelessWidget {
filter: Filter.and([ filter: Filter.and([
Filter.equal('type', 'messaging'), Filter.equal('type', 'messaging'),
Filter.in_('members', [ Filter.in_('members', [
StreamChatCore.of(context).user!.id, StreamChatCore.of(context).currentUser!.id,
]) ])
]), ]),
emptyBuilder: (BuildContext context) => const Center( emptyBuilder: (BuildContext context) => const Center(
@@ -336,7 +336,7 @@ class _MessageScreenState extends State<MessageScreen> {
/// below, we add two simple extensions to the [StreamChatClient] and [Channel]. /// below, we add two simple extensions to the [StreamChatClient] and [Channel].
extension on StreamChatClient { extension on StreamChatClient {
/// Fetches the current user id. /// Fetches the current user id.
String get uid => state.user!.id; String get uid => state.currentUser!.id;
} }
extension on Channel { extension on Channel {
@@ -116,7 +116,7 @@ class MessageListCoreState extends State<MessageListCore> {
bool get _isThreadConversation => widget.parentMessage != null; bool get _isThreadConversation => widget.parentMessage != null;
OwnUser? get _currentUser => _streamChannel!.channel.client.state.user; OwnUser? get _currentUser => _streamChannel!.channel.client.state.currentUser;
var _messages = <Message>[]; var _messages = <Message>[];
@@ -134,8 +134,7 @@ class MessageListCoreState extends State<MessageListCore> {
bool defaultFilter(Message m) { bool defaultFilter(Message m) {
final isMyMessage = m.user?.id == _currentUser?.id; final isMyMessage = m.user?.id == _currentUser?.id;
final isDeletedOrShadowed = m.isDeleted == true || m.shadowed == true; if (m.shadowed && !isMyMessage) return false;
if (isDeletedOrShadowed && !isMyMessage) return false;
return true; return true;
} }
@@ -97,11 +97,25 @@ class StreamChatCoreState extends State<StreamChatCore>
@override @override
Widget build(BuildContext context) => widget.child; Widget build(BuildContext context) => widget.child;
// coverage:ignore-start
/// The current user /// The current user
User? get user => client.state.user; @Deprecated('Use `.currentUser` instead, Will be removed in future releases')
User? get user => client.state.currentUser;
/// The current user as a stream /// The current user as a stream
Stream<User?> get userStream => client.state.userStream; @Deprecated(
'Use `.currentUserStream` instead, Will be removed in future releases',
)
Stream<User?> get userStream => client.state.currentUserStream;
// coverage:ignore-end
/// The current user
User? get currentUser => client.state.currentUser;
/// The current user as a stream
Stream<User?> get currentUserStream => client.state.currentUserStream;
StreamSubscription<ConnectivityResult>? _connectivitySubscription; StreamSubscription<ConnectivityResult>? _connectivitySubscription;
@@ -126,7 +140,7 @@ class StreamChatCoreState extends State<StreamChatCore>
if (!_isInForeground) return; if (!_isInForeground) return;
if (_isConnectionAvailable) { if (_isConnectionAvailable) {
if (client.wsConnectionStatus == ConnectionStatus.disconnected && if (client.wsConnectionStatus == ConnectionStatus.disconnected &&
user != null) { currentUser != null) {
client.openConnection(); client.openConnection();
} }
} else { } else {
@@ -163,7 +177,7 @@ class StreamChatCoreState extends State<StreamChatCore>
AppLifecycleState.resumed, AppLifecycleState.resumed,
AppLifecycleState.inactive, AppLifecycleState.inactive,
].contains(state); ].contains(state);
if (user != null) { if (currentUser != null) {
if (_isInForeground) { if (_isInForeground) {
_onForeground(); _onForeground();
} else { } else {
@@ -18,10 +18,10 @@ class MockClient extends Mock implements StreamChatClient {
} }
class MockClientState extends Mock implements ClientState { class MockClientState extends Mock implements ClientState {
OwnUser? _user; OwnUser? _currentUser;
@override @override
OwnUser get user => _user ??= OwnUser( OwnUser get currentUser => _currentUser ??= OwnUser(
id: 'testUserId', id: 'testUserId',
role: 'admin', role: 'admin',
createdAt: DateTime.now(), createdAt: DateTime.now(),
@@ -431,7 +431,7 @@ void main() {
); );
testWidgets( testWidgets(
'streamChatCoreState.userStream should emit all the user events ' 'streamChatCoreState.currentUserStream should emit all the user events '
'provided by client', 'provided by client',
(tester) async { (tester) async {
await tester.runAsync(() async { await tester.runAsync(() async {
@@ -451,7 +451,7 @@ void main() {
expect(find.byKey(streamChatCoreKey), findsOneWidget); expect(find.byKey(streamChatCoreKey), findsOneWidget);
expect(find.byKey(childKey), findsOneWidget); expect(find.byKey(childKey), findsOneWidget);
when(() => mockClient.state.userStream) when(() => mockClient.state.currentUserStream)
.thenAnswer((_) => userController.stream); .thenAnswer((_) => userController.stream);
final streamChatCoreState = tester.state<StreamChatCoreState>( final streamChatCoreState = tester.state<StreamChatCoreState>(
@@ -462,7 +462,7 @@ void main() {
userController.add(ownUser); userController.add(ownUser);
await expectLater( await expectLater(
streamChatCoreState.userStream, streamChatCoreState.currentUserStream,
emits(ownUser), emits(ownUser),
); );
@@ -255,5 +255,5 @@ class _MessageViewState extends State<MessageView> {
/// Helper extension for quickly retrieving /// Helper extension for quickly retrieving
/// the current user id from a [StreamChatClient]. /// the current user id from a [StreamChatClient].
extension on StreamChatClient { extension on StreamChatClient {
String get uid => state.user!.id; String get uid => state.currentUser!.id;
} }