From 852fed1364bbbe616f881a9894da7a5f1019f42e Mon Sep 17 00:00:00 2001 From: Stef Lewandowski Date: Thu, 28 Nov 2024 17:00:16 +0000 Subject: [PATCH 1/2] fix: break out inline-defined components --- .../AppComponents/Chat/markdown.tsx | 196 +++++++++--------- .../ContentOptions/ReportContentDialog.tsx | 64 +++--- 2 files changed, 135 insertions(+), 125 deletions(-) diff --git a/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx b/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx index fcee6eb5b..7f26c57e6 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx @@ -1,6 +1,6 @@ import type { FC } from "react"; -import React, { memo } from "react"; -import type { Options } from "react-markdown"; +import React, { memo, useMemo } from "react"; +import type { Components, Options } from "react-markdown"; import ReactMarkdown from "react-markdown"; import * as Tooltip from "@radix-ui/react-tooltip"; @@ -24,110 +24,112 @@ export type ReactMarkdownWithStylesProps = Readonly<{ className?: string; }>; +const createComponents = ( + className?: string, + lessonPlanSectionDescription?: string, +): Partial => ({ + li: ({ children }) => ( +
  • {children}
  • + ), + p: ({ children }) => ( +

    {children}

    + ), + h1: ({ children }) => ( + + +

    {children}

    +
    + {!!lessonPlanSectionDescription && ( + + + + + + + + + + {lessonPlanSectionDescription} + + + + + + )} +
    + ), + code: (props) => { + const { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + node, + className, + children, + inline, + ...restProps + } = props as { + node?: React.ReactNode; + inline?: boolean; + className?: string; + children?: React.ReactNode; + }; + if (children && Array.isArray(children) && children.length) { + if (children[0] == "▍") { + return ; + } + + children[0] = (children[0] as string).replace("`▍`", "▍"); + } + + const match = /language-(\w+)/.exec(className ?? ""); + + if (inline) { + return ( + + {children} + + ); + } + + return ( + + ); + }, + a: ({ children, href }) => { + const isExternal = href?.startsWith("http"); + const tags = isExternal + ? { target: "_blank", rel: "noopener noreferrer" } + : {}; + return ( + + {children} + + ); + }, +}); + export const MemoizedReactMarkdownWithStyles = ({ markdown, lessonPlanSectionDescription, className, }: ReactMarkdownWithStylesProps) => { + const components: Partial = useMemo(() => { + return createComponents(className, lessonPlanSectionDescription); + }, [className, lessonPlanSectionDescription]); return ( {children} - ); - }, - p({ children }) { - return

    {children}

    ; - }, - h1({ children }) { - return ( - - -

    {children}

    -
    - {!!lessonPlanSectionDescription && ( - - - - - - - - - - {lessonPlanSectionDescription} - - - - - - )} -
    - ); - }, - code(props) { - const { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - node, - className, - children, - inline, - ...restProps - } = props as { - node?: React.ReactNode; - inline?: boolean; - className?: string; - children?: React.ReactNode; - }; - if (children && Array.isArray(children) && children.length) { - if (children[0] == "▍") { - return ( - - ); - } - - children[0] = (children[0] as string).replace("`▍`", "▍"); - } - - const match = /language-(\w+)/.exec(className ?? ""); - - if (inline) { - return ( - - {children} - - ); - } - - return ( - - ); - }, - a({ children, href }) { - const isExternal = href?.startsWith("http"); - const tags = isExternal - ? { target: "_blank", rel: "noopener noreferrer" } - : {}; - return ( - - {children} - - ); - }, - }} + components={components} > {markdown}
    diff --git a/apps/nextjs/src/components/DialogControl/ContentOptions/ReportContentDialog.tsx b/apps/nextjs/src/components/DialogControl/ContentOptions/ReportContentDialog.tsx index cfed34faa..351ad512d 100644 --- a/apps/nextjs/src/components/DialogControl/ContentOptions/ReportContentDialog.tsx +++ b/apps/nextjs/src/components/DialogControl/ContentOptions/ReportContentDialog.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useCallback, useState } from "react"; import { aiLogger } from "@oakai/logger"; import { @@ -36,31 +36,43 @@ const ReportContentDialog = ({ surveyName: "Report Content", }); - function close() { + const close = useCallback(() =>{ closeDialog(); closeDialogWithPostHogDismiss(); - } + }, [closeDialog, closeDialogWithPostHogDismiss]); - function onSubmit( - e?: React.FormEvent | React.MouseEvent, - ) { - log.info("submitting"); - e?.preventDefault(); - setUserHasSubmitted(true); - submitSurveyWithOutClosing({ - //Messages Array - $survey_response: messages ?? "No chat history", - // Last Message Id - $survey_response_1: messages - ? messages[messages.length - 1]?.id - : "No chat history", - // Chat Id - $survey_response_2: chatId, - // Comment - $survey_response_3: userInput, - }); - setUserInput(""); - } + const onSubmit = useCallback( + ( + e?: + | React.FormEvent + | React.MouseEvent, + ) => { + log.info("submitting"); + e?.preventDefault(); + setUserHasSubmitted(true); + submitSurveyWithOutClosing({ + //Messages Array + $survey_response: messages ?? "No chat history", + // Last Message Id + $survey_response_1: messages + ? messages[messages.length - 1]?.id + : "No chat history", + // Chat Id + $survey_response_2: chatId, + // Comment + $survey_response_3: userInput, + }); + setUserInput(""); + }, + [chatId, messages, submitSurveyWithOutClosing, userInput], + ); + + const actionButtonStates = useCallback( + () => ( + Submit feedback + ), + [onSubmit], + ); return ( @@ -96,11 +108,7 @@ const ReportContentDialog = ({ /> ( - - Submit feedback - - )} + actionButtonStates={actionButtonStates} closeDialog={close} /> From 27c8e4ddcb274a085fbfe342d76f53b1ff2e99af Mon Sep 17 00:00:00 2001 From: Stef Lewandowski Date: Thu, 28 Nov 2024 17:00:34 +0000 Subject: [PATCH 2/2] Memoize component builder functions --- apps/nextjs/src/components/AppComponents/Chat/markdown.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx b/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx index 7f26c57e6..14cc365b7 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx @@ -24,6 +24,7 @@ export type ReactMarkdownWithStylesProps = Readonly<{ className?: string; }>; +// This could do with further refactoring to make it more readable const createComponents = ( className?: string, lessonPlanSectionDescription?: string,