diff --git a/web/src/app/_components/image.tsx b/web/src/app/_components/image.tsx new file mode 100644 index 0000000..8f227d1 --- /dev/null +++ b/web/src/app/_components/image.tsx @@ -0,0 +1,73 @@ +import { memo, useCallback, useEffect, useState } from "react"; + +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "~/components/ui/tooltip"; +import { cn } from "~/lib/utils"; + +function Image({ + className, + imageClassName, + imageTransition, + src, + alt, + fallback = null, +}: { + className?: string; + imageClassName?: string; + imageTransition?: boolean; + src: string; + alt: string; + fallback?: React.ReactNode; +}) { + const [isLoading, setIsLoading] = useState(true); + const [isError, setIsError] = useState(false); + + useEffect(() => { + setIsError(false); + setIsLoading(true); + }, [src]); + + const handleLoad = useCallback(() => { + setIsError(false); + setIsLoading(false); + }, []); + const handleError = useCallback( + (e: React.SyntheticEvent) => { + e.currentTarget.style.display = "none"; + console.warn(`Markdown: Image "${e.currentTarget.src}" failed to load`); + setIsError(true); + }, + [], + ); + return ( + + {isError ? ( + fallback + ) : ( + + + {alt} + + +

{alt ?? "No caption"}

+
+
+ )} +
+ ); +} + +export default memo(Image); diff --git a/web/src/app/_components/markdown.tsx b/web/src/app/_components/markdown.tsx index b41f169..8446dfc 100644 --- a/web/src/app/_components/markdown.tsx +++ b/web/src/app/_components/markdown.tsx @@ -20,6 +20,8 @@ import { import { rehypeSplitWordsIntoSpans } from "~/core/rehype"; import { cn } from "~/lib/utils"; +import Image from "./image"; + export function Markdown({ className, children, @@ -39,10 +41,6 @@ export function Markdown({ } return [rehypeKatex]; }, [animate]); - const handleImgError = (e: React.SyntheticEvent) => { - e.currentTarget.style.display = "none"; - console.warn(`Markdown: Image "${e.currentTarget.src}" failed to load`); - }; return (
), img: ({ src, alt }) => ( - {alt} + + {alt + ), }} {...props} diff --git a/web/src/app/_components/research-activities-block.tsx b/web/src/app/_components/research-activities-block.tsx index 1917168..ff2cd0a 100644 --- a/web/src/app/_components/research-activities-block.tsx +++ b/web/src/app/_components/research-activities-block.tsx @@ -18,6 +18,7 @@ import { useMessage, useStore } from "~/core/store"; import { cn } from "~/lib/utils"; import { FavIcon } from "./fav-icon"; +import Image from "./image"; import { LoadingAnimation } from "./loading-animation"; import { Markdown } from "./markdown"; import { RainbowText } from "./rainbow-text"; @@ -123,7 +124,6 @@ function WebSearchToolCall({ toolCall }: { toolCall: ToolCallRuntime }) { } else { results = []; } - console.info(results); return results; }, [toolCall.result]); const pageResults = useMemo( @@ -172,20 +172,30 @@ function WebSearchToolCall({ toolCall }: { toolCall: ToolCallRuntime }) { ))} {imageResults.map((searchResult, i) => ( -
  • + -
    -
  • + ))} )}