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/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 3285db75..22738794 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -201,6 +201,21 @@ class Channel { return state!.channelStateStream.map((cs) => cs.channel?.frozen == true); } + /// Cooldown count + int? get cooldown { + _checkInitialized(); + return state?._channelState.channel?.cooldown; + } + + /// Cooldown count as a stream + Stream? get cooldownStream { + _checkInitialized(); + return state?.channelStateStream.map((cs) => cs.channel?.cooldown); + } + + /// Stores time at which cooldown was started + DateTime? cooldownStartedAt; + /// Channel creation date. DateTime? get createdAt { _checkInitialized(); @@ -525,6 +540,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) { @@ -980,6 +998,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 74abcb39..f9d10a92 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -1252,6 +1252,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 c04f9683..68f0d1c3 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 updateChannelPartial( + channelId, + channelType, + set: { + 'cooldown': cooldown, + }, + ); + return response; + } + + /// Disable slowdown + Future disableSlowdown( + String channelId, + String channelType, + ) async { + final response = await updateChannelPartial( + channelId, + channelType, + unset: ['cooldown'], + ); + return response; + } + /// 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 37e587ff..a4e6db79 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,10 @@ class ChannelModel { @JsonKey(includeIfNull: false, toJson: Serializer.readOnly, defaultValue: 0) final int memberCount; + /// The number of seconds in a cooldown + @JsonKey(includeIfNull: false, defaultValue: 0) + final int cooldown; + /// Map of custom channel extraData @JsonKey( includeIfNull: false, @@ -107,6 +112,7 @@ class ChannelModel { 'deleted_at', 'member_count', 'team', + 'cooldown', ]; /// Shortcut for channel name @@ -133,6 +139,7 @@ class ChannelModel { int? memberCount, Map? extraData, String? team, + int? cooldown, }) => ChannelModel( id: id ?? this.id, @@ -148,6 +155,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 +176,7 @@ class ChannelModel { memberCount: other.memberCount, extraData: other.extraData, team: other.team, + cooldown: other.cooldown, ); } } 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/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/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/api/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart similarity index 98% rename from packages/stream_chat/test/src/api/channel_test.dart rename to packages/stream_chat/test/src/client/channel_test.dart index 7c5386c6..08ebd091 100644 --- a/packages/stream_chat/test/src/api/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -1859,6 +1859,50 @@ void main() { ).called(1); }); + test('`.enableSlowMode`', () async { + const cooldown = 10; + + final channelModel = ChannelModel( + cid: channelCid, + cooldown: cooldown, + ); + + when(() => client.enableSlowdown( + channelId, + channelType, + cooldown, + )).thenAnswer((_) async => PartialUpdateChannelResponse() + ..channel = channelModel); + + final res = await channel.enableSlowMode(cooldownInterval: 10); + + expect(res, isNotNull); + + verify(() => client.enableSlowdown( + channelId, + channelType, + cooldown, + )).called(1); + }); + + test('`.disableSlowMode`', () async { + final channelModel = ChannelModel( + cid: channelCid, + ); + + when(() => client.disableSlowdown( + channelId, + channelType, + )).thenAnswer((_) async => PartialUpdateChannelResponse() + ..channel = channelModel); + + final res = await channel.disableSlowMode(); + + expect(res, isNotNull); + + verify(() => client.disableSlowdown(channelId, channelType)).called(1); + }); + test('`.banUser`', () async { const userId = 'test-user-id'; const options = {'key': 'value'}; 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 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..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 @@ -605,4 +605,65 @@ 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 = { + 'cooldown': 10, + }; + + final path = _getChannelUrl(channelId, channelType); + + final channelModel = ChannelModel( + id: channelId, + type: channelType, + extraData: set, + ); + + when(() => client.patch(path, data: { + 'set': set, + })).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': set, + })).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); + }); } 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..e27f5970 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', () { @@ -24,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', + }, ); }); @@ -38,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', + }, ); }); }); diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 3b1875dd..71be8396 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_flutter/lib/src/localization/translations.dart b/packages/stream_chat_flutter/lib/src/localization/translations.dart index d3b3e8cb..e603656c 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; @@ -667,4 +670,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 2adae0bd..388df21b 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -315,9 +315,15 @@ class MessageInputState extends State { bool get _hasQuotedMessage => widget.quotedMessage != null; + late DateTime? _cooldownStartedAt; + int? _timeOut; + + Timer? _slowModeTimer; + @override void initState() { super.initState(); + _startSlowMode(); _focusNode = widget.focusNode ?? FocusNode(); _emojiNames = Emoji.all().where((it) => it.name != null).map((e) => e.name!); @@ -348,6 +354,25 @@ class MessageInputState extends State { }); } + void _startSlowMode() { + final channel = StreamChannel.of(context).channel; + if (channel.cooldownStartedAt != null) { + _cooldownStartedAt = channel.cooldownStartedAt; + if (DateTime.now().difference(_cooldownStartedAt!).inSeconds < + channel.cooldown!) { + _timeOut = channel.cooldown! - + DateTime.now().difference(_cooldownStartedAt!).inSeconds; + _slowModeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { + if (_timeOut == 0) { + timer.cancel(); + } else { + setState(() => _timeOut = _timeOut! - 1); + } + }); + } + } + } + @override Widget build(BuildContext context) { Widget child = DecoratedBox( @@ -496,20 +521,25 @@ class MessageInputState extends State { ); Widget _animateSendButton(BuildContext context) { - final sendButton = widget.activeSendButton != null - ? InkWell( - onTap: sendMessage, - child: widget.activeSendButton, - ) - : _buildSendButton(context); - return AnimatedCrossFade( - crossFadeState: (_messageIsPresent || _attachments.isNotEmpty) - ? CrossFadeState.showFirst - : CrossFadeState.showSecond, - firstChild: sendButton, - secondChild: widget.idleSendButton ?? _buildIdleSendButton(context), - duration: _messageInputTheme.sendAnimationDuration!, - alignment: Alignment.center, + 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); + } + + return AnimatedSwitcher( + duration: _streamChatTheme.messageInputTheme.sendAnimationDuration!, + child: sendButton, ); } @@ -781,6 +811,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; } @@ -2115,6 +2149,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) { @@ -2207,6 +2242,7 @@ class MessageInputState extends State { _emojiOverlay?.remove(); _mentionsOverlay?.remove(); _keyboardListener?.cancel(); + _slowModeTimer?.cancel(); super.dispose(); } @@ -2380,3 +2416,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/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); + }, + ); } 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/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 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 1efe6c95..eced0616 100644 --- a/packages/stream_chat_localizations/example/lib/add_new_lang.dart +++ b/packages/stream_chat_localizations/example/lib/add_new_lang.dart @@ -383,6 +383,9 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => 'Reply to Message'; + + @override + String get slowModeOnLabel => 'Slow mode ON'; } void main() async { 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 13de9729..aa9b4249 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 @@ -359,4 +359,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 7082ebf0..7244e3d0 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 @@ -364,4 +364,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 2331b522..0a0b551a 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 @@ -363,4 +363,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 975e8097..5da076af 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 @@ -358,4 +358,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 313e1e26..84cf76f6 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,4 +360,7 @@ Il file è troppo grande per essere caricato. Il limite è di $limitInMB MB.'''; @override String get replyToMessageLabel => 'Rispondi al messaggio'; + + @override + String get slowModeOnLabel => 'Slowmode attiva'; } 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..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 @@ -344,4 +344,7 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations { @override String get replyToMessageLabel => '메시지에 회신합니다.'; + + @override + String get slowModeOnLabel => '슬로모드 켜짐'; }