mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 08:53:36 +00:00
feat: enhance image handling in chat and drop zone components
- Updated ImageAttachment interface to make 'id' and 'size' optional for better compatibility with server messages. - Improved image display in AgentView for user messages, including a count of attached images and a clickable preview. - Refined ImageDropZone to conditionally render file size and ensure proper handling of image removal actions.
This commit is contained in:
@@ -244,14 +244,16 @@ export function ImageDropZone({
|
|||||||
<p className="text-xs font-medium text-foreground truncate">
|
<p className="text-xs font-medium text-foreground truncate">
|
||||||
{image.filename}
|
{image.filename}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-muted-foreground">
|
{image.size !== undefined && (
|
||||||
{formatFileSize(image.size)}
|
<p className="text-xs text-muted-foreground">
|
||||||
</p>
|
{formatFileSize(image.size)}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* Remove button */}
|
{/* Remove button */}
|
||||||
{!disabled && (
|
{!disabled && image.id && (
|
||||||
<button
|
<button
|
||||||
onClick={() => removeImage(image.id)}
|
onClick={() => removeImage(image.id!)}
|
||||||
className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded-full hover:bg-destructive hover:text-destructive-foreground text-muted-foreground"
|
className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded-full hover:bg-destructive hover:text-destructive-foreground text-muted-foreground"
|
||||||
>
|
>
|
||||||
<X className="h-3 w-3" />
|
<X className="h-3 w-3" />
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
PanelLeft,
|
PanelLeft,
|
||||||
Paperclip,
|
Paperclip,
|
||||||
X,
|
X,
|
||||||
|
ImageIcon,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { useElectronAgent } from "@/hooks/use-electron-agent";
|
import { useElectronAgent } from "@/hooks/use-electron-agent";
|
||||||
@@ -588,6 +589,45 @@ export function AgentView() {
|
|||||||
{message.content}
|
{message.content}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Display attached images for user messages */}
|
||||||
|
{message.role === "user" && message.images && message.images.length > 0 && (
|
||||||
|
<div className="mt-3 space-y-2">
|
||||||
|
<div className="flex items-center gap-1.5 text-xs text-primary-foreground/80">
|
||||||
|
<ImageIcon className="w-3 h-3" />
|
||||||
|
<span>{message.images.length} image{message.images.length > 1 ? 's' : ''} attached</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{message.images.map((image, index) => {
|
||||||
|
// Construct proper data URL from base64 data and mime type
|
||||||
|
const dataUrl = image.data.startsWith('data:')
|
||||||
|
? image.data
|
||||||
|
: `data:${image.mimeType || 'image/png'};base64,${image.data}`;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={image.id || `img-${index}`}
|
||||||
|
className="relative group rounded-lg overflow-hidden border border-primary-foreground/20 bg-primary-foreground/10"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={dataUrl}
|
||||||
|
alt={image.filename || `Attached image ${index + 1}`}
|
||||||
|
className="w-20 h-20 object-cover cursor-pointer hover:opacity-90 transition-opacity"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
// Open image in a larger view (could be enhanced with a modal)
|
||||||
|
window.open(dataUrl, '_blank');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 bg-black/50 px-1.5 py-0.5 text-[9px] text-white truncate">
|
||||||
|
{image.filename || `Image ${index + 1}`}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<p
|
<p
|
||||||
className={cn(
|
className={cn(
|
||||||
"text-[11px] mt-2 font-medium",
|
"text-[11px] mt-2 font-medium",
|
||||||
@@ -677,18 +717,22 @@ export function AgentView() {
|
|||||||
<p className="text-xs font-medium text-foreground truncate max-w-24">
|
<p className="text-xs font-medium text-foreground truncate max-w-24">
|
||||||
{image.filename}
|
{image.filename}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-[10px] text-muted-foreground">
|
{image.size !== undefined && (
|
||||||
{formatFileSize(image.size)}
|
<p className="text-[10px] text-muted-foreground">
|
||||||
</p>
|
{formatFileSize(image.size)}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* Remove button */}
|
{/* Remove button */}
|
||||||
<button
|
{image.id && (
|
||||||
onClick={() => removeImage(image.id)}
|
<button
|
||||||
className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded-full hover:bg-destructive/10 text-muted-foreground hover:text-destructive"
|
onClick={() => removeImage(image.id!)}
|
||||||
disabled={isProcessing}
|
className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded-full hover:bg-destructive/10 text-muted-foreground hover:text-destructive"
|
||||||
>
|
disabled={isProcessing}
|
||||||
<X className="h-3 w-3" />
|
>
|
||||||
</button>
|
<X className="h-3 w-3" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -210,11 +210,11 @@ export const DEFAULT_KEYBOARD_SHORTCUTS: KeyboardShortcuts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export interface ImageAttachment {
|
export interface ImageAttachment {
|
||||||
id: string;
|
id?: string; // Optional - may not be present in messages loaded from server
|
||||||
data: string; // base64 encoded image data
|
data: string; // base64 encoded image data
|
||||||
mimeType: string; // e.g., "image/png", "image/jpeg"
|
mimeType: string; // e.g., "image/png", "image/jpeg"
|
||||||
filename: string;
|
filename: string;
|
||||||
size: number; // file size in bytes
|
size?: number; // file size in bytes - optional for messages from server
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChatMessage {
|
export interface ChatMessage {
|
||||||
|
|||||||
4
apps/app/src/types/electron.d.ts
vendored
4
apps/app/src/types/electron.d.ts
vendored
@@ -3,11 +3,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface ImageAttachment {
|
export interface ImageAttachment {
|
||||||
id: string;
|
id?: string; // Optional - may not be present in messages loaded from server
|
||||||
data: string; // base64 encoded image data
|
data: string; // base64 encoded image data
|
||||||
mimeType: string; // e.g., "image/png", "image/jpeg"
|
mimeType: string; // e.g., "image/png", "image/jpeg"
|
||||||
filename: string;
|
filename: string;
|
||||||
size: number; // file size in bytes
|
size?: number; // file size in bytes - optional for messages from server
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Message {
|
export interface Message {
|
||||||
|
|||||||
Reference in New Issue
Block a user