Add screenshot paste support (#2679)

This commit is contained in:
Max Novich
2025-05-28 11:11:22 -07:00
committed by GitHub
parent d8fa740067
commit feb7b15c76
10 changed files with 828 additions and 58 deletions
+22 -3
View File
@@ -1,7 +1,9 @@
import React, { useEffect, useMemo, useRef } from 'react';
import LinkPreview from './LinkPreview';
import ImagePreview from './ImagePreview';
import GooseResponseForm from './GooseResponseForm';
import { extractUrls } from '../utils/urlUtils';
import { extractImagePaths, removeImagePathsFromText } from '../utils/imageUtils';
import { formatMessageTimestamp } from '../utils/timeUtils';
import MarkdownContent from './MarkdownContent';
import ToolCallWithResponse from './ToolCallWithResponse';
@@ -40,6 +42,13 @@ export default function GooseMessage({
// Extract text content from the message
let textContent = getTextContent(message);
// Extract image paths from the message
const imagePaths = extractImagePaths(textContent);
// Remove image paths from text for display
const displayText =
imagePaths.length > 0 ? removeImagePathsFromText(textContent, imagePaths) : textContent;
// Memoize the timestamp
const timestamp = useMemo(() => formatMessageTimestamp(message.created), [message.created]);
@@ -53,7 +62,7 @@ export default function GooseMessage({
const messageIndex = messages?.findIndex((msg) => msg.id === message.id);
const previousMessage = messageIndex > 0 ? messages[messageIndex - 1] : null;
const previousUrls = previousMessage ? extractUrls(getTextContent(previousMessage)) : [];
const urls = toolRequests.length === 0 ? extractUrls(textContent, previousUrls) : [];
const urls = toolRequests.length === 0 ? extractUrls(displayText, previousUrls) : [];
const toolConfirmationContent = getToolConfirmationContent(message);
const hasToolConfirmation = toolConfirmationContent !== undefined;
@@ -106,8 +115,18 @@ export default function GooseMessage({
{textContent && (
<div className="flex flex-col group">
<div className={`goose-message-content pt-2`}>
<div ref={contentRef}>{<MarkdownContent content={textContent} />}</div>
<div ref={contentRef}>{<MarkdownContent content={displayText} />}</div>
</div>
{/* Render images if any */}
{imagePaths.length > 0 && (
<div className="flex flex-wrap gap-2 mt-2 mb-2">
{imagePaths.map((imagePath, index) => (
<ImagePreview key={index} src={imagePath} alt={`Image ${index + 1}`} />
))}
</div>
)}
{/* Only show MessageCopyLink if there's text content and no tool requests/responses */}
<div className="relative flex justify-start">
{toolRequests.length === 0 && (
@@ -117,7 +136,7 @@ export default function GooseMessage({
)}
{textContent && message.content.every((content) => content.type === 'text') && (
<div className="absolute left-0 pt-1">
<MessageCopyLink text={textContent} contentRef={contentRef} />
<MessageCopyLink text={displayText} contentRef={contentRef} />
</div>
)}
</div>