Repository: expo/expo
File: docs/ui/components/AskPageAI/AskPageAIChatMessages.tsx (TypeScript)

Code before:
      </div>
    );
  }

  return (
    <div className="space-y-5">
      {conversation.map((qa, index) => {
        const markers = markersByIndex[index] ?? [];
        const questionFromPrompt = extractUserQuestion(qa.question, qa.question);
        const normalizedQuestion = normalizeQuestion(questionFromPrompt);
        const displayQuestion = askedQuestions[index] ?? questionFromPrompt;
        const normalizedAnswer = qa.answer
          ?.replace(/<br\s*\/?>((\n)?)/gi, '\n')
          ?.replace(/<sup[^>]*>(.*?)<\/sup>/gi, '$1');
        const trimmedAnswer = normalizedAnswer?.trim();
        const trimmedLower = trimmedAnswer?.toLowerCase() ?? '';
        const fallbackLower = fallbackResponse.toLowerCase();
        const hasSources = Array.isArray(qa.sources) && qa.sources.length > 0;
        const isOffPageAnswer =
          contextScope === 'page' &&
          hasSources &&
          qa.sources!.some(source => !source.source_url.includes(basePath));
        const sourcesForDisplay = isOffPageAnswer ? [] : (qa.sources ?? []);
        const isFallbackAnswer =
          trimmedAnswer === fallbackResponse ||
          trimmedLower.startsWith(fallbackLower) ||
          trimmedLower.includes(fallbackLower) ||
          trimmedLower.includes('search all expo docs') ||
          isOffPageAnswer;
        const answerForDisplay = isOffPageAnswer ? fallbackResponse : normalizedAnswer;
        const hasTriggeredGlobalSearch = Boolean(globalSearchRequests[normalizedQuestion]);
        const isPendingGlobal = pendingGlobalQuestionKey === normalizedQuestion;
        const isFinalAnswer =
          'isFeedbackSubmissionEnabled' in qa && Boolean((qa as any).isFeedbackSubmissionEnabled);
        const shouldOfferGlobalSearch =
          isFinalAnswer && contextScope === 'page' && isFallbackAnswer;
        const switchStatus = globalSwitchNotices[normalizedQuestion];
        const showSwitchingNotice = Boolean(switchStatus);
        const switchNoticeText =
          switchStatus === 'pending' ? 'Switching to Expo docs.' : 'Switched to Expo docs.';
        const canSubmitFeedback = Boolean(qa.id && qa.isFeedbackSubmissionEnabled);
        const isUpvoted = qa.reaction === 'upvote';
        const isDownvoted = qa.reaction === 'downvote';
        const disableUpvote = !canSubmitFeedback || isDownvoted;
        const disableDownvote = !canSubmitFeedback || isUpvoted;

        return (
          <div key={qa.id ?? `${qa.question}-${index}`} className="space-y-2">
            {markers.map(marker => (
              <div key={`marker-${marker.id}`} className="flex justify-center">
                <FOOTNOTE

Review comment (suggestion):
I think these two lines can be removed because both `trimmedAnswer === fallbackResponse` and `.startsWith()` are covered by the `.includes()`.

Code after:
      </div>
    );
  }

  return (
    <div className="space-y-5">
      {conversation.map((qa, index) => {
        const markers = markersByIndex[index] ?? [];
        const questionFromPrompt = extractUserQuestion(qa.question, qa.question);
        const normalizedQuestion = normalizeQuestion(questionFromPrompt);
        const displayQuestion = askedQuestions[index] ?? questionFromPrompt;
        const normalizedAnswer = qa.answer
          ?.replace(/<br\s*\/?>((\n)?)/gi, '\n')
          ?.replace(/<sup[^>]*>(.*?)<\/sup>/gi, '$1');
        const trimmedAnswer = normalizedAnswer?.trim();
        const trimmedLower = trimmedAnswer?.toLowerCase() ?? '';
        const fallbackLower = fallbackResponse.toLowerCase();
        const hasSources = Array.isArray(qa.sources) && qa.sources.length > 0;
        const isOffPageAnswer =
          contextScope === 'page' &&
          hasSources &&
          qa.sources!.some(source => !source.source_url.includes(basePath));
        const sourcesForDisplay = isOffPageAnswer ? [] : (qa.sources ?? []);
        const isFallbackAnswer =
          trimmedLower.includes(fallbackLower) ||
          trimmedLower.includes('search all expo docs') ||
          isOffPageAnswer;
        const answerForDisplay = isOffPageAnswer ? fallbackResponse : normalizedAnswer;
        const hasTriggeredGlobalSearch = Boolean(globalSearchRequests[normalizedQuestion]);
        const isPendingGlobal = pendingGlobalQuestionKey === normalizedQuestion;
        const isFinalAnswer =
          'isFeedbackSubmissionEnabled' in qa && Boolean((qa as any).isFeedbackSubmissionEnabled);
        const shouldOfferGlobalSearch =
          isFinalAnswer && contextScope === 'page' && isFallbackAnswer;
        const switchStatus = globalSwitchNotices[normalizedQuestion];
        const showSwitchingNotice = Boolean(switchStatus);
        const switchNoticeText =
          switchStatus === 'pending' ? 'Switching to Expo docs.' : 'Switched to Expo docs.';
        const canSubmitFeedback = Boolean(qa.id && qa.isFeedbackSubmissionEnabled);
        const isUpvoted = qa.reaction === 'upvote';
        const isDownvoted = qa.reaction === 'downvote';
        const disableUpvote = !canSubmitFeedback || isDownvoted;
        const disableDownvote = !canSubmitFeedback || isUpvoted;

        return (
          <div key={qa.id ?? `${qa.question}-${index}`} className="space-y-2">
            {markers.map(marker => (
              <div key={`marker-${marker.id}`} className="flex justify-center">
                <FOOTNOTE
                  theme="secondary"
                  className="inline-block rounded-md border border-default bg-subtle px-2 py-1">