Skip to content

Commit 2e79624

Browse files
committed
feat: remove sentinel values
1 parent 440be0f commit 2e79624

File tree

17 files changed

+190
-265
lines changed

17 files changed

+190
-265
lines changed

examples/flyer_chat/lib/gemini.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class GeminiState extends State<Gemini> {
127127
index: index,
128128
showTime: false,
129129
showStatus: false,
130-
receivedBackgroundColor: null,
130+
receivedBackgroundColor: Colors.transparent,
131131
padding:
132132
message.authorId == _agent.id
133133
? EdgeInsets.zero
@@ -149,7 +149,7 @@ class GeminiState extends State<Gemini> {
149149
chunkAnimationDuration: _kChunkAnimationDuration,
150150
showTime: false,
151151
showStatus: false,
152-
receivedBackgroundColor: null,
152+
receivedBackgroundColor: Colors.transparent,
153153
padding:
154154
message.authorId == _agent.id
155155
? EdgeInsets.zero

examples/flyer_chat/lib/gemini_stream_manager.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,16 @@ class GeminiStreamManager extends ChangeNotifier {
4141
return; // Stream might have finished
4242
}
4343

44-
final trimmedChunk = chunk.trim(); // Trim the chunk
45-
if (trimmedChunk.isEmpty) {
46-
return; // Don't process empty chunks after trimming
44+
// Trim single trailing newline from the incoming chunk if present.
45+
var processedChunk = chunk;
46+
if (processedChunk.endsWith('\n') && !processedChunk.endsWith('\n\n')) {
47+
processedChunk = processedChunk.substring(0, processedChunk.length - 1);
4748
}
4849

50+
// Use the potentially processed chunk
4951
_accumulatedTexts[streamId] =
50-
(_accumulatedTexts[streamId] ?? '') + trimmedChunk;
52+
(_accumulatedTexts[streamId] ?? '') + processedChunk;
53+
5154
_streamStates[streamId] = StreamStateStreaming(
5255
_accumulatedTexts[streamId]!,
5356
);

examples/flyer_chat/lib/local.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class LocalState extends State<Local> {
5656
return Scaffold(
5757
appBar: AppBar(title: const Text('Local')),
5858
body: Chat(
59-
backgroundColor: null,
59+
backgroundColor: Colors.transparent,
6060
builders: Builders(
6161
chatAnimatedListBuilder: (context, itemBuilder) {
6262
return ChatAnimatedList(

packages/flutter_chat_ui/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- The `sending` field has been removed from the message model; instead, you can set `sending: true` in the metadata of the Message model to achieve the same functionality.
99
- The `isOnlyEmoji` property has been removed from the text message model; to indicate that a message contains only emojis, use `isOnlyEmoji: true` in the metadata of the text message.
1010
- The `firstName` and `lastName` fields in the `User` model have been consolidated into a single `name` field for improved simplicity.
11+
- The default sentinel values that previously allowed users to set specific properties to `null` have been removed. Instead, please use `Colors.transparent`, `BorderRadius.zero`, or `TextStyle()` to achieve the desired effect. Passing `null` will now use the standard configuration.
1112

1213
**⚠️ New Features ⚠️**
1314

packages/flutter_chat_ui/lib/src/chat.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import 'utils/load_more_notifier.dart';
1010
import 'utils/typedefs.dart';
1111

1212
class Chat extends StatefulWidget {
13-
static const Color _sentinelColor = Colors.transparent;
14-
1513
final UserID currentUserId;
1614
final ResolveUserCallback resolveUser;
1715
final ChatController chatController;
@@ -38,7 +36,7 @@ class Chat extends StatefulWidget {
3836
this.onMessageTap,
3937
this.onMessageLongPress,
4038
this.onAttachmentTap,
41-
this.backgroundColor = _sentinelColor,
39+
this.backgroundColor,
4240
this.decoration,
4341
this.timeFormat,
4442
});
@@ -109,9 +107,9 @@ class _ChatState extends State<Chat> with WidgetsBindingObserver {
109107
],
110108
child: Container(
111109
color:
112-
widget.backgroundColor == Chat._sentinelColor
113-
? _theme.colors.surface
114-
: widget.backgroundColor,
110+
widget.decoration != null
111+
? null
112+
: (widget.backgroundColor ?? _theme.colors.surface),
115113
decoration: widget.decoration,
116114
child: Stack(
117115
children: [

packages/flutter_chat_ui/lib/src/chat_message/chat_message.dart

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import 'package:provider/provider.dart';
55
import '../utils/typedefs.dart';
66

77
class ChatMessage extends StatelessWidget {
8-
static const EdgeInsetsGeometry _sentinelPadding = EdgeInsets.zero;
9-
108
final Message message;
119
final int index;
1210
final Animation<double> animation;
@@ -55,7 +53,7 @@ class ChatMessage extends StatelessWidget {
5553
this.receivedMessageRowAlignment = CrossAxisAlignment.end,
5654
this.scaleAnimationAlignment,
5755
this.alignment,
58-
this.padding = _sentinelPadding,
56+
this.padding,
5957
this.paddingChangeAnimationDuration = const Duration(milliseconds: 250),
6058
this.isRemoved,
6159
this.groupStatus,
@@ -75,8 +73,7 @@ class ChatMessage extends StatelessWidget {
7573
curve: Curves.linearToEaseOut,
7674
);
7775

78-
final resolvedPadding =
79-
padding == _sentinelPadding ? _resolveDefaultPadding(context) : padding;
76+
final resolvedPadding = padding ?? _resolveDefaultPadding(context);
8077

8178
final Widget messageWidget = Column(
8279
mainAxisSize: MainAxisSize.min,
@@ -126,16 +123,18 @@ class ChatMessage extends StatelessWidget {
126123
],
127124
);
128125

129-
return padding != null
130-
? paddingChangeAnimationDuration != null
131-
? AnimatedPadding(
132-
padding: resolvedPadding!,
133-
duration: paddingChangeAnimationDuration!,
134-
curve: Curves.linearToEaseOut,
135-
child: messageWidget,
136-
)
137-
: Padding(padding: resolvedPadding!, child: messageWidget)
138-
: messageWidget;
126+
if (resolvedPadding != EdgeInsets.zero) {
127+
return paddingChangeAnimationDuration != null
128+
? AnimatedPadding(
129+
padding: resolvedPadding,
130+
duration: paddingChangeAnimationDuration!,
131+
curve: Curves.linearToEaseOut,
132+
child: messageWidget,
133+
)
134+
: Padding(padding: resolvedPadding, child: messageWidget);
135+
}
136+
137+
return messageWidget;
139138
}
140139

141140
Widget _buildMessage({required bool isSentByMe}) => Column(

packages/flutter_chat_ui/lib/src/composer.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import 'utils/composer_height_notifier.dart';
77
import 'utils/typedefs.dart';
88

99
class Composer extends StatefulWidget {
10-
static const Color _sentinelColor = Colors.transparent;
11-
1210
final TextEditingController? textEditingController;
1311
final double? left;
1412
final double? right;
@@ -62,7 +60,7 @@ class Composer extends StatefulWidget {
6260
this.filled = true,
6361
this.topWidget,
6462
this.handleSafeArea = true,
65-
this.backgroundColor = _sentinelColor,
63+
this.backgroundColor,
6664
this.attachmentIconColor,
6765
this.sendIconColor,
6866
this.hintColor,
@@ -146,10 +144,7 @@ class _ComposerState extends State<Composer> {
146144
child: ClipRect(
147145
child: Container(
148146
key: _key,
149-
color:
150-
widget.backgroundColor == Composer._sentinelColor
151-
? theme.colors.surfaceContainerLow
152-
: widget.backgroundColor,
147+
color: widget.backgroundColor ?? theme.colors.surfaceContainerLow,
153148
child: Column(
154149
children: [
155150
if (widget.topWidget != null) widget.topWidget!,

packages/flutter_chat_ui/lib/src/simple_text_message.dart

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ import 'package:flutter_chat_core/flutter_chat_core.dart';
33
import 'package:provider/provider.dart';
44

55
class SimpleTextMessage extends StatelessWidget {
6-
static const BorderRadiusGeometry _sentinelBorderRadius = BorderRadius.zero;
7-
static const Color _sentinelColor = Colors.transparent;
8-
static const TextStyle _sentinelTextStyle = TextStyle();
9-
106
final TextMessage message;
117
final int index;
128
final EdgeInsetsGeometry? padding;
@@ -26,13 +22,13 @@ class SimpleTextMessage extends StatelessWidget {
2622
required this.message,
2723
required this.index,
2824
this.padding = const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
29-
this.borderRadius = _sentinelBorderRadius,
25+
this.borderRadius,
3026
this.onlyEmojiFontSize = 48,
31-
this.sentBackgroundColor = _sentinelColor,
32-
this.receivedBackgroundColor = _sentinelColor,
33-
this.sentTextStyle = _sentinelTextStyle,
34-
this.receivedTextStyle = _sentinelTextStyle,
35-
this.timeStyle = _sentinelTextStyle,
27+
this.sentBackgroundColor,
28+
this.receivedBackgroundColor,
29+
this.sentTextStyle,
30+
this.receivedTextStyle,
31+
this.timeStyle,
3632
this.showTime = true,
3733
this.showStatus = true,
3834
this.timeAndStatusPosition = TimeAndStatusPosition.end,
@@ -80,10 +76,7 @@ class SimpleTextMessage extends StatelessWidget {
8076
? null
8177
: BoxDecoration(
8278
color: backgroundColor,
83-
borderRadius:
84-
borderRadius == _sentinelBorderRadius
85-
? theme.shape
86-
: borderRadius,
79+
borderRadius: borderRadius ?? theme.shape,
8780
),
8881
child: _buildContentBasedOnPosition(
8982
context: context,
@@ -144,38 +137,30 @@ class SimpleTextMessage extends StatelessWidget {
144137

145138
Color? _resolveBackgroundColor(bool isSentByMe, ChatTheme theme) {
146139
if (isSentByMe) {
147-
return sentBackgroundColor == _sentinelColor
148-
? theme.colors.primary
149-
: sentBackgroundColor;
140+
return sentBackgroundColor ?? theme.colors.primary;
150141
}
151-
return receivedBackgroundColor == _sentinelColor
152-
? theme.colors.surfaceContainer
153-
: receivedBackgroundColor;
142+
return receivedBackgroundColor ?? theme.colors.surfaceContainer;
154143
}
155144

156145
TextStyle? _resolveTextStyle(bool isSentByMe, ChatTheme theme) {
157146
if (isSentByMe) {
158-
return sentTextStyle == _sentinelTextStyle
159-
? theme.typography.bodyMedium.copyWith(color: theme.colors.onPrimary)
160-
: sentTextStyle;
147+
return sentTextStyle ??
148+
theme.typography.bodyMedium.copyWith(color: theme.colors.onPrimary);
161149
}
162-
return receivedTextStyle == _sentinelTextStyle
163-
? theme.typography.bodyMedium.copyWith(color: theme.colors.onSurface)
164-
: receivedTextStyle;
150+
return receivedTextStyle ??
151+
theme.typography.bodyMedium.copyWith(color: theme.colors.onSurface);
165152
}
166153

167154
TextStyle? _resolveTimeStyle(bool isSentByMe, ChatTheme theme) {
168155
if (isSentByMe) {
169-
return timeStyle == _sentinelTextStyle
170-
? theme.typography.labelSmall.copyWith(
156+
return timeStyle ??
157+
theme.typography.labelSmall.copyWith(
171158
color:
172159
_isOnlyEmoji ? theme.colors.onSurface : theme.colors.onPrimary,
173-
)
174-
: timeStyle;
160+
);
175161
}
176-
return timeStyle == _sentinelTextStyle
177-
? theme.typography.labelSmall.copyWith(color: theme.colors.onSurface)
178-
: timeStyle;
162+
return timeStyle ??
163+
theme.typography.labelSmall.copyWith(color: theme.colors.onSurface);
179164
}
180165
}
181166

packages/flyer_chat_file_message/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## 0.0.12
22

3+
**⚠️ Breaking Changes ⚠️**
4+
5+
- The default sentinel values that previously allowed users to set specific properties to `null` have been removed. Instead, please use `Colors.transparent`, `BorderRadius.zero`, or `TextStyle()` to achieve the desired effect. Passing `null` will now use the standard configuration.
6+
37
- Do not show status for received messages
48

59
## 0.0.11

0 commit comments

Comments
 (0)