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) {
              if (ChatKitUtils.isDesktopOrWeb) {
                // 桌面/Web 端:直接复制号码并弹出 Toast,不弹底部弹框
                copyPhoneNumber(match.text);
              } else {
                showPhoneDialog(context, match.text);
              }
            } else if (match.type == MatchType.url) {
              if (ChatKitUtils.isDesktopOrWeb) {
                // 桌面/Web 端:调用系统浏览器打开,不在应用内打开
                final uri = Uri.parse(_formatUrl(match.text));
                launchUrl(uri, mode: LaunchMode.externalApplication);
              } else {
                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;
}