diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 280585b0ad2..df460777837 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -31,6 +31,7 @@ import { KiloProfileSelector } from "../kilocode/chat/KiloProfileSelector" import { MAX_IMAGES_PER_MESSAGE } from "./ChatView" import ContextMenu from "./ContextMenu" import { ImageWarningBanner } from "./ImageWarningBanner" +import { ContextFeedbackBanner, FeedbackType } from "./ContextFeedbackBanner" import { VolumeX, Pin, Check, WandSparkles, SendHorizontal, Paperclip, MessageSquareX } from "lucide-react" import { IndexingStatusBadge } from "./IndexingStatusBadge" import { MicrophoneButton } from "./MicrophoneButton" // kilocode_change: STT microphone button @@ -291,6 +292,14 @@ export const ChatTextArea = forwardRef( return () => window.removeEventListener("message", messageHandler) }, [setInputValue, searchRequestId, inputValue, onSend]) const [isDraggingOver, setIsDraggingOver] = useState(false) + // kilocode_change start: Context feedback state + const [contextFeedback, setContextFeedback] = useState<{ + visible: boolean + type: FeedbackType + messageKey: string + interpolations?: Record + }>({ visible: false, type: "success", messageKey: "" }) + // kilocode_change end: Context feedback state // kilocode_change start: Slash commands state const [showSlashCommandsMenu, setShowSlashCommandsMenu] = useState(false) const [selectedSlashCommandsIndex, setSelectedSlashCommandsIndex] = useState(0) @@ -446,6 +455,19 @@ export const ChatTextArea = forwardRef( } }, [inputValue, setInputValue, t]) + // kilocode_change start: Context feedback handlers + const showContextFeedback = useCallback( + (type: FeedbackType, messageKey: string, interpolations?: Record) => { + setContextFeedback({ visible: true, type, messageKey, interpolations }) + }, + [], + ) + + const dismissContextFeedback = useCallback(() => { + setContextFeedback((prev) => ({ ...prev, visible: false })) + }, []) + // kilocode_change end: Context feedback handlers + // kilocode_change start: Image and speech handlers const showImageWarning = useCallback( (messageKey: string) => { @@ -1237,8 +1259,18 @@ export const ChatTextArea = forwardRef( const newCursorPosition = cursorPosition + totalLength setCursorPosition(newCursorPosition) setIntendedCursorPosition(newCursorPosition) + + // kilocode_change start: Show feedback when files are added + if (lines.length === 1) { + showContextFeedback("success", "kilocode:contextFeedback.fileAddedToContext") + } else { + showContextFeedback("success", "kilocode:contextFeedback.filesAddedToContext", { + count: lines.length, + }) + } + // kilocode_change end: Show feedback when files are added } - + return } @@ -1821,6 +1853,15 @@ export const ChatTextArea = forwardRef( isVisible={!!imageWarning} /> {/* kilocode_change end: ImageWarningBanner integration */} + {/* kilocode_change start: ContextFeedbackBanner integration */} + + {/* kilocode_change end: ContextFeedbackBanner integration */} {/* kilocode_change start: pull slash commands from Cline */} {showSlashCommandsMenu && (
diff --git a/webview-ui/src/components/chat/ContextFeedbackBanner.tsx b/webview-ui/src/components/chat/ContextFeedbackBanner.tsx new file mode 100644 index 00000000000..a668a595272 --- /dev/null +++ b/webview-ui/src/components/chat/ContextFeedbackBanner.tsx @@ -0,0 +1,83 @@ +// kilocode_change - new file: Visual feedback for file drag-drop operations +import React, { useEffect } from "react" +import { CheckCircle, Info, X } from "lucide-react" + +import { useAppTranslation } from "@/i18n/TranslationContext" +import { cn } from "@/lib/utils" + +export type FeedbackType = "success" | "info" + +interface ContextFeedbackBannerProps { + isVisible: boolean + type: FeedbackType + messageKey: string + interpolations?: Record + onDismiss: () => void + className?: string +} + +export const ContextFeedbackBanner: React.FC = ({ + isVisible, + type, + messageKey, + interpolations, + onDismiss, + className, +}) => { + const { t } = useAppTranslation() + + useEffect(() => { + if (isVisible) { + const timer = setTimeout(() => { + onDismiss() + }, 3000) // 3s auto-dismiss + + return () => clearTimeout(timer) + } + }, [isVisible, onDismiss]) + + if (!isVisible) { + return null + } + + const Icon = type === "success" ? CheckCircle : Info + + const styles = { + success: { + border: "1px solid var(--vscode-testing-iconPassed)", + color: "var(--vscode-testing-iconPassed)", + background: "var(--vscode-input-background)", + }, + info: { + border: "1px solid var(--vscode-notificationsInfoIcon-foreground)", + color: "var(--vscode-notificationsInfoIcon-foreground)", + background: "var(--vscode-input-background)", + }, + } + + return ( +
+ + {t(messageKey, interpolations)} + +
+ ) +} \ No newline at end of file diff --git a/webview-ui/src/i18n/locales/en/kilocode.json b/webview-ui/src/i18n/locales/en/kilocode.json index 7a849f0573b..bde28ae5a4f 100644 --- a/webview-ui/src/i18n/locales/en/kilocode.json +++ b/webview-ui/src/i18n/locales/en/kilocode.json @@ -44,6 +44,11 @@ "maxImagesReached": "Maximum of 20 images per message. Remove some images to add more.", "imagesRemovedNoSupport": "Images removed, unsupported by model." }, + "contextFeedback": { + "filesAddedToContext": "{{count}} file(s) added to context", + "fileAddedToContext": "File added to context", + "shiftDragHint": "Hold Shift while dragging to add files to context" + }, "settings": { "sections": { "mcp": "MCP Servers" diff --git a/webview-ui/src/i18n/locales/pt-BR/kilocode.json b/webview-ui/src/i18n/locales/pt-BR/kilocode.json index e164a3f9b0d..e5fcc6908a9 100644 --- a/webview-ui/src/i18n/locales/pt-BR/kilocode.json +++ b/webview-ui/src/i18n/locales/pt-BR/kilocode.json @@ -293,6 +293,11 @@ "maxImagesReached": "Máximo de 20 imagens por mensagem. Remova algumas imagens para adicionar mais.", "imagesRemovedNoSupport": "Imagens removidas, não suportadas pelo modelo." }, + "contextFeedback": { + "filesAddedToContext": "{{count}} arquivo(s) adicionado(s) ao contexto", + "fileAddedToContext": "Arquivo adicionado ao contexto", + "shiftDragHint": "Segure Shift enquanto arrasta para adicionar arquivos ao contexto" + }, "memoryWarning": { "message": "O uso de memória está em {{percentage}}%. Por favor, reinicie seu IDE para evitar travamentos." },