import { Component, For, Show } from "solid-js" import { Icon } from "@opencode-ai/ui/icon" import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon" import { Tooltip } from "@opencode-ai/ui/tooltip" import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2" import { AttachmentCardV2 } from "@opencode-ai/session-ui/v2/attachment-card-v2" import { CommentCardV2 } from "@opencode-ai/session-ui/v2/comment-card-v2" import { typeLabel } from "@opencode-ai/session-ui/message-file" import type { ContextItem, ImageAttachmentPart } from "@/context/prompt" import "./image-attachments.css" type PromptCommentItem = ContextItem & { key: string } type PromptImageAttachmentsProps = { attachments: ImageAttachmentPart[] onOpen: (attachment: ImageAttachmentPart) => void onRemove: (id: string) => void removeLabel: string fileLabel: string newLayoutDesigns: boolean comments?: PromptCommentItem[] commentActive?: (item: PromptCommentItem) => boolean onOpenComment?: (item: PromptCommentItem) => void onRemoveComment?: (item: PromptCommentItem) => void } const fallbackClass = "size-16 rounded-md bg-surface-base flex items-center justify-center border border-border-base" const imageClass = "size-16 rounded-md object-cover border border-border-base hover:border-border-strong-base transition-colors" const imageClassV2 = "w-[58px] h-[46px] rounded-[6px] object-cover" // inset box-shadows do not paint over content, so the hairline is a separate overlay const imageHairlineClassV2 = "absolute inset-0 rounded-[6px] shadow-[inset_0_0_0_0.5px_var(--v2-border-border-base)] pointer-events-none" const removeClass = "absolute -top-1.5 -right-1.5 size-5 rounded-full bg-surface-raised-stronger-non-alpha border border-border-base flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity hover:bg-surface-raised-base-hover" const removeClassV2 = "absolute -top-1 -right-1 size-4 rounded-full bg-v2-icon-icon-muted outline-solid outline-1 outline-v2-icon-icon-contrast flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity" const nameClass = "absolute bottom-0 left-0 right-0 px-1 py-0.5 bg-black/50 rounded-b-md" export const PromptImageAttachments: Component = (props) => { return ( 0 || (props.newLayoutDesigns && (props.comments?.length ?? 0) > 0)}>
{(item) => (
props.onOpenComment?.(item)} />
)}
{(attachment) => { const image = attachment.mime.startsWith("image/") const media = () => (
} > {typeLabel(attachment.filename, attachment.mime, props.fileLabel)} } > {attachment.filename} props.onOpen(attachment)} /> ) const name = () => (
{attachment.filename}
) const remove = () => ( ) // v2 keeps the remove button outside the tooltip trigger so hovering it dismisses the tooltip return (
{media()} {name()} {remove()}
} >
{media()}
{remove()}
) }}
) }