buildTextSpansWithPhoneAndUrlDetection static method

List<InlineSpan> buildTextSpansWithPhoneAndUrlDetection(
  1. BuildContext context,
  2. bool isSelf,
  3. String text,
  4. int startIndex, {
  5. int? end,
  6. ChatUIConfig? chatUIConfig,
  7. dynamic remoteExtension,
})

解析包含电话号码和URL链接的文本消息

Implementation

static List<InlineSpan> buildTextSpansWithPhoneAndUrlDetection(
  BuildContext context,
  bool isSelf,
  String text,
  int startIndex, {
  int? end,
  ChatUIConfig? chatUIConfig,
  dynamic remoteExtension,
}) {
  List<InlineSpan> spans = [];

  // 获取所有匹配项,URL优先匹配
  List<TextMatch> matches = [];

  // 首先添加URL匹配
  urlRegex.allMatches(text).forEach((match) {
    matches.add(TextMatch(
      start: match.start,
      end: match.end,
      text: match.group(0)!,
      type: MatchType.url,
    ));
  });

  // 然后添加电话号码匹配
  phoneRegex.allMatches(text).forEach((match) {
    matches.add(TextMatch(
      start: match.start,
      end: match.end,
      text: match.group(0)!,
      type: MatchType.phone,
    ));
  });

  // 如果没有匹配项,使用原有逻辑
  if (matches.isEmpty) {
    return ChatMessageHelper.textSpan(
      context,
      isSelf,
      text,
      startIndex,
      end: end,
      chatUIConfig: chatUIConfig,
      remoteExtension: remoteExtension,
    );
  }

  // 去重重叠的匹配项,URL优先
  List<TextMatch> filteredMatches = removeOverlapping(matches);

  // 定义文本字体大小和颜色
  final textSize = (isSelf
          ? chatUIConfig?.sendMessageTextSize
          : chatUIConfig?.receiveMessageTextSize) ??
      16;
  final textAitColor =
      chatUIConfig?.messageLinkColor ?? CommonColors.color_007aff;

  int lastEnd = 0;
  for (final match in filteredMatches) {
    // 添加匹配项前的文本
    if (match.start > lastEnd) {
      spans.addAll(ChatMessageHelper.textSpan(
        context,
        isSelf,
        text.substring(lastEnd, match.start),
        startIndex + lastEnd,
        chatUIConfig: chatUIConfig,
        remoteExtension: remoteExtension,
      ));
    }

    // 添加高亮文本(电话号码或URL)
    spans.add(TextSpan(
      text: match.text,
      style: TextStyle(
        color: textAitColor,
        fontSize: textSize,
        decoration: TextDecoration.underline,
      ),
      recognizer: TapGestureRecognizer()
        ..onTap = () {
          if (match.type == MatchType.phone) {
            showPhoneDialog(context, match.text);
          } else if (match.type == MatchType.url) {
            handleUrlClick(context, match.text);
          }
        },
    ));

    lastEnd = match.end;
  }

  // 添加剩余文本
  if (lastEnd < text.length) {
    spans.addAll(ChatMessageHelper.textSpan(
      context,
      isSelf,
      text.substring(lastEnd),
      startIndex + lastEnd,
      chatUIConfig: chatUIConfig,
      remoteExtension: remoteExtension,
    ));
  }

  return spans;
}