From d65b499084240ff2f20af8a2e6a6b599be2f1fd2 Mon Sep 17 00:00:00 2001 From: qer Date: Wed, 10 Jun 2026 12:47:07 +0800 Subject: [PATCH] fix(web): show an image placeholder for image-only queued prompts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A prompt queued while the agent is busy can carry image attachments with no text; the queue strip rendered its bare text — an empty string, so the row was just a blank button next to a remove cross. Queue items now expose {text, attachmentCount}: image-only prompts render an 'image ×N' placeholder with a small badge, and any item carrying images disables the load-back-into-input edit action (the uploaded files can't be restored to the composer; editing would silently drop them — remove stays available). Verified with component render tests for the three shapes (image-only / text-only / text+images). --- apps/kimi-web/src/components/Composer.vue | 36 ++++++++++++++----- .../src/components/ConversationPane.vue | 4 +-- .../src/composables/useKimiWebClient.ts | 12 +++++-- apps/kimi-web/src/i18n/locales/en/composer.ts | 2 ++ apps/kimi-web/src/i18n/locales/zh/composer.ts | 2 ++ apps/kimi-web/src/types.ts | 7 ++++ 6 files changed, 49 insertions(+), 14 deletions(-) diff --git a/apps/kimi-web/src/components/Composer.vue b/apps/kimi-web/src/components/Composer.vue index bd45410de..11208535b 100644 --- a/apps/kimi-web/src/components/Composer.vue +++ b/apps/kimi-web/src/components/Composer.vue @@ -7,7 +7,7 @@ import MentionMenu from './MentionMenu.vue'; import type { SlashCommand } from '../lib/slashCommands'; import { filterCommands, parseSlash } from '../lib/slashCommands'; import type { FileItem } from './MentionMenu.vue'; -import type { ConversationStatus, PermissionMode } from '../types'; +import type { ConversationStatus, PermissionMode, QueuedPromptView } from '../types'; import type { AppModel, ThinkingLevel } from '../api/types'; // --------------------------------------------------------------------------- @@ -35,7 +35,7 @@ interface Attachment { const props = withDefaults(defineProps<{ running?: boolean; - queued?: string[]; + queued?: QueuedPromptView[]; searchFiles?: (q: string) => Promise; /** If undefined, attach button is hidden and paste/drag are no-ops. */ uploadImage?: (file: Blob, name?: string) => Promise<{ fileId: string; name: string; mediaType: string } | null>; @@ -592,7 +592,10 @@ function selectModel(modelId: string): void { @dragleave="handleDragLeave" @drop="handleDrop" > - +
{{ t('composer.queueLabel') }}
{{ msg }} + :disabled="msg.attachmentCount > 0" + :title="msg.attachmentCount > 0 ? t('composer.queuedHasImage', { n: msg.attachmentCount }) : t('composer.editQueued')" + @click="msg.attachmentCount === 0 && editQueued(i, msg.text)" + > + + {{ msg.text || t('composer.queuedImageOnly', { n: msg.attachmentCount }) }} + @@ -896,9 +903,10 @@ function selectModel(modelId: string): void { } .queue-text { + display: inline-flex; + align-items: center; + gap: 4px; overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; background: none; border: none; padding: 0; @@ -910,9 +918,19 @@ function selectModel(modelId: string): void { max-width: 168px; text-align: left; } -.queue-text:hover { +.queue-text:hover:not(:disabled) { color: var(--blue); } +.queue-text:disabled { + cursor: default; +} +.queue-img { flex: none; color: var(--muted); } +.queue-text-inner { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.queue-text-inner.placeholder { color: var(--muted); } .queue-rm { display: flex; diff --git a/apps/kimi-web/src/components/ConversationPane.vue b/apps/kimi-web/src/components/ConversationPane.vue index b2e5e162a..1cd00aeff 100644 --- a/apps/kimi-web/src/components/ConversationPane.vue +++ b/apps/kimi-web/src/components/ConversationPane.vue @@ -2,7 +2,7 @@