Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: adjust file card layout
  • Loading branch information
Na2CuCl4 committed Dec 20, 2025
commit 12ef71edd3b8d7e08d55d07c378e6b6c45846ced
96 changes: 92 additions & 4 deletions app/components/chat.module.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,96 @@
@import "../styles/animation.scss";

.attach-images {
position: absolute;
left: 30px;
bottom: 32px;
display: flex;
flex-wrap: wrap;
gap: 10px;
width: 100%;
margin-top: 10px;
padding: 0 120px 0 10px; /* leave room for send button */
}

.attach-files {
display: flex;
flex-wrap: wrap;
gap: 10px;
width: 100%;
margin-top: 10px;
padding: 4px 120px 0 10px; /* leave room for send button */
box-sizing: border-box;
}

.attach-file-card {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 10px 12px;
border-radius: 12px;
background: var(--white);
border: var(--border-in-light);
box-shadow: var(--card-shadow);
animation: slide-in ease 0.2s;
transition: transform ease 0.2s, box-shadow ease 0.2s;
flex: 0 1 280px; /* consistent card width without stretching */
max-width: 280px;

&:hover {
transform: translateY(-1px);
box-shadow: var(--shadow);
}
}

.attach-file-left {
display: flex;
align-items: center;
gap: 10px;
min-width: 0;
}

.attach-file-icon {
width: 34px;
height: 34px;
border-radius: 10px;
background: var(--gray);
border: var(--border-in-light);
display: flex;
align-items: center;
justify-content: center;
color: var(--black);
}

.attach-file-meta {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}

.attach-file-name {
font-size: 13px;
font-weight: 600;
color: var(--black);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}

.attach-file-size {
font-size: 12px;
color: #666;
}

.attach-file-error {
font-size: 12px;
color: #d9534f;
}

.attach-file-actions {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
}

.attach-image {
Expand Down Expand Up @@ -627,12 +713,14 @@
cursor: text;
display: flex;
flex: 1;
flex-direction: column;
gap: 10px;
border-radius: 10px;
border: var(--border-in-light);
}

.chat-input-panel-inner-attach {
padding-bottom: 80px;
padding-bottom: 12px;
}

.chat-input-panel-inner:has(.chat-input:focus) {
Expand Down
20 changes: 2 additions & 18 deletions app/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import ShortcutkeyIcon from "../icons/shortcutkey.svg";
import McpToolIcon from "../icons/tool.svg";
import HeadphoneIcon from "../icons/headphone.svg";
import {
AttachedFile,
BOT_HELLO,
ChatMessage,
createMessage,
Expand Down Expand Up @@ -1049,16 +1050,6 @@ function _Chat() {
const [uploading, setUploading] = useState(false);

// files
type AttachedFile = {
name: string;
content: File; // original file
size: number; // bytes
type: string; // mime
status: "idle" | "uploading" | "success" | "error";
text?: string; // recognized content
textSize?: number; // bytes of recognized content
error?: string;
};
const [attachFiles, setAttachFiles] = useState<AttachedFile[]>([]);

// prompt hints
Expand Down Expand Up @@ -1143,16 +1134,9 @@ function _Chat() {
matchCommand.invoke();
return;
}
// append recognized files as text blocks
const fileTextBlocks = attachFiles
.filter((f) => f.status === "success" && f.text)
.map((f) => `${f.name}\n\n---\n\n${f.text}`);
const combinedInput = [userInput, ...fileTextBlocks]
.filter((t) => t && t.length > 0)
.join("\n\n");
setIsLoading(true);
chatStore
.onUserInput(combinedInput, attachImages)
.onUserInput(userInput, attachImages, attachFiles)
.then(() => setIsLoading(false));
setAttachImages([]);
setAttachFiles([]);
Expand Down
35 changes: 30 additions & 5 deletions app/store/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,17 @@ export const BOT_HELLO: ChatMessage = createMessage({
content: Locale.Store.BotHello,
});

export type AttachedFile = {
name: string;
content: File; // original file
size: number; // bytes
type: string; // mime
status: "idle" | "uploading" | "success" | "error";
text?: string; // recognized content
textSize?: number; // bytes of recognized content
error?: string;
};

function createEmptySession(): ChatSession {
return {
id: nanoid(),
Expand Down Expand Up @@ -407,6 +418,7 @@ export const useChatStore = createPersistStore(
async onUserInput(
content: string,
attachImages?: string[],
attachFiles?: AttachedFile[],
isMcpResponse?: boolean,
) {
const session = get().currentSession();
Expand All @@ -417,14 +429,26 @@ export const useChatStore = createPersistStore(
? content
: fillTemplateWith(content, modelConfig);

if (!isMcpResponse && attachImages && attachImages.length > 0) {
if (!isMcpResponse) {
mContent = [
...(content ? [{ type: "text" as const, text: content }] : []),
...attachImages.map((url) => ({
type: "image_url" as const,
image_url: { url },
})),
];
if (attachImages && attachImages.length > 0) {
mContent.push(
...attachImages.map((url) => ({
type: "image_url" as const,
image_url: { url },
})),
);
}
if (attachFiles && attachFiles.length > 0) {
mContent.push(
...attachFiles.map((file) => ({
type: "text" as const,
text: file.name + "\n\n---\n\n" + (file.text ?? ""),
})),
);
}
}

let userMessage: ChatMessage = createMessage({
Expand Down Expand Up @@ -844,6 +868,7 @@ export const useChatStore = createPersistStore(
get().onUserInput(
`\`\`\`json:mcp-response:${mcpRequest.clientId}\n${mcpResponse}\n\`\`\``,
[],
[],
true,
);
})
Expand Down