Null check operator is used on a null value when long press a link
Is there an existing issue for this?
- [X] I have searched the existing issues
Flutter Quill version
10.7.5
Steps to reproduce
dont know
Expected results
no error
Actual results
Null check operator used on a null value
#0 _TextLineState._longPressLink (package:flutter_quill/src/editor/widgets/text/text_line.dart:656)#1 _TextLineState._getRecognizer.
Additional Context
Screenshots / Video demonstration
[Upload media here]
Logs
[Paste your logs here]
This line is causing the issue. Need to handle this in a better way without using the null check operator, if we're not sure why then should use assert or throw an exception with a clear message instead of return and then causing unexpected behavior that's more difficult to trace.
This commit is related.
I would avoid using dynamic in Dart (and any other language) when possible which is something that's used in Delta and Attribute, instead manually cast and handle exceptions.
Hi @tschiekdev @EchoEllet,
The error occurs when you perform a long press on a piece of text, add a link, then long press again and choose “remove.” After that, performing another long press on the same text triggers the reported error. To reproduce the issue, you need to start with a completely empty field.
The identified fix involves modifying the _longPressLink function in the text_line file.
Here’s the updated code:
Future<void> _longPressLink(Node node) async {
final link = node.style.attributes[Attribute.link.key]!.value!;
final action = await widget.linkActionPicker(node);
switch (action) {
case LinkMenuAction.launch:
_tapLink(link);
break;
case LinkMenuAction.copy:
Clipboard.setData(ClipboardData(text: link));
break;
case LinkMenuAction.remove:
final range = getLinkRange(node);
widget.controller
.formatText(range.start, range.end - range.start, Attribute.link);
// ADDED CODE
final recognizer = _linkRecognizers.remove(node);
recognizer?.dispose();
// END ADDED CODE
break;
case LinkMenuAction.none:
break;
}
}
The issue happens because, at line 659 of the text_line file, a class is instantiated that registers a callback, which isn’t properly removed when the link is deleted:
if (isLink && canLaunchLinks) {
if (isDesktop || widget.readOnly) {
_linkRecognizers[segment] = TapGestureRecognizer()
..onTap = () => _tapNodeLink(segment);
} else {
_linkRecognizers[segment] = LongPressGestureRecognizer()
..onLongPress = () => _longPressLink(segment);
}
}
I hope this information is helpful and that the issue will be fixed in the main branch 🚀
Best regards, Leonard