refactor IPC (#341)

This commit is contained in:
Lingxuan Zuo
2026-03-08 11:54:49 +08:00
committed by GitHub
Unverified
parent c03d92e9a2
commit 3d804a9f5e
52 changed files with 3121 additions and 336 deletions

View File

@@ -10,6 +10,7 @@ import { useState, useRef, useEffect, useCallback } from 'react';
import { Send, Square, X, Paperclip, FileText, Film, Music, FileArchive, File, Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Textarea } from '@/components/ui/textarea';
import { invokeIpc } from '@/lib/api-client';
// ── Types ────────────────────────────────────────────────────────
@@ -100,7 +101,7 @@ export function ChatInput({ onSend, onStop, disabled = false, sending = false }:
const pickFiles = useCallback(async () => {
try {
const result = await window.electron.ipcRenderer.invoke('dialog:open', {
const result = await invokeIpc('dialog:open', {
properties: ['openFile', 'multiSelections'],
}) as { canceled: boolean; filePaths?: string[] };
if (result.canceled || !result.filePaths?.length) return;
@@ -125,7 +126,7 @@ export function ChatInput({ onSend, onStop, disabled = false, sending = false }:
// Stage all files via IPC
console.log('[pickFiles] Staging files:', result.filePaths);
const staged = await window.electron.ipcRenderer.invoke(
const staged = await invokeIpc(
'file:stage',
result.filePaths,
) as Array<{
@@ -192,7 +193,7 @@ export function ChatInput({ onSend, onStop, disabled = false, sending = false }:
console.log(`[stageBuffer] Reading file: ${file.name} (${file.type}, ${file.size} bytes)`);
const base64 = await readFileAsBase64(file);
console.log(`[stageBuffer] Base64 length: ${base64?.length ?? 'null'}`);
const staged = await window.electron.ipcRenderer.invoke('file:stageBuffer', {
const staged = await invokeIpc('file:stageBuffer', {
base64,
fileName: file.name,
mimeType: file.type || 'application/octet-stream',
@@ -226,6 +227,7 @@ export function ChatInput({ onSend, onStop, disabled = false, sending = false }:
}, []);
const allReady = attachments.length === 0 || attachments.every(a => a.status === 'ready');
const hasFailedAttachments = attachments.some((a) => a.status === 'error');
const canSend = (input.trim() || attachments.length > 0) && allReady && !disabled && !sending;
const canStop = sending && !disabled && !!onStop;
@@ -391,6 +393,22 @@ export function ChatInput({ onSend, onStop, disabled = false, sending = false }:
)}
</Button>
</div>
<div className="mt-1 flex items-center justify-between gap-2 text-xs text-muted-foreground">
<span>Tip: switch sessions from the sidebar to keep context clean.</span>
{hasFailedAttachments && (
<Button
variant="link"
size="sm"
className="h-auto p-0 text-xs"
onClick={() => {
setAttachments((prev) => prev.filter((att) => att.status !== 'error'));
void pickFiles();
}}
>
Retry failed attachments
</Button>
)}
</div>
</div>
</div>
);

View File

@@ -10,6 +10,7 @@ import remarkGfm from 'remark-gfm';
import { createPortal } from 'react-dom';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { invokeIpc } from '@/lib/api-client';
import type { RawMessage, AttachedFileMeta } from '@/stores/chat';
import { extractText, extractThinking, extractImages, extractToolUse, formatTimestamp } from './message-utils';
@@ -539,7 +540,7 @@ function ImageLightbox({
const handleShowInFolder = useCallback(() => {
if (filePath) {
window.electron.ipcRenderer.invoke('shell:showItemInFolder', filePath);
invokeIpc('shell:showItemInFolder', filePath);
}
}, [filePath]);