@@ -946,39 +946,36 @@ class StreamMessageInputState extends State<StreamMessageInput>
946
946
defaultButton;
947
947
}
948
948
949
- Future <void > _sendPoll (Poll poll) {
950
- final streamChannel = StreamChannel .of (context);
951
- final channel = streamChannel.channel;
952
-
949
+ Future <void > _sendPoll (Poll poll, Channel channel) {
953
950
return channel.sendPoll (poll);
954
951
}
955
952
956
- Future <void > _updatePoll (Poll poll) {
957
- final streamChannel = StreamChannel .of (context);
958
- final channel = streamChannel.channel;
959
-
953
+ Future <void > _updatePoll (Poll poll, Channel channel) {
960
954
return channel.updatePoll (poll);
961
955
}
962
956
963
- Future <void > _deletePoll (Poll poll) {
964
- final streamChannel = StreamChannel .of (context);
965
- final channel = streamChannel.channel;
966
-
957
+ Future <void > _deletePoll (Poll poll, Channel channel) {
967
958
return channel.deletePoll (poll);
968
959
}
969
960
970
- Future <void > _createOrUpdatePoll (Poll ? old, Poll ? current) async {
961
+ Future <void > _createOrUpdatePoll (
962
+ Poll ? old,
963
+ Poll ? current,
964
+ ) async {
965
+ final channel = StreamChannel .maybeOf (context)? .channel;
966
+ if (channel == null ) return ;
967
+
971
968
// If both are null or the same, return
972
969
if ((old == null && current == null ) || old == current) return ;
973
970
974
971
// If old is null, i.e., there was no poll before, create the poll.
975
- if (old == null ) return _sendPoll (current! );
972
+ if (old == null ) return _sendPoll (current! , channel );
976
973
977
974
// If current is null, i.e., the poll is removed, delete the poll.
978
- if (current == null ) return _deletePoll (old);
975
+ if (current == null ) return _deletePoll (old, channel );
979
976
980
977
// Otherwise, update the poll.
981
- return _updatePoll (current);
978
+ return _updatePoll (current, channel );
982
979
}
983
980
984
981
/// Handle the platform-specific logic for selecting files.
@@ -996,7 +993,10 @@ class StreamMessageInputState extends State<StreamMessageInput>
996
993
..removeWhere ((it) {
997
994
if (it != AttachmentPickerType .poll) return false ;
998
995
if (_effectiveController.message.parentId != null ) return true ;
999
- final channel = StreamChannel .of (context).channel;
996
+
997
+ final channel = StreamChannel .maybeOf (context)? .channel;
998
+ if (channel == null ) return true ;
999
+
1000
1000
if (channel.config? .polls == true && channel.canSendPoll) return false ;
1001
1001
1002
1002
return true ;
@@ -1210,11 +1210,12 @@ class StreamMessageInputState extends State<StreamMessageInput>
1210
1210
1211
1211
late final _onChangedDebounced = debounce (
1212
1212
() {
1213
- var value = _effectiveController.text;
1214
1213
if (! mounted) return ;
1215
- value = value.trim ();
1216
1214
1217
- final channel = StreamChannel .of (context).channel;
1215
+ final channel = StreamChannel .maybeOf (context)? .channel;
1216
+ if (channel == null ) return ;
1217
+
1218
+ final value = _effectiveController.text.trim ();
1218
1219
if (value.isNotEmpty && channel.canSendTypingEvents) {
1219
1220
// Notify the server that the user started typing.
1220
1221
channel.keyStroke (_effectiveController.message.parentId).onError (
@@ -1235,7 +1236,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
1235
1236
1236
1237
setState (() => _actionsShrunk = value.isNotEmpty && actionsLength > 1 );
1237
1238
1238
- _checkContainsUrl (value, context );
1239
+ _checkContainsUrl (value, channel );
1239
1240
},
1240
1241
const Duration (milliseconds: 350 ),
1241
1242
leading: true ,
@@ -1264,7 +1265,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
1264
1265
caseSensitive: false ,
1265
1266
);
1266
1267
1267
- void _checkContainsUrl (String value, BuildContext context ) async {
1268
+ void _checkContainsUrl (String value, Channel channel ) async {
1268
1269
// Cancel the previous operation if it's still running
1269
1270
_enrichUrlOperation? .cancel ();
1270
1271
@@ -1281,10 +1282,8 @@ class StreamMessageInputState extends State<StreamMessageInput>
1281
1282
}).toList ();
1282
1283
1283
1284
// Reset the og attachment if the text doesn't contain any url
1284
- if (matchedUrls.isEmpty ||
1285
- ! StreamChannel .of (context).channel.canSendLinks) {
1286
- _effectiveController.clearOGAttachment ();
1287
- return ;
1285
+ if (matchedUrls.isEmpty || ! channel.canSendLinks) {
1286
+ return _effectiveController.clearOGAttachment ();
1288
1287
}
1289
1288
1290
1289
final firstMatchedUrl = matchedUrls.first.group (0 )! ;
@@ -1294,7 +1293,8 @@ class StreamMessageInputState extends State<StreamMessageInput>
1294
1293
return ;
1295
1294
}
1296
1295
1297
- final client = StreamChat .of (context).client;
1296
+ final client = StreamChat .maybeOf (context)? .client;
1297
+ if (client == null ) return ;
1298
1298
1299
1299
_enrichUrlOperation = CancelableOperation .fromFuture (
1300
1300
_enrichUrl (firstMatchedUrl, client),
@@ -1319,7 +1319,6 @@ class StreamMessageInputState extends State<StreamMessageInput>
1319
1319
) async {
1320
1320
var response = _ogAttachmentCache[url];
1321
1321
if (response == null ) {
1322
- final client = StreamChat .of (context).client;
1323
1322
try {
1324
1323
response = await client.enrichUrl (url);
1325
1324
_ogAttachmentCache[url] = response;
@@ -1462,7 +1461,9 @@ class StreamMessageInputState extends State<StreamMessageInput>
1462
1461
if (_effectiveController.isSlowModeActive) return ;
1463
1462
if (! widget.validator (_effectiveController.message)) return ;
1464
1463
1465
- final streamChannel = StreamChannel .of (context);
1464
+ final streamChannel = StreamChannel .maybeOf (context);
1465
+ if (streamChannel == null ) return ;
1466
+
1466
1467
final channel = streamChannel.channel;
1467
1468
var message = _effectiveController.value;
1468
1469
@@ -1483,7 +1484,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
1483
1484
return ;
1484
1485
}
1485
1486
1486
- _maybeDeleteDraftMessage (message);
1487
+ _maybeDeleteDraftMessage (message, channel );
1487
1488
widget.onQuotedMessageCleared? .call ();
1488
1489
_effectiveController.reset ();
1489
1490
@@ -1501,7 +1502,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
1501
1502
await WidgetsBinding .instance.endOfFrame;
1502
1503
}
1503
1504
1504
- await _sendOrUpdateMessage (message: message);
1505
+ await _sendOrUpdateMessage (message: message, channel : channel );
1505
1506
1506
1507
if (mounted) {
1507
1508
if (widget.shouldKeepFocusAfterMessage ?? ! _commandEnabled) {
@@ -1514,10 +1515,9 @@ class StreamMessageInputState extends State<StreamMessageInput>
1514
1515
1515
1516
Future <void > _sendOrUpdateMessage ({
1516
1517
required Message message,
1518
+ required Channel channel,
1517
1519
}) async {
1518
1520
try {
1519
- final channel = StreamChannel .of (context).channel;
1520
-
1521
1521
// Note: edited messages which are bounced back with an error needs to be
1522
1522
// sent as new messages as the backend doesn't store them.
1523
1523
final resp = await switch (_isEditing && ! message.isBouncedWithError) {
@@ -1558,19 +1558,21 @@ class StreamMessageInputState extends State<StreamMessageInput>
1558
1558
}
1559
1559
1560
1560
void _maybeUpdateOrDeleteDraftMessage () {
1561
+ final channel = StreamChannel .maybeOf (context)? .channel;
1562
+ if (channel == null ) return ;
1563
+
1561
1564
final message = _effectiveController.message;
1562
1565
final isMessageValid = widget.validator.call (message);
1563
1566
1564
1567
// If the message is valid, we need to create or update it as a draft
1565
1568
// message for the channel or thread.
1566
- if (isMessageValid) return _maybeUpdateDraftMessage (message);
1569
+ if (isMessageValid) return _maybeUpdateDraftMessage (message, channel );
1567
1570
1568
1571
// Otherwise, we need to delete the draft message.
1569
- return _maybeDeleteDraftMessage (message);
1572
+ return _maybeDeleteDraftMessage (message, channel );
1570
1573
}
1571
1574
1572
- void _maybeUpdateDraftMessage (Message message) {
1573
- final channel = StreamChannel .of (context).channel;
1575
+ void _maybeUpdateDraftMessage (Message message, Channel channel) {
1574
1576
final draft = switch (message.parentId) {
1575
1577
final parentId? => channel.state? .threadDraft (parentId),
1576
1578
null => channel.state? .draft,
@@ -1584,8 +1586,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
1584
1586
return channel.createDraft (draftMessage).ignore ();
1585
1587
}
1586
1588
1587
- void _maybeDeleteDraftMessage (Message message) {
1588
- final channel = StreamChannel .of (context).channel;
1589
+ void _maybeDeleteDraftMessage (Message message, Channel channel) {
1589
1590
final draft = switch (message.parentId) {
1590
1591
final parentId? => channel.state? .threadDraft (parentId),
1591
1592
null => channel.state? .draft,
0 commit comments