Skip to content

Commit 8262772

Browse files
authored
feat(ui): composer also send to channel (#2537)
* Improve layout for 'send as dm' * Remove unused imports * remove use of default color * Changed hideSendAsDm in canAlsoSendToChannelFromThread * fix typo
1 parent c4ea35a commit 8262772

9 files changed

Lines changed: 58 additions & 54 deletions

File tree

melos.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ command:
9595
stream_core_flutter:
9696
git:
9797
url: https://github.com/GetStream/stream-core-flutter.git
98-
ref: 213dfb64b1d0c22a668a4a0924503703ff9a33e9
98+
ref: 2959ed4323d189c1c43930964726f8d219e5dd94
9999
path: packages/stream_core_flutter
100100
synchronized: ^3.1.0+1
101101
thumblr: ^0.0.4

packages/stream_chat_flutter/lib/src/components/message_composer/stream_chat_message_composer.dart

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:stream_chat_flutter/src/components/message_composer/message_comp
77
import 'package:stream_chat_flutter/src/components/message_composer/message_composer_recording_locked.dart';
88
import 'package:stream_chat_flutter/src/components/message_composer/message_composer_recording_ongoing.dart';
99
import 'package:stream_chat_flutter/src/components/message_composer/message_composer_trailing.dart';
10+
import 'package:stream_chat_flutter/src/message_input/dm_checkbox_list_tile.dart';
1011
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
1112
import 'package:stream_core_flutter/stream_core_flutter.dart' as core;
1213

@@ -33,6 +34,7 @@ class StreamChatMessageComposer extends StatefulWidget {
3334
StreamAudioRecorderController? audioRecorderController,
3435
bool sendVoiceRecordingAutomatically = false,
3536
AudioRecorderFeedback feedback = const AudioRecorderFeedback(),
37+
bool canAlsoSendToChannel = false,
3638
}) : props = MessageComposerProps(
3739
controller: controller,
3840
isFloating: false,
@@ -46,6 +48,7 @@ class StreamChatMessageComposer extends StatefulWidget {
4648
audioRecorderController: audioRecorderController,
4749
sendVoiceRecordingAutomatically: sendVoiceRecordingAutomatically,
4850
feedback: feedback,
51+
canAlsoSendToChannel: canAlsoSendToChannel,
4952
);
5053

5154
/// The controller for the message composer.
@@ -176,6 +179,7 @@ class MessageComposerProps {
176179
this.audioRecorderController,
177180
this.sendVoiceRecordingAutomatically = false,
178181
this.feedback = const AudioRecorderFeedback(),
182+
this.canAlsoSendToChannel = false,
179183
});
180184

181185
/// The controller for the message composer.
@@ -216,6 +220,10 @@ class MessageComposerProps {
216220

217221
/// The feedback for the audio recorder.
218222
final AudioRecorderFeedback feedback;
223+
224+
/// Whether the user can also send the message as a direct message.
225+
/// Usually used in threads.
226+
final bool canAlsoSendToChannel;
219227
}
220228

221229
extension on StreamAudioRecorderController {
@@ -290,7 +298,29 @@ class DefaultStreamChatMessageComposer extends StatelessWidget {
290298
inputLeading: StreamMessageComposerInputLeading(
291299
props: componentProps,
292300
),
293-
inputBody: body,
301+
inputBody:
302+
body ??
303+
Column(
304+
mainAxisSize: MainAxisSize.min,
305+
children: [
306+
core.StreamMessageComposerInputField(
307+
controller: inputController.textFieldController,
308+
placeholder: props.placeholder,
309+
focusNode: props.focusNode,
310+
),
311+
if (props.canAlsoSendToChannel)
312+
DmCheckboxListTile(
313+
value: props.controller?.showInChannel ?? false,
314+
// height of list tile is 34px, height of checkbox is 16px, so we need to subtract 8px to make the spacing correct.
315+
contentPadding: EdgeInsets.only(
316+
right: context.streamSpacing.md,
317+
left: context.streamSpacing.md,
318+
bottom: context.streamSpacing.md - 8,
319+
),
320+
onChanged: (value) => props.controller?.showInChannel = value,
321+
),
322+
],
323+
),
294324
);
295325
}
296326

packages/stream_chat_flutter/lib/src/localization/translations.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ class DefaultTranslations implements Translations {
670670
String get reconnectingLabel => 'Reconnecting...';
671671

672672
@override
673-
String get alsoSendAsDirectMessageLabel => 'Also send as direct message';
673+
String get alsoSendAsDirectMessageLabel => 'Also send in Channel';
674674

675675
@override
676676
String get addACommentOrSendLabel => 'Add a comment or send';

packages/stream_chat_flutter/lib/src/message_input/dm_checkbox_list_tile.dart

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'package:flutter/material.dart';
2-
import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart';
3-
import 'package:stream_chat_flutter/src/utils/extensions.dart';
2+
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
3+
import 'package:stream_core_flutter/stream_core_flutter.dart';
44

55
/// {@template dmCheckboxListTile}
66
/// A widget that represents a checkbox list tile for direct message input.
@@ -25,37 +25,21 @@ class DmCheckboxListTile extends StatelessWidget {
2525

2626
@override
2727
Widget build(BuildContext context) {
28-
final theme = StreamChatTheme.of(context);
29-
final textTheme = theme.textTheme;
30-
final colorTheme = theme.colorTheme;
28+
final textTheme = context.streamTextTheme;
3129

3230
const visualDensity = VisualDensity(
3331
vertical: VisualDensity.minimumDensity,
3432
horizontal: VisualDensity.minimumDensity,
3533
);
3634

3735
final checkbox = ExcludeFocus(
38-
child: CheckboxTheme(
39-
data: CheckboxThemeData(
40-
overlayColor: WidgetStatePropertyAll(
41-
colorTheme.accentPrimary.withAlpha(kRadialReactionAlpha),
42-
),
43-
),
44-
child: Checkbox(
45-
value: value,
46-
visualDensity: visualDensity,
47-
activeColor: colorTheme.accentPrimary,
48-
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
49-
side: BorderSide(width: 2, color: colorTheme.textLowEmphasis),
50-
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(3)),
51-
onChanged: switch (onChanged) {
52-
final onChanged? => (value) {
53-
if (value == null) return;
54-
return onChanged.call(value);
55-
},
56-
_ => null,
57-
},
58-
),
36+
child: StreamCheckbox(
37+
value: value,
38+
size: StreamCheckboxSize.sm,
39+
onChanged: switch (onChanged) {
40+
final onChanged? => onChanged.call,
41+
_ => null,
42+
},
5943
),
6044
);
6145

@@ -70,10 +54,7 @@ class DmCheckboxListTile extends StatelessWidget {
7054
contentPadding: contentPadding,
7155
title: Text(
7256
context.translations.alsoSendAsDirectMessageLabel,
73-
style: textTheme.footnote.copyWith(
74-
// ignore: deprecated_member_use
75-
color: colorTheme.textHighEmphasis.withOpacity(0.5),
76-
),
57+
style: textTheme.metadataDefault,
7758
),
7859
),
7960
);

packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import 'package:flutter_portal/flutter_portal.dart';
1111
import 'package:stream_chat_flutter/platform_widget_builder/src/platform_widget_builder.dart';
1212
import 'package:stream_chat_flutter/src/message_input/attachment_button.dart';
1313
import 'package:stream_chat_flutter/src/message_input/command_button.dart';
14-
import 'package:stream_chat_flutter/src/message_input/dm_checkbox_list_tile.dart';
1514
import 'package:stream_chat_flutter/src/message_input/quoting_message_top_area.dart';
1615
import 'package:stream_chat_flutter/src/message_input/stream_message_input_icon_button.dart';
1716
import 'package:stream_chat_flutter/src/message_input/tld.dart';
@@ -127,7 +126,7 @@ class StreamMessageInput extends StatefulWidget {
127126
this.focusNode,
128127
this.sendButtonLocation = SendButtonLocation.outside,
129128
this.autofocus = false,
130-
this.hideSendAsDm = false,
129+
this.canAlsoSendToChannelFromThread = true,
131130
this.enableVoiceRecording = false,
132131
this.sendVoiceRecordingAutomatically = false,
133132
this.voiceRecordingFeedback = const AudioRecorderFeedback(),
@@ -219,8 +218,10 @@ class StreamMessageInput extends StatefulWidget {
219218
/// Use this property to hide/show the commands button.
220219
final bool showCommandsButton;
221220

222-
/// Hide send as dm checkbox.
223-
final bool hideSendAsDm;
221+
/// Show the checkbox to send the message as a direct message to the channel.
222+
///
223+
/// Defaults to true.
224+
final bool canAlsoSendToChannelFromThread;
224225

225226
/// If true the voice recording button will be displayed.
226227
///
@@ -789,9 +790,9 @@ class StreamMessageInputState extends State<StreamMessageInput> with Restoration
789790
placeholder: _getHint(context) ?? '',
790791
focusNode: focusNode,
791792
onSendPressed: sendMessage,
792-
audioRecorderController: _audioRecorderController,
793+
canAlsoSendToChannel: _shouldShowSendToChannelCheckbox(),
794+
audioRecorderController: widget.enableVoiceRecording ? _audioRecorderController : null,
793795
),
794-
_buildDmCheckbox(context),
795796
_buildInlineAttachmentPicker(context),
796797
].nonNulls.toList(),
797798
),
@@ -855,19 +856,11 @@ class StreamMessageInputState extends State<StreamMessageInput> with Restoration
855856
return null;
856857
}
857858

858-
Widget? _buildDmCheckbox(BuildContext context) {
859-
if (widget.hideSendAsDm) return null;
859+
bool _shouldShowSendToChannelCheckbox() {
860+
if (!widget.canAlsoSendToChannelFromThread) return false;
860861

861862
final insideThread = _effectiveController.message.parentId != null;
862-
if (!insideThread) return null;
863-
864-
return DmCheckboxListTile(
865-
value: _effectiveController.showInChannel,
866-
contentPadding: EdgeInsets.symmetric(
867-
horizontal: context.streamSpacing.md,
868-
),
869-
onChanged: (value) => _effectiveController.showInChannel = value,
870-
);
863+
return insideThread;
871864
}
872865

873866
Widget _buildNoPermissionMessage(BuildContext context) {

packages/stream_chat_flutter/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ dependencies:
6262
stream_core_flutter:
6363
git:
6464
url: https://github.com/GetStream/stream-core-flutter.git
65-
ref: 213dfb64b1d0c22a668a4a0924503703ff9a33e9
65+
ref: 2959ed4323d189c1c43930964726f8d219e5dd94
6666
path: packages/stream_core_flutter
6767
svg_icon_widget: ^0.0.1
6868
synchronized: ^3.1.0+1

packages/stream_chat_flutter/test/src/message_input/message_input_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ void main() {
539539
channel: channel,
540540
child: const Scaffold(
541541
bottomNavigationBar: StreamMessageInput(
542-
hideSendAsDm: true,
542+
canAlsoSendToChannelFromThread: false,
543543
),
544544
),
545545
),

packages/stream_chat_localizations/example/lib/add_new_lang.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations {
132132
String get reconnectingLabel => 'Reconnecting...';
133133

134134
@override
135-
String get alsoSendAsDirectMessageLabel => 'Also send as direct message';
135+
String get alsoSendAsDirectMessageLabel => 'Also send in Channel';
136136

137137
@override
138138
String get addACommentOrSendLabel => 'Add a comment or send';

packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations {
112112
String get reconnectingLabel => 'Reconnecting...';
113113

114114
@override
115-
String get alsoSendAsDirectMessageLabel => 'Also send as direct message';
115+
String get alsoSendAsDirectMessageLabel => 'Also send in Channel';
116116

117117
@override
118118
String get addACommentOrSendLabel => 'Add a comment or send';

0 commit comments

Comments
 (0)