From 61d7661297c8473859bd0f2e20927e950ef6b103 Mon Sep 17 00:00:00 2001 From: groovinchip Date: Thu, 22 Jul 2021 10:11:34 -0400 Subject: [PATCH 01/26] chore: add cooldown to channel_model.dart and test it --- .../stream_chat/lib/src/core/models/channel_model.dart | 8 ++++++++ .../stream_chat/test/src/core/models/channel_test.dart | 1 + 2 files changed, 9 insertions(+) diff --git a/packages/stream_chat/lib/src/core/models/channel_model.dart b/packages/stream_chat/lib/src/core/models/channel_model.dart index 37e587ff..9fdf3723 100644 --- a/packages/stream_chat/lib/src/core/models/channel_model.dart +++ b/packages/stream_chat/lib/src/core/models/channel_model.dart @@ -23,6 +23,7 @@ class ChannelModel { this.memberCount = 0, this.extraData = const {}, this.team, + this.cooldown = 0, }) : assert( (cid != null && cid.contains(':')) || (id != null && type != null), 'provide either a cid or an id and type', @@ -81,6 +82,9 @@ class ChannelModel { @JsonKey(includeIfNull: false, toJson: Serializer.readOnly, defaultValue: 0) final int memberCount; + @JsonKey(includeIfNull: false) + final int cooldown; + /// Map of custom channel extraData @JsonKey( includeIfNull: false, @@ -107,6 +111,7 @@ class ChannelModel { 'deleted_at', 'member_count', 'team', + 'cooldown', ]; /// Shortcut for channel name @@ -133,6 +138,7 @@ class ChannelModel { int? memberCount, Map? extraData, String? team, + int? cooldown, }) => ChannelModel( id: id ?? this.id, @@ -148,6 +154,7 @@ class ChannelModel { memberCount: memberCount ?? this.memberCount, extraData: extraData ?? this.extraData, team: team ?? this.team, + cooldown: cooldown ?? this.cooldown, ); /// Returns a new [ChannelModel] that is a combination of this channelModel @@ -168,6 +175,7 @@ class ChannelModel { memberCount: other.memberCount, extraData: other.extraData, team: other.team, + cooldown: other.cooldown, ); } } diff --git a/packages/stream_chat/test/src/core/models/channel_test.dart b/packages/stream_chat/test/src/core/models/channel_test.dart index ca734c44..31162bd6 100644 --- a/packages/stream_chat/test/src/core/models/channel_test.dart +++ b/packages/stream_chat/test/src/core/models/channel_test.dart @@ -12,6 +12,7 @@ void main() { expect(channel.cid, equals('livestream:test')); expect(channel.extraData['cats'], equals(true)); expect(channel.extraData['fruit'], equals(['bananas', 'apples'])); + expect(channel.cooldown, equals(0)); }); test('should serialize to json correctly', () { From da3cf4d6de168f1e183758fb6978cb61134b9a8c Mon Sep 17 00:00:00 2001 From: groovinchip Date: Thu, 22 Jul 2021 10:20:31 -0400 Subject: [PATCH 02/26] chore: start adding cooldown and cooldown stream to channel.dart --- packages/stream_chat/lib/src/client/channel.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 94a07f34..6bec5ce7 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -118,6 +118,18 @@ class Channel { return state?.channelStateStream.map((cs) => cs.channel?.frozen); } + /// Cooldown count + int? get cooldown { + _checkInitialized(); + return state?._channelState.channel?.cooldown; + } + + /// Cooldown count as a stream + Stream? get cooldownStream { + _checkInitialized(); + return state?.cooldownStateStream.map((cs) => cs.channel?.cooldown); + } + /// Channel creation date DateTime? get createdAt { _checkInitialized(); From c2b6ea13d816fd12818dba5ff1c1475aba23d111 Mon Sep 17 00:00:00 2001 From: groovinchip Date: Thu, 22 Jul 2021 13:46:04 -0400 Subject: [PATCH 03/26] fix: use the right stream for cooldown stream --- packages/stream_chat/lib/src/client/channel.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 6bec5ce7..4a7cbbb5 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -127,7 +127,7 @@ class Channel { /// Cooldown count as a stream Stream? get cooldownStream { _checkInitialized(); - return state?.cooldownStateStream.map((cs) => cs.channel?.cooldown); + return state?.channelStateStream.map((cs) => cs.channel?.cooldown); } /// Channel creation date From 848aa550f763c2cef2bbaa500e9ff96e5e870b87 Mon Sep 17 00:00:00 2001 From: groovinchip Date: Thu, 22 Jul 2021 13:47:58 -0400 Subject: [PATCH 04/26] chore: add doc for cooldown in channel_model.dart --- packages/stream_chat/lib/src/core/models/channel_model.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/stream_chat/lib/src/core/models/channel_model.dart b/packages/stream_chat/lib/src/core/models/channel_model.dart index 9fdf3723..3df04007 100644 --- a/packages/stream_chat/lib/src/core/models/channel_model.dart +++ b/packages/stream_chat/lib/src/core/models/channel_model.dart @@ -82,6 +82,7 @@ class ChannelModel { @JsonKey(includeIfNull: false, toJson: Serializer.readOnly, defaultValue: 0) final int memberCount; + /// The number of seconds in a cooldown @JsonKey(includeIfNull: false) final int cooldown; From 9fb60e93c1c93d13b7b540a4f2bd3ef5dee6e9e7 Mon Sep 17 00:00:00 2001 From: groovinchip Date: Mon, 26 Jul 2021 11:42:24 -0400 Subject: [PATCH 05/26] progress on slow mode --- .../stream_chat/lib/src/client/channel.dart | 20 ++++ .../stream_chat/lib/src/client/client.dart | 22 +++++ .../lib/src/core/api/channel_api.dart | 29 ++++++ .../lib/src/core/models/channel_model.dart | 2 +- .../lib/src/core/models/channel_model.g.dart | 2 + .../lib/src/core/models/own_user.g.dart | 3 + .../stream_chat_flutter/example/lib/main.dart | 14 ++- .../lib/src/message_input.dart | 98 +++++++++++++++++-- .../lib/src/message_list_view.dart | 4 +- 9 files changed, 178 insertions(+), 16 deletions(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 4a7cbbb5..8e298fc9 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -130,6 +130,9 @@ class Channel { return state?.channelStateStream.map((cs) => cs.channel?.cooldown); } + /// + DateTime? cooldownStartedAt; + /// Channel creation date DateTime? get createdAt { _checkInitialized(); @@ -429,6 +432,9 @@ class Channel { skipPush: skipPush, ); state!.addMessage(response.message); + if (cooldown! > 0) { + cooldownStartedAt = DateTime.now(); + } return response; } catch (e) { if (e is StreamChatNetworkError && e.isRetriable) { @@ -827,6 +833,20 @@ class Channel { return _client.updateChannelPartial(id!, type, set: set, unset: unset); } + /// Enable slow mode + Future enableSlowMode({ + required int cooldownInterval, + }) async { + _checkInitialized(); + return _client.enableSlowdown(id!, type, cooldownInterval); + } + + /// Disable slow mode + Future disableSlowMode() async { + _checkInitialized(); + return _client.disableSlowdown(id!, type); + } + /// Delete this channel. Messages are permanently removed. Future delete() async { _checkInitialized(); diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 050d36f1..2ea20e60 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -1244,6 +1244,28 @@ class StreamChatClient { language, ); + /// Enables slow mode + Future enableSlowdown( + String channelId, + String channelType, + int cooldown, + ) async => + _chatApi.channel.enableSlowdown( + channelId, + channelType, + cooldown, + ); + + /// Disables slow mode + Future disableSlowdown( + String channelId, + String channelType, + ) async => + _chatApi.channel.disableSlowdown( + channelId, + channelType, + ); + /// Pins provided message /// [timeoutOrExpirationDate] can either be a [DateTime] or a value in seconds /// to be added to [DateTime.now] diff --git a/packages/stream_chat/lib/src/core/api/channel_api.dart b/packages/stream_chat/lib/src/core/api/channel_api.dart index 1ba7f333..31a64cf8 100644 --- a/packages/stream_chat/lib/src/core/api/channel_api.dart +++ b/packages/stream_chat/lib/src/core/api/channel_api.dart @@ -123,6 +123,35 @@ class ChannelApi { return PartialUpdateChannelResponse.fromJson(response.data); } + /// Enable slowdown + Future enableSlowdown( + String channelId, + String channelType, + int cooldown, + ) async { + final response = await _client.post( + _getChannelUrl(channelId, channelType), + data: { + 'cooldown': cooldown, + }, + ); + return UpdateChannelResponse.fromJson(response.data); + } + + /// Disable slowdown + Future disableSlowdown( + String channelId, + String channelType, + ) async { + final response = await _client.post( + _getChannelUrl(channelId, channelType), + data: { + 'cooldown': 0, + }, + ); + return UpdateChannelResponse.fromJson(response.data); + } + /// Accept invitation to the channel Future acceptChannelInvite( String channelId, diff --git a/packages/stream_chat/lib/src/core/models/channel_model.dart b/packages/stream_chat/lib/src/core/models/channel_model.dart index 3df04007..a4e6db79 100644 --- a/packages/stream_chat/lib/src/core/models/channel_model.dart +++ b/packages/stream_chat/lib/src/core/models/channel_model.dart @@ -83,7 +83,7 @@ class ChannelModel { final int memberCount; /// The number of seconds in a cooldown - @JsonKey(includeIfNull: false) + @JsonKey(includeIfNull: false, defaultValue: 0) final int cooldown; /// Map of custom channel extraData diff --git a/packages/stream_chat/lib/src/core/models/channel_model.g.dart b/packages/stream_chat/lib/src/core/models/channel_model.g.dart index 4bde3d4a..d9adf94b 100644 --- a/packages/stream_chat/lib/src/core/models/channel_model.g.dart +++ b/packages/stream_chat/lib/src/core/models/channel_model.g.dart @@ -33,6 +33,7 @@ ChannelModel _$ChannelModelFromJson(Map json) { memberCount: json['member_count'] as int? ?? 0, extraData: json['extra_data'] as Map? ?? {}, team: json['team'] as String?, + cooldown: json['cooldown'] as int? ?? 0, ); } @@ -57,6 +58,7 @@ Map _$ChannelModelToJson(ChannelModel instance) { writeNotNull('updated_at', readonly(instance.updatedAt)); writeNotNull('deleted_at', readonly(instance.deletedAt)); writeNotNull('member_count', readonly(instance.memberCount)); + val['cooldown'] = instance.cooldown; val['extra_data'] = instance.extraData; writeNotNull('team', readonly(instance.team)); return val; diff --git a/packages/stream_chat/lib/src/core/models/own_user.g.dart b/packages/stream_chat/lib/src/core/models/own_user.g.dart index 26e4786e..465faff2 100644 --- a/packages/stream_chat/lib/src/core/models/own_user.g.dart +++ b/packages/stream_chat/lib/src/core/models/own_user.g.dart @@ -36,5 +36,8 @@ OwnUser _$OwnUserFromJson(Map json) { online: json['online'] as bool? ?? false, extraData: json['extra_data'] as Map? ?? {}, banned: json['banned'] as bool? ?? false, + teams: + (json['teams'] as List?)?.map((e) => e as String).toList() ?? + [], ); } diff --git a/packages/stream_chat_flutter/example/lib/main.dart b/packages/stream_chat_flutter/example/lib/main.dart index 89362d81..6f038616 100644 --- a/packages/stream_chat_flutter/example/lib/main.dart +++ b/packages/stream_chat_flutter/example/lib/main.dart @@ -13,7 +13,7 @@ void main() async { /// Create a new instance of [StreamChatClient] passing the apikey obtained /// from your project dashboard. final client = StreamChatClient( - 's2dxdhpxd94g', + 'kv7mcsxr24p8', logLevel: Level.INFO, )..chatPersistenceClient = chatPersistentClient; @@ -24,15 +24,19 @@ void main() async { /// Please see the following for more information: /// https://getstream.io/chat/docs/ios_user_setup_and_tokens/ await client.connectUser( - User(id: 'super-band-9'), - 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic3VwZXItYmFuZC05In0.' - '0L6lGoeLwkz0aZRUcpZKsvaXtNEDHBcezVTZ0oPq40A', + User(id: 'salvatore'), + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoic2FsdmF0b3JlIn0.pgiJz7sIc7iP29BHKFwe3nLm5-OaR_1l2P-SlgiC9a8', ); - final channel = client.channel('messaging', id: 'godevs'); + final channel = client.channel('messaging', id: 'godevs2', extraData: { + 'members': ['salvatore'], + }); await channel.watch(); + await channel.enableSlowMode(cooldownInterval: 20); + print('Channel cooldown set to ${channel.cooldown}'); + runApp( MyApp( client: client, diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 5a4f6822..c3c2e30a 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -291,9 +291,13 @@ class MessageInputState extends State { bool get _hasQuotedMessage => widget.quotedMessage != null; + late DateTime? _cooldownStartedAt; + int? _timeOut; + @override void initState() { super.initState(); + _startSlowMode(); _focusNode = widget.focusNode ?? FocusNode(); _emojiNames = Emoji.all().where((it) => it.name != null).map((e) => e.name!); @@ -324,6 +328,25 @@ class MessageInputState extends State { }); } + void _startSlowMode() { + if (StreamChannel.of(context).channel.cooldownStartedAt != null) { + _cooldownStartedAt = StreamChannel.of(context).channel.cooldownStartedAt; + if (DateTime.now().difference(_cooldownStartedAt!).inSeconds < + StreamChannel.of(context).channel.cooldown!) { + _timeOut = StreamChannel.of(context).channel.cooldown! - + DateTime.now().difference(_cooldownStartedAt!).inSeconds; + Timer.periodic(const Duration(seconds: 1), (timer) { + if (_timeOut == 0) { + timer.cancel(); + } else { + print('Time left until cooldown is over: $_timeOut'); + setState(() => _timeOut = _timeOut! - 1); + } + }); + } + } + } + @override Widget build(BuildContext context) { Widget child = DecoratedBox( @@ -472,13 +495,44 @@ class MessageInputState extends State { ); Widget _animateSendButton(BuildContext context) { - final sendButton = widget.activeSendButton != null - ? InkWell( - onTap: sendMessage, - child: widget.activeSendButton, - ) - : _buildSendButton(context); - return AnimatedCrossFade( + late Widget sendButton; + if (_timeOut != null && _timeOut! > 0) { + sendButton = _CountdownButton( + count: _timeOut!, + ); + } else if (!_messageIsPresent && _attachments.isEmpty) { + sendButton = widget.idleSendButton ?? _buildIdleSendButton(context); + } else { + sendButton = widget.activeSendButton != null + ? InkWell( + onTap: sendMessage, + child: widget.activeSendButton, + ) + : _buildSendButton(context); + } + + /*if (_timeOut == null || _timeOut == 0) { + sendButton = widget.activeSendButton != null + ? InkWell( + onTap: sendMessage, + child: widget.activeSendButton, + ) + : _buildSendButton(context); + } else { + sendButton = _CountdownButton( + count: _timeOut!, + ); + } + + if (!_messageIsPresent && _attachments.isEmpty) { + sendButton = widget.idleSendButton ?? _buildIdleSendButton(context); + }*/ + + return AnimatedSwitcher( + duration: _streamChatTheme.messageInputTheme.sendAnimationDuration!, + child: sendButton, + ); + /*return AnimatedCrossFade( crossFadeState: (_messageIsPresent || _attachments.isNotEmpty) ? CrossFadeState.showFirst : CrossFadeState.showSecond, @@ -486,7 +540,7 @@ class MessageInputState extends State { secondChild: widget.idleSendButton ?? _buildIdleSendButton(context), duration: _streamChatTheme.messageInputTheme.sendAnimationDuration!, alignment: Alignment.center, - ); + );*/ } Widget _buildExpandActionsButton() { @@ -2082,6 +2136,7 @@ class MessageInputState extends State { if (resp.message?.type == 'error') { _parseExistingMessage(message); } + _startSlowMode(); widget.onMessageSent?.call(resp.message); } catch (e, stk) { if (widget.onError != null) { @@ -2347,3 +2402,30 @@ class __PickerWidgetState extends State<_PickerWidget> { }); } } + +class _CountdownButton extends StatelessWidget { + const _CountdownButton({ + Key? key, + required this.count, + }) : super(key: key); + + final int count; + + @override + Widget build(BuildContext context) => Padding( + padding: const EdgeInsets.all(8), + child: DecoratedBox( + decoration: BoxDecoration( + color: StreamChatTheme.of(context).colorTheme.disabled, + shape: BoxShape.circle, + ), + child: SizedBox( + height: 24, + width: 24, + child: Center( + child: Text('$count'), + ), + ), + ), + ); +} diff --git a/packages/stream_chat_flutter/lib/src/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view.dart index 3d0a3acd..8a236cbd 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view.dart @@ -942,7 +942,7 @@ class _MessageListViewState extends State { final currentUser = StreamChat.of(context).user; final members = StreamChannel.of(context).channel.state?.members ?? []; final currentUserMember = - members.firstWhere((e) => e.user!.id == currentUser!.id); + members.firstWhereOrNull((e) => e.user!.id == currentUser!.id); Widget messageWidget = MessageWidget( key: ValueKey('MESSAGE-${message.id}'), @@ -1049,7 +1049,7 @@ class _MessageListViewState extends State { } FocusScope.of(context).unfocus(); }, - showPinButton: widget.pinPermissions.contains(currentUserMember.role), + showPinButton: widget.pinPermissions.contains(currentUserMember?.role), ); if (widget.messageBuilder != null) { From b989fbc3ad3908b690705d08bd6bc21c432ed6e3 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 30 Jul 2021 11:48:23 +0200 Subject: [PATCH 06/26] fix(llc): use channel partial update for slowmode --- .../stream_chat/lib/src/client/channel.dart | 4 ++-- .../stream_chat/lib/src/client/client.dart | 4 ++-- .../lib/src/core/api/channel_api.dart | 24 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index fb579a56..1f6d3edd 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -834,7 +834,7 @@ class Channel { } /// Enable slow mode - Future enableSlowMode({ + Future enableSlowMode({ required int cooldownInterval, }) async { _checkInitialized(); @@ -842,7 +842,7 @@ class Channel { } /// Disable slow mode - Future disableSlowMode() async { + Future disableSlowMode() async { _checkInitialized(); return _client.disableSlowdown(id!, type); } diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 7b5cbb35..788bc9cf 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -1248,7 +1248,7 @@ class StreamChatClient { ); /// Enables slow mode - Future enableSlowdown( + Future enableSlowdown( String channelId, String channelType, int cooldown, @@ -1260,7 +1260,7 @@ class StreamChatClient { ); /// Disables slow mode - Future disableSlowdown( + Future disableSlowdown( String channelId, String channelType, ) async => diff --git a/packages/stream_chat/lib/src/core/api/channel_api.dart b/packages/stream_chat/lib/src/core/api/channel_api.dart index 31a64cf8..e8782feb 100644 --- a/packages/stream_chat/lib/src/core/api/channel_api.dart +++ b/packages/stream_chat/lib/src/core/api/channel_api.dart @@ -124,32 +124,32 @@ class ChannelApi { } /// Enable slowdown - Future enableSlowdown( + Future enableSlowdown( String channelId, String channelType, int cooldown, ) async { - final response = await _client.post( - _getChannelUrl(channelId, channelType), - data: { + final response = await updateChannelPartial( + channelId, + channelType, + set: { 'cooldown': cooldown, }, ); - return UpdateChannelResponse.fromJson(response.data); + return response; } /// Disable slowdown - Future disableSlowdown( + Future disableSlowdown( String channelId, String channelType, ) async { - final response = await _client.post( - _getChannelUrl(channelId, channelType), - data: { - 'cooldown': 0, - }, + final response = await updateChannelPartial( + channelId, + channelType, + unset: ['cooldown'], ); - return UpdateChannelResponse.fromJson(response.data); + return response; } /// Accept invitation to the channel From 33262200a3347aae43cd8de03b7fed709f45d6e5 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 16 Aug 2021 14:21:12 +0530 Subject: [PATCH 07/26] fix: tests --- .../test/src/core/models/channel_state_test.dart | 1 + .../test/src/core/models/channel_test.dart | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat/test/src/core/models/channel_state_test.dart b/packages/stream_chat/test/src/core/models/channel_state_test.dart index 8bd17d46..f151607a 100644 --- a/packages/stream_chat/test/src/core/models/channel_state_test.dart +++ b/packages/stream_chat/test/src/core/models/channel_state_test.dart @@ -29,6 +29,7 @@ void main() { DateTime.parse('2019-04-03T18:43:33.213374Z')); expect(channelState.channel?.createdBy, isA()); expect(channelState.channel?.frozen, true); + expect(channelState.channel?.cooldown, 0); expect(channelState.channel?.extraData['example'], 1); expect(channelState.channel?.extraData['name'], '#dev'); expect( diff --git a/packages/stream_chat/test/src/core/models/channel_test.dart b/packages/stream_chat/test/src/core/models/channel_test.dart index 31162bd6..e27f5970 100644 --- a/packages/stream_chat/test/src/core/models/channel_test.dart +++ b/packages/stream_chat/test/src/core/models/channel_test.dart @@ -25,7 +25,13 @@ void main() { expect( channel.toJson(), - {'id': 'id', 'type': 'type', 'frozen': false, 'name': 'cool'}, + { + 'id': 'id', + 'type': 'type', + 'frozen': false, + 'cooldown': 0, + 'name': 'cool', + }, ); }); @@ -39,7 +45,13 @@ void main() { expect( channel.toJson(), - {'id': 'id', 'type': 'type', 'name': 'cool', 'frozen': false}, + { + 'id': 'id', + 'type': 'type', + 'frozen': false, + 'cooldown': 0, + 'name': 'cool', + }, ); }); }); From fd13d1089f54396176a3e2d6539e8a65b0361564 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 16 Aug 2021 14:48:36 +0530 Subject: [PATCH 08/26] fix: tests --- packages/stream_chat/test/fixtures/channel_state_to_json.json | 1 + .../stream_chat/test/src/core/models/channel_state_test.dart | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat/test/fixtures/channel_state_to_json.json b/packages/stream_chat/test/fixtures/channel_state_to_json.json index 4b8a0369..ebb74fb6 100644 --- a/packages/stream_chat/test/fixtures/channel_state_to_json.json +++ b/packages/stream_chat/test/fixtures/channel_state_to_json.json @@ -4,6 +4,7 @@ "id": "dev", "type": "team", "frozen": true, + "cooldown": 0, "name": "#dev", "image": "https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png", "example": 1 diff --git a/packages/stream_chat/test/src/core/models/channel_state_test.dart b/packages/stream_chat/test/src/core/models/channel_state_test.dart index f151607a..8bd17d46 100644 --- a/packages/stream_chat/test/src/core/models/channel_state_test.dart +++ b/packages/stream_chat/test/src/core/models/channel_state_test.dart @@ -29,7 +29,6 @@ void main() { DateTime.parse('2019-04-03T18:43:33.213374Z')); expect(channelState.channel?.createdBy, isA()); expect(channelState.channel?.frozen, true); - expect(channelState.channel?.cooldown, 0); expect(channelState.channel?.extraData['example'], 1); expect(channelState.channel?.extraData['name'], '#dev'); expect( From f28b6b61a0dbbead99d3218838cdd7fa9802caa2 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 18 Aug 2021 15:45:46 +0530 Subject: [PATCH 09/26] fix: cooldown and teams, added correct textfield hint --- packages/stream_chat/lib/src/core/models/event.dart | 4 ++++ packages/stream_chat/lib/src/core/models/event.g.dart | 2 ++ .../lib/src/localization/translations.dart | 6 ++++++ packages/stream_chat_flutter/lib/src/message_input.dart | 4 ++++ .../lib/src/stream_chat_localizations_en.dart | 3 +++ .../lib/src/stream_chat_localizations_es.dart | 3 +++ .../lib/src/stream_chat_localizations_fr.dart | 3 +++ .../lib/src/stream_chat_localizations_hi.dart | 3 +++ .../lib/src/stream_chat_localizations_it.dart | 3 +++ 9 files changed, 31 insertions(+) diff --git a/packages/stream_chat/lib/src/core/models/event.dart b/packages/stream_chat/lib/src/core/models/event.dart index 26831555..9250176d 100644 --- a/packages/stream_chat/lib/src/core/models/event.dart +++ b/packages/stream_chat/lib/src/core/models/event.dart @@ -184,6 +184,8 @@ class EventChannel extends ChannelModel { DateTime? deletedAt, required int memberCount, Map? extraData, + required int cooldown, + String? team, }) : super( id: id, type: type, @@ -197,6 +199,8 @@ class EventChannel extends ChannelModel { deletedAt: deletedAt, memberCount: memberCount, extraData: extraData ?? {}, + cooldown: cooldown, + team: team, ); /// Create a new instance from a json diff --git a/packages/stream_chat/lib/src/core/models/event.g.dart b/packages/stream_chat/lib/src/core/models/event.g.dart index 5247af17..93d2e75b 100644 --- a/packages/stream_chat/lib/src/core/models/event.g.dart +++ b/packages/stream_chat/lib/src/core/models/event.g.dart @@ -87,5 +87,7 @@ EventChannel _$EventChannelFromJson(Map json) { : DateTime.parse(json['deleted_at'] as String), memberCount: json['member_count'] as int? ?? 0, extraData: json['extra_data'] as Map? ?? {}, + cooldown: json['cooldown'] as int? ?? 0, + team: json['team'] as String?, ); } diff --git a/packages/stream_chat_flutter/lib/src/localization/translations.dart b/packages/stream_chat_flutter/lib/src/localization/translations.dart index d6e5add0..4c86e6e2 100644 --- a/packages/stream_chat_flutter/lib/src/localization/translations.dart +++ b/packages/stream_chat_flutter/lib/src/localization/translations.dart @@ -100,6 +100,9 @@ abstract class Translations { /// The label for write a message in [MessageInput] String get writeAMessageLabel; + /// The label for slow mode enabled in [MessageInput] + String get slowModeOnLabel; + /// The label for instant commands in [MessageInput] String get instantCommandsLabel; @@ -664,4 +667,7 @@ class DefaultTranslations implements Translations { @override String get replyToMessageLabel => 'Reply to Message'; + + @override + String get slowModeOnLabel => 'Slow mode ON'; } diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index afff3d52..23e64642 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -835,6 +835,10 @@ class MessageInputState extends State { if (_attachments.isNotEmpty) { return context.translations.addACommentOrSendLabel; } + if(_timeOut != 0 && _timeOut != null) { + return context.translations.slowModeOnLabel; + } + return context.translations.writeAMessageLabel; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart index 5041d398..56f2ccfe 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart @@ -357,4 +357,7 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => 'Reply to Message'; + + @override + String get slowModeOnLabel => 'Slow mode ON'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart index b43e4ba8..5602a4a5 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart @@ -362,4 +362,7 @@ class StreamChatLocalizationsEs extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => 'Responder al Mensaje'; + + @override + String get slowModeOnLabel => 'Modo lento activado'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart index 9d8586d5..f3ab6070 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart @@ -361,4 +361,7 @@ class StreamChatLocalizationsFr extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => 'Répondre au Message'; + + @override + String get slowModeOnLabel => 'Mode lent activé'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart index 850e481b..386651cb 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart @@ -356,4 +356,7 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => 'संदेश का जवाब'; + + @override + String get slowModeOnLabel => 'स्लो मोड चालू'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart index 8b2e1692..cb82a690 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart @@ -358,4 +358,7 @@ Il file è troppo grande per essere caricato. Il limite è di $limitInMB MB.'''; @override String get replyToMessageLabel => 'Rispondi al messaggio'; + + @override + String get slowModeOnLabel => 'Modalità lenta attiva'; } From 00ea765959e7aea360f0d8e637714533e10e7288 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 18 Aug 2021 16:00:17 +0530 Subject: [PATCH 10/26] fix: it translations --- .../lib/src/stream_chat_localizations_it.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart index cb82a690..b3740f23 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart @@ -360,5 +360,5 @@ Il file è troppo grande per essere caricato. Il limite è di $limitInMB MB.'''; String get replyToMessageLabel => 'Rispondi al messaggio'; @override - String get slowModeOnLabel => 'Modalità lenta attiva'; + String get slowModeOnLabel => 'Slowmode attiva'; } From c2177fa7a55a52055473a84f3a48034025dcfd6f Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 18 Aug 2021 16:01:07 +0530 Subject: [PATCH 11/26] fmt --- packages/stream_chat_flutter/lib/src/message_input.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 23e64642..90a4b8fa 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -835,7 +835,7 @@ class MessageInputState extends State { if (_attachments.isNotEmpty) { return context.translations.addACommentOrSendLabel; } - if(_timeOut != 0 && _timeOut != null) { + if (_timeOut != 0 && _timeOut != null) { return context.translations.slowModeOnLabel; } From 2a30ff2e73140977aa6ca3808328cb06e592bae8 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 18 Aug 2021 16:08:20 +0530 Subject: [PATCH 12/26] fixes --- packages/stream_chat_flutter_core/test/channels_bloc_test.dart | 1 + .../stream_chat_localizations/example/lib/add_new_lang.dart | 3 +++ 2 files changed, 4 insertions(+) diff --git a/packages/stream_chat_flutter_core/test/channels_bloc_test.dart b/packages/stream_chat_flutter_core/test/channels_bloc_test.dart index a237a23c..2aee9eba 100644 --- a/packages/stream_chat_flutter_core/test/channels_bloc_test.dart +++ b/packages/stream_chat_flutter_core/test/channels_bloc_test.dart @@ -558,6 +558,7 @@ void main() { config: ChannelConfig(), createdAt: DateTime.now(), memberCount: 1, + cooldown: 0, ), ); diff --git a/packages/stream_chat_localizations/example/lib/add_new_lang.dart b/packages/stream_chat_localizations/example/lib/add_new_lang.dart index 8a1d196e..f7eb280e 100644 --- a/packages/stream_chat_localizations/example/lib/add_new_lang.dart +++ b/packages/stream_chat_localizations/example/lib/add_new_lang.dart @@ -381,6 +381,9 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => 'Reply to Message'; + + @override + String get slowModeOnLabel => 'Slow mode ON'; } void main() async { From a029adae249bae2b44abd7ae008eeef8f7ea27a4 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 18 Aug 2021 17:30:15 +0530 Subject: [PATCH 13/26] fixes --- packages/stream_chat_flutter/lib/src/message_input.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 90a4b8fa..7b6d2936 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -363,7 +363,6 @@ class MessageInputState extends State { if (_timeOut == 0) { timer.cancel(); } else { - print('Time left until cooldown is over: $_timeOut'); setState(() => _timeOut = _timeOut! - 1); } }); From 170f18093ed296002de1b32b3d4b85bfe357df62 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 18 Aug 2021 17:31:44 +0530 Subject: [PATCH 14/26] Update packages/stream_chat/lib/src/client/channel.dart --- packages/stream_chat/lib/src/client/channel.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 5dfcb4f9..3190dc1b 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -213,7 +213,7 @@ class Channel { return state?.channelStateStream.map((cs) => cs.channel?.cooldown); } - /// + /// Stores time at which cooldown was started DateTime? cooldownStartedAt; /// Channel creation date. From b920919e0f872ea9d808cfe15156cc5d1ba0bb7a Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Thu, 19 Aug 2021 17:20:59 +0530 Subject: [PATCH 15/26] added tests --- .../test/src/api/channel_test.dart | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/stream_chat/test/src/api/channel_test.dart b/packages/stream_chat/test/src/api/channel_test.dart index 7c5386c6..6afa60c2 100644 --- a/packages/stream_chat/test/src/api/channel_test.dart +++ b/packages/stream_chat/test/src/api/channel_test.dart @@ -1859,6 +1859,52 @@ void main() { ).called(1); }); + test('`.enableSlowMode`', () async { + final channelModel = ChannelModel( + cid: channelCid, + cooldown: 10, + ); + + when(() => client.enableSlowdown( + channelCid, + channelType, + 10, + )).thenAnswer((_) async => PartialUpdateChannelResponse() + ..channel = channelModel); + + final res = await channel.enableSlowMode(cooldownInterval: 10); + + expect(res, isNotNull); + + verify(() => client.enableSlowdown( + channelCid, + channelType, + any(), + )).called(1); + }); + + test('`.disableSlowMode`', () async { + final channelModel = ChannelModel( + cid: channelCid, + cooldown: 0, + ); + + when(() => client.disableSlowdown( + channelCid, + channelType, + )).thenAnswer((_) async => PartialUpdateChannelResponse() + ..channel = channelModel); + + final res = await channel.disableSlowMode(); + + expect(res, isNotNull); + + verify(() => client.disableSlowdown( + channelCid, + channelType, + )).called(1); + }); + test('`.banUser`', () async { const userId = 'test-user-id'; const options = {'key': 'value'}; From ddf33a19897641d874dd716e500565887e5b235a Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Thu, 19 Aug 2021 17:50:37 +0530 Subject: [PATCH 16/26] added tests --- .../test/src/api/channel_test.dart | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/stream_chat/test/src/api/channel_test.dart b/packages/stream_chat/test/src/api/channel_test.dart index 6afa60c2..08ebd091 100644 --- a/packages/stream_chat/test/src/api/channel_test.dart +++ b/packages/stream_chat/test/src/api/channel_test.dart @@ -1860,15 +1860,17 @@ void main() { }); test('`.enableSlowMode`', () async { + const cooldown = 10; + final channelModel = ChannelModel( cid: channelCid, - cooldown: 10, + cooldown: cooldown, ); when(() => client.enableSlowdown( - channelCid, + channelId, channelType, - 10, + cooldown, )).thenAnswer((_) async => PartialUpdateChannelResponse() ..channel = channelModel); @@ -1877,32 +1879,28 @@ void main() { expect(res, isNotNull); verify(() => client.enableSlowdown( - channelCid, + channelId, channelType, - any(), + cooldown, )).called(1); }); test('`.disableSlowMode`', () async { final channelModel = ChannelModel( cid: channelCid, - cooldown: 0, ); when(() => client.disableSlowdown( - channelCid, - channelType, - )).thenAnswer((_) async => PartialUpdateChannelResponse() + channelId, + channelType, + )).thenAnswer((_) async => PartialUpdateChannelResponse() ..channel = channelModel); final res = await channel.disableSlowMode(); expect(res, isNotNull); - verify(() => client.disableSlowdown( - channelCid, - channelType, - )).called(1); + verify(() => client.disableSlowdown(channelId, channelType)).called(1); }); test('`.banUser`', () async { From 5cd59f2277431cf2c8842a0e82702531bee485b3 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Thu, 19 Aug 2021 18:03:34 +0530 Subject: [PATCH 17/26] fix: timer dispose, added widget test --- .../lib/src/message_input.dart | 5 +- .../test/src/message_input_test.dart | 65 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 7b6d2936..e97e1364 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -318,6 +318,8 @@ class MessageInputState extends State { late DateTime? _cooldownStartedAt; int? _timeOut; + Timer? slowModeTimer; + @override void initState() { super.initState(); @@ -359,7 +361,7 @@ class MessageInputState extends State { StreamChannel.of(context).channel.cooldown!) { _timeOut = StreamChannel.of(context).channel.cooldown! - DateTime.now().difference(_cooldownStartedAt!).inSeconds; - Timer.periodic(const Duration(seconds: 1), (timer) { + slowModeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { if (_timeOut == 0) { timer.cancel(); } else { @@ -2265,6 +2267,7 @@ class MessageInputState extends State { _emojiOverlay?.remove(); _mentionsOverlay?.remove(); _keyboardListener?.cancel(); + slowModeTimer?.cancel(); super.dispose(); } diff --git a/packages/stream_chat_flutter/test/src/message_input_test.dart b/packages/stream_chat_flutter/test/src/message_input_test.dart index 679fb7f3..62fe0107 100644 --- a/packages/stream_chat_flutter/test/src/message_input_test.dart +++ b/packages/stream_chat_flutter/test/src/message_input_test.dart @@ -69,4 +69,69 @@ void main() { expect(find.byKey(const Key('messageInputText')), findsOneWidget); }, ); + + testWidgets( + 'checks message input slow mode', + (WidgetTester tester) async { + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel(); + final channelState = MockChannelState(); + final lastMessageAt = DateTime.parse('2020-06-22 12:00:00'); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); + when(() => channel.lastMessageAt).thenReturn(lastMessageAt); + when(() => channel.state).thenReturn(channelState); + when(() => channel.cooldown).thenReturn(10); + when(() => channel.cooldownStartedAt).thenReturn(DateTime.now()); + when(() => channel.client).thenReturn(client); + when(() => channel.isMuted).thenReturn(false); + when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false)); + when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({ + 'name': 'test', + })); + when(() => channel.extraData).thenReturn({ + 'name': 'test', + }); + when(() => channelState.membersStream).thenAnswer((i) => Stream.value([ + Member( + userId: 'user-id', + user: User(id: 'user-id'), + ) + ])); + when(() => channelState.members).thenReturn([ + Member( + userId: 'user-id', + user: User(id: 'user-id'), + ), + ]); + when(() => channelState.messages).thenReturn([ + Message( + text: 'hello', + user: User(id: 'other-user'), + ) + ]); + when(() => channelState.messagesStream).thenAnswer((i) => Stream.value([ + Message( + text: 'hello', + user: User(id: 'other-user'), + ) + ])); + + await tester.pumpWidget(MaterialApp( + home: StreamChat( + client: client, + child: StreamChannel( + channel: channel, + child: const Scaffold( + body: MessageInput(), + ), + ), + ), + )); + + expect(find.text('Slow mode ON'), findsOneWidget); + }, + ); } From 4cec36a7231bf39fc30523855d43f976a9e8349a Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Thu, 19 Aug 2021 18:13:18 +0530 Subject: [PATCH 18/26] fix: analysis --- packages/stream_chat_flutter/lib/src/message_input.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index e97e1364..de7c2788 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -318,7 +318,7 @@ class MessageInputState extends State { late DateTime? _cooldownStartedAt; int? _timeOut; - Timer? slowModeTimer; + Timer? _slowModeTimer; @override void initState() { @@ -361,7 +361,7 @@ class MessageInputState extends State { StreamChannel.of(context).channel.cooldown!) { _timeOut = StreamChannel.of(context).channel.cooldown! - DateTime.now().difference(_cooldownStartedAt!).inSeconds; - slowModeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { + _slowModeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { if (_timeOut == 0) { timer.cancel(); } else { @@ -2267,7 +2267,7 @@ class MessageInputState extends State { _emojiOverlay?.remove(); _mentionsOverlay?.remove(); _keyboardListener?.cancel(); - slowModeTimer?.cancel(); + _slowModeTimer?.cancel(); super.dispose(); } From 26407a0f15567f9b1c2699b242181397b8d08bf4 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 20 Aug 2021 11:03:04 +0200 Subject: [PATCH 19/26] rename test folder --- packages/stream_chat/test/src/{api => client}/channel_test.dart | 0 packages/stream_chat/test/src/{api => client}/client_test.dart | 0 .../stream_chat/test/src/{api => client}/retry_queue_test.dart | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename packages/stream_chat/test/src/{api => client}/channel_test.dart (100%) rename packages/stream_chat/test/src/{api => client}/client_test.dart (100%) rename packages/stream_chat/test/src/{api => client}/retry_queue_test.dart (100%) diff --git a/packages/stream_chat/test/src/api/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart similarity index 100% rename from packages/stream_chat/test/src/api/channel_test.dart rename to packages/stream_chat/test/src/client/channel_test.dart diff --git a/packages/stream_chat/test/src/api/client_test.dart b/packages/stream_chat/test/src/client/client_test.dart similarity index 100% rename from packages/stream_chat/test/src/api/client_test.dart rename to packages/stream_chat/test/src/client/client_test.dart diff --git a/packages/stream_chat/test/src/api/retry_queue_test.dart b/packages/stream_chat/test/src/client/retry_queue_test.dart similarity index 100% rename from packages/stream_chat/test/src/api/retry_queue_test.dart rename to packages/stream_chat/test/src/client/retry_queue_test.dart From 6cf63fe3ca899bf8606830e26b9c549f2141ef61 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Aug 2021 16:10:01 +0530 Subject: [PATCH 20/26] added tests --- .../test/src/core/api/channel_api_test.dart | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/packages/stream_chat/test/src/core/api/channel_api_test.dart b/packages/stream_chat/test/src/core/api/channel_api_test.dart index 8ffd778d..8dd6a3f4 100644 --- a/packages/stream_chat/test/src/core/api/channel_api_test.dart +++ b/packages/stream_chat/test/src/core/api/channel_api_test.dart @@ -605,4 +605,69 @@ void main() { verify(() => client.post(path, data: {})).called(1); verifyNoMoreInteractions(client); }); + + test('enableSlowdown', () async { + const channelId = 'test-channel-id'; + const channelType = 'test-channel-type'; + const cooldown = 10; + const set = { + 'ccooldown': 10, + }; + + final path = _getChannelUrl(channelId, channelType); + + final channelModel = ChannelModel( + id: channelId, + type: channelType, + extraData: set, + ); + + when(() => client.patch(path, data: { + 'set': { + 'cooldown': cooldown, + }, + })).thenAnswer((_) async => successResponse(path, data: { + 'channel': channelModel.toJson(), + })); + + final res = + await channelApi.enableSlowdown(channelId, channelType, cooldown); + + expect(res, isNotNull); + + verify(() => client.patch(path, data: { + 'set': { + 'cooldown': cooldown, + }, + })).called(1); + verifyNoMoreInteractions(client); + }); + + test('disableSlowdown', () async { + const channelId = 'test-channel-id'; + const channelType = 'test-channel-type'; + const unset = ['cooldown']; + + final path = _getChannelUrl(channelId, channelType); + + final channelModel = ChannelModel( + id: channelId, + type: channelType, + ); + + when(() => client.patch(path, data: { + 'unset': unset, + })).thenAnswer((_) async => successResponse(path, data: { + 'channel': channelModel.toJson(), + })); + + final res = await channelApi.disableSlowdown(channelId, channelType); + + expect(res, isNotNull); + + verify(() => client.patch(path, data: { + 'unset': unset, + })).called(1); + verifyNoMoreInteractions(client); + }); } From feac07057a45e5d70851c1b5f7ec423ec2ce4c67 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Aug 2021 16:10:48 +0530 Subject: [PATCH 21/26] removed comments --- .../lib/src/message_input.dart | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index de7c2788..7c67c4d3 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -536,36 +536,10 @@ class MessageInputState extends State { : _buildSendButton(context); } - /*if (_timeOut == null || _timeOut == 0) { - sendButton = widget.activeSendButton != null - ? InkWell( - onTap: sendMessage, - child: widget.activeSendButton, - ) - : _buildSendButton(context); - } else { - sendButton = _CountdownButton( - count: _timeOut!, - ); - } - - if (!_messageIsPresent && _attachments.isEmpty) { - sendButton = widget.idleSendButton ?? _buildIdleSendButton(context); - }*/ - return AnimatedSwitcher( duration: _streamChatTheme.messageInputTheme.sendAnimationDuration!, child: sendButton, ); - /*return AnimatedCrossFade( - crossFadeState: (_messageIsPresent || _attachments.isNotEmpty) - ? CrossFadeState.showFirst - : CrossFadeState.showSecond, - firstChild: sendButton, - secondChild: widget.idleSendButton ?? _buildIdleSendButton(context), - duration: _messageInputTheme.sendAnimationDuration!, - alignment: Alignment.center, - );*/ } Widget _buildExpandActionsButton(BuildContext context) { From b7ba8b5e854ce9d6ccbb6a77670d865200ef091f Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Aug 2021 16:13:46 +0530 Subject: [PATCH 22/26] fixed test --- .../test/src/core/api/channel_api_test.dart | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/stream_chat/test/src/core/api/channel_api_test.dart b/packages/stream_chat/test/src/core/api/channel_api_test.dart index 8dd6a3f4..9110845d 100644 --- a/packages/stream_chat/test/src/core/api/channel_api_test.dart +++ b/packages/stream_chat/test/src/core/api/channel_api_test.dart @@ -611,7 +611,7 @@ void main() { const channelType = 'test-channel-type'; const cooldown = 10; const set = { - 'ccooldown': 10, + 'cooldown': 10, }; final path = _getChannelUrl(channelId, channelType); @@ -623,9 +623,7 @@ void main() { ); when(() => client.patch(path, data: { - 'set': { - 'cooldown': cooldown, - }, + 'set': set, })).thenAnswer((_) async => successResponse(path, data: { 'channel': channelModel.toJson(), })); @@ -636,9 +634,7 @@ void main() { expect(res, isNotNull); verify(() => client.patch(path, data: { - 'set': { - 'cooldown': cooldown, - }, + 'set': set, })).called(1); verifyNoMoreInteractions(client); }); From fea90d4afdbc25151678ab2dd71266a53b067c5d Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Aug 2021 16:20:56 +0530 Subject: [PATCH 23/26] added japanese and korean localizations --- .../lib/src/stream_chat_localizations_ja.dart | 3 +++ .../lib/src/stream_chat_localizations_ko.dart | 3 +++ 2 files changed, 6 insertions(+) diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart index e6946125..21fc48fa 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart @@ -346,4 +346,7 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => 'メッセージに返信'; + + @override + String get slowModeOnLabel => 'スローモードオン'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart index 2642b991..a933ddb0 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart @@ -344,4 +344,7 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => '메시지에 회신합니다.'; + + @override + String get slowModeOnLabel => '느린 모드 켜짐'; } From 071b337194dedaea4999d4d2e9f9bb9de29b6d5d Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 20 Aug 2021 14:40:41 +0200 Subject: [PATCH 24/26] call streamchannel.of just once --- packages/stream_chat_flutter/lib/src/message_input.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 7c67c4d3..388df21b 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -355,11 +355,12 @@ class MessageInputState extends State { } void _startSlowMode() { - if (StreamChannel.of(context).channel.cooldownStartedAt != null) { - _cooldownStartedAt = StreamChannel.of(context).channel.cooldownStartedAt; + final channel = StreamChannel.of(context).channel; + if (channel.cooldownStartedAt != null) { + _cooldownStartedAt = channel.cooldownStartedAt; if (DateTime.now().difference(_cooldownStartedAt!).inSeconds < - StreamChannel.of(context).channel.cooldown!) { - _timeOut = StreamChannel.of(context).channel.cooldown! - + channel.cooldown!) { + _timeOut = channel.cooldown! - DateTime.now().difference(_cooldownStartedAt!).inSeconds; _slowModeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { if (_timeOut == 0) { From 80aaef037a8180c619ae75010397d784511f7029 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 20 Aug 2021 17:12:26 +0200 Subject: [PATCH 25/26] Update packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart --- .../lib/src/stream_chat_localizations_ko.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart index a933ddb0..49015674 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart @@ -346,5 +346,5 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations { String get replyToMessageLabel => '메시지에 회신합니다.'; @override - String get slowModeOnLabel => '느린 모드 켜짐'; + String get slowModeOnLabel => '슬로모드 켜짐'; } From 0f8418dd29a660fe92fa91207371b3db75eda796 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 23 Aug 2021 13:07:23 +0530 Subject: [PATCH 26/26] added changelog --- packages/stream_chat/CHANGELOG.md | 1 + packages/stream_chat_flutter/CHANGELOG.md | 2 ++ packages/stream_chat_localizations/CHANGELOG.md | 1 + 3 files changed, 4 insertions(+) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 52496a96..85bc73ef 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -10,6 +10,7 @@ - `User` and `OwnUser` classes now have a `name` property. Setting a name will also set the 'name' key on `extraData`, so `user.name` and `user.extraData['name']` is the same. - `Channel` class now has extra `image` getter and setter. As well as an `updateImage` to do a partial update after a channel has been initialized. - `Channel` class now has extra `name` getter and setter. As well as an `updateName` to do a partial update after a channel has been initialized. +- Added slow mode which allows a cooldown period after a user sends a message. ## 2.1.1 🐞 Fixed diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index b21acc7a..e9dfe04b 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -25,6 +25,8 @@ typedef ActionButtonBuilder = Widget Function( > **_NOTE:_** The last parameter is the default `ActionButton` You can call `.copyWith` to customize just a subset of properties. +- Added slow mode which allows a cooldown period after a user sends a message. + 🔄 Changed Theming has been upgraded! Most theme classes now have `InheritedTheme` classes associated with diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index d718ce12..8e13d154 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -5,6 +5,7 @@ * Added support for [Spanish](https://github.com/GetStream/stream-chat-flutter/blob/master/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart) locale. * Added support for [Korean](https://github.com/GetStream/stream-chat-flutter/blob/master/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart) locale. * Added support for [Japanese](https://github.com/GetStream/stream-chat-flutter/blob/master/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart) locale. +* Added strings for cooldown mode. 🔄 Changed