flutter_social_textfield icon indicating copy to clipboard operation
flutter_social_textfield copied to clipboard

How to customized some link pattern?

Open lucasjinreal opened this issue 2 years ago • 0 comments

Hi, this lib is useful.

I want customized the link pattern, is there a way to do it?

am using this logic to buld spans:


class WidgetSpanTextEditingController extends TextEditingController {
  WidgetSpanTextEditingController({String? text})
      : super.fromValue(text == null
            ? TextEditingValue.empty
            : TextEditingValue(text: text));

  @override
  TextSpan buildTextSpan(
      {required BuildContext context,
      TextStyle? style,
      required bool withComposing}) {
    TextRange? matchedRange;
    TextRange? matchedRange2;

    if (text.contains('$SPLIT_CMD_START') && text.contains('$SPLIT_CMD_END')) {
      matchedRange = _findMatchedRange(text);
      matchedRange2 = _findMatchedRange(text, trimTag: false);
    }

    if (matchedRange != null) {
      return TextSpan(
        children: [
          TextSpan(text: matchedRange.textBefore(text)),
          WidgetSpan(
              child: GestureDetector(
                  child: Padding(
                    padding: const EdgeInsets.only(
                        right: 5.0, top: 2.0, bottom: 2.0),
                    child: ClipRRect(
                        borderRadius:
                            const BorderRadius.all(Radius.circular(5.0)),
                        child: Container(
                          padding: const EdgeInsets.all(5.0),
                          color: Colors.orange,
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            mainAxisSize: MainAxisSize.min,
                            children: <Widget>[
                              Text(matchedRange2!
                                      .textInside(text)
                                      .trim()
                                      .split(SPLIT_CMD_MID)[0]
                                  //style: textStyle?.copyWith(color: Colors.orange),
                                  ),
                              const SizedBox(
                                width: 5.0,
                              ),
                              InkWell(
                                child: const Icon(
                                  Icons.close,
                                  size: 15.0,
                                ),
                                onTap: () {
                                  // controller!.value = controller!.value
                                  //     .copyWith(
                                  //         text: controller!.text.replaceRange(
                                  //             start!, start! + text.length, ''),
                                  //         selection: TextSelection.fromPosition(
                                  //             TextPosition(offset: start!)));
                                  clearMatchedText(matchedRange, text);
                                },
                              )
                            ],
                          ),
                        )),
                  ),
                  onTap: () {})),
          TextSpan(text: matchedRange.textAfter(text)),
        ],
        style: style,
      );
    }

    return TextSpan(text: text, style: style);
  }

  String clearMatchedText(TextRange? range, String text) {
    if (range != null) if (range.start >= 0 && range.end <= text.length) {
      text = text.replaceRange(range.start, range.end, '');
      return text;
    }
    return text;
  }

  // TextRange _findMatchedRange(String text) {
  //   final RegExp matchPattern = RegExp(RegExp.escape('\uffff'));
  //   late TextRange matchedRange;

  //   for (final Match match in matchPattern.allMatches(text)) {
  //     matchedRange = TextRange(start: match.start, end: match.end);
  //   }

  //   return matchedRange;
  // }

  TextRange _findMatchedRange(String text, {bool trimTag = true}) {
    final RegExp matchPattern = RegExp(r'<cmd>(.*?)<\/cmd>');
    late TextRange matchedRange;

    for (final Match match in matchPattern.allMatches(text)) {
      int start = match.start;
      if (!trimTag) start += '$SPLIT_CMD_START'.length;
      int end = match.end;
      if (!trimTag) end -= '$SPLIT_CMD_END'.length;
      matchedRange = TextRange(start: start, end: end);
    }
    return matchedRange;
  }
}

but question is when deleting, it is not delete whole span, but character by character.

lucasjinreal avatar Oct 13 '23 12:10 lucasjinreal