diff --git a/src/components/chat/chat-input.tsx b/src/components/chat/chat-input.tsx index 49a46f4..4b71409 100644 --- a/src/components/chat/chat-input.tsx +++ b/src/components/chat/chat-input.tsx @@ -12,7 +12,6 @@ import type { AvailableCommandInfo, } from "@/lib/types" import type { QueuedMessage } from "@/hooks/use-message-queue" -import { ConversationContextBar } from "@/components/chat/conversation-context-bar" import { MessageInput } from "@/components/chat/message-input" import { MessageQueueDisplay } from "@/components/chat/message-queue-display" @@ -93,7 +92,6 @@ export const ChatInput = memo(function ChatInput({ className="p-4 pt-0" onContextMenu={(event) => event.stopPropagation()} > - {queue && queue.length > 0 && onQueueReorder && diff --git a/src/components/chat/conversation-context-bar.tsx b/src/components/chat/conversation-context-bar.tsx index 0963ab8..839cc7a 100644 --- a/src/components/chat/conversation-context-bar.tsx +++ b/src/components/chat/conversation-context-bar.tsx @@ -9,13 +9,8 @@ import { Folder, FolderOpen, GitBranch, - GitCommit, - GitMerge, Loader2, - MoreHorizontal, - Upload, Plus, - Archive, Trash2, } from "lucide-react" import { useAppWorkspace } from "@/contexts/app-workspace-context" @@ -26,10 +21,6 @@ import { gitCheckout, gitNewBranch, gitDeleteBranch, - openCommitWindow, - openPushWindow, - openStashWindow, - openMergeWindow, } from "@/lib/api" import { isDesktop, openFileDialog } from "@/lib/platform" import type { GitBranchList } from "@/lib/types" @@ -49,13 +40,6 @@ import { CommandList, CommandSeparator, } from "@/components/ui/command" -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu" import { Dialog, DialogContent, @@ -69,10 +53,15 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" -import { Separator } from "@/components/ui/separator" import { cn } from "@/lib/utils" -export const ConversationContextBar = memo(function ConversationContextBar() { +interface ConversationContextBarProps { + tabId?: string | null +} + +export const ConversationContextBar = memo(function ConversationContextBar({ + tabId, +}: ConversationContextBarProps = {}) { const t = useTranslations("Folder.conversationContextBar") const tBd = useTranslations("Folder.branchDropdown") const { tabs, activeTabId, setTabFolder } = useTabContext() @@ -87,32 +76,32 @@ export const ConversationContextBar = memo(function ConversationContextBar() { } = useAppWorkspace() const { addTask, updateTask } = useTaskContext() - const activeTab = useMemo( - () => tabs.find((x) => x.id === activeTabId) ?? null, - [tabs, activeTabId] - ) + const ownTab = useMemo(() => { + const lookupId = tabId ?? activeTabId + return tabs.find((x) => x.id === lookupId) ?? null + }, [tabs, tabId, activeTabId]) - const activeFolder = useMemo( + const ownFolder = useMemo( () => - activeTab - ? (allFolders.find((f) => f.id === activeTab.folderId) ?? null) + ownTab + ? (allFolders.find((f) => f.id === ownTab.folderId) ?? null) : null, - [activeTab, allFolders] + [ownTab, allFolders] ) - if (!activeTab || !activeFolder) return null + if (!ownTab || !ownFolder) return null - const isNewConversation = activeTab.conversationId == null + const isNewConversation = ownTab.conversationId == null const currentBranch = - branches.get(activeFolder.id) ?? activeFolder.git_branch ?? null + branches.get(ownFolder.id) ?? ownFolder.git_branch ?? null return ( -
+
{ const target = allFolders.find((f) => f.id === folderId) @@ -122,7 +111,7 @@ export const ConversationContextBar = memo(function ConversationContextBar() { const detail = isOpen ? target : await addFolderToWorkspaceById(folderId) - setTabFolder(activeTab.id, detail.id, detail.path) + setTabFolder(ownTab.id, detail.id, detail.path) toast.success(t("toasts.folderChanged", { name: detail.name })) } catch (err) { console.error( @@ -142,7 +131,7 @@ export const ConversationContextBar = memo(function ConversationContextBar() { if (!result) return const selected = Array.isArray(result) ? result[0] : result const detail = await openFolder(selected) - setTabFolder(activeTab.id, detail.id, detail.path) + setTabFolder(ownTab.id, detail.id, detail.path) toast.success(t("toasts.folderChanged", { name: detail.name })) } } catch (err) { @@ -155,20 +144,18 @@ export const ConversationContextBar = memo(function ConversationContextBar() { labelSearch={t("searchFolder")} /> - - { - const taskId = `checkout-${activeFolder.id}-${Date.now()}` + const taskId = `checkout-${ownFolder.id}-${Date.now()}` addTask(taskId, tBd("tasks.checkoutTo", { branchName })) updateTask(taskId, { status: "running" }) try { - await gitCheckout(activeFolder.path, branchName) - setBranch(activeFolder.id, branchName) - await refreshFolder(activeFolder.id) + await gitCheckout(ownFolder.path, branchName) + setBranch(ownFolder.id, branchName) + await refreshFolder(ownFolder.id) updateTask(taskId, { status: "completed" }) } catch (err) { const msg = err instanceof Error ? err.message : String(err) @@ -177,13 +164,13 @@ export const ConversationContextBar = memo(function ConversationContextBar() { } }} onNewBranch={async (branchName, startPoint) => { - const taskId = `new-branch-${activeFolder.id}-${Date.now()}` + const taskId = `new-branch-${ownFolder.id}-${Date.now()}` addTask(taskId, tBd("tasks.newBranch", { name: branchName })) updateTask(taskId, { status: "running" }) try { - await gitNewBranch(activeFolder.path, branchName, startPoint) - setBranch(activeFolder.id, branchName) - await refreshFolder(activeFolder.id) + await gitNewBranch(ownFolder.path, branchName, startPoint) + setBranch(ownFolder.id, branchName) + await refreshFolder(ownFolder.id) updateTask(taskId, { status: "completed" }) } catch (err) { const msg = err instanceof Error ? err.message : String(err) @@ -192,11 +179,11 @@ export const ConversationContextBar = memo(function ConversationContextBar() { } }} onDeleteBranch={async (branchName) => { - const taskId = `delete-branch-${activeFolder.id}-${Date.now()}` + const taskId = `delete-branch-${ownFolder.id}-${Date.now()}` addTask(taskId, tBd("tasks.deleteBranch", { branchName })) updateTask(taskId, { status: "running" }) try { - await gitDeleteBranch(activeFolder.path, branchName, false) + await gitDeleteBranch(ownFolder.path, branchName, false) updateTask(taskId, { status: "completed" }) } catch (err) { const msg = err instanceof Error ? err.message : String(err) @@ -205,13 +192,6 @@ export const ConversationContextBar = memo(function ConversationContextBar() { } }} /> - -
- -
) @@ -250,19 +230,16 @@ const FolderPicker = memo(function FolderPicker({ const trigger = ( ) @@ -381,15 +358,15 @@ const BranchPicker = memo(function BranchPicker({ @@ -517,124 +494,3 @@ const BranchPicker = memo(function BranchPicker({ ) }) - -// ============================================================================ -// GitActionButtons -// ============================================================================ - -interface GitActionButtonsProps { - folderId: number - currentBranch: string | null -} - -const GitActionButtons = memo(function GitActionButtons({ - folderId, - currentBranch, -}: GitActionButtonsProps) { - const t = useTranslations("Folder.conversationContextBar") - const tBd = useTranslations("Folder.branchDropdown") - - const handleCommit = useCallback(async () => { - try { - await openCommitWindow(folderId) - } catch (err) { - console.error("[GitActions] commit failed:", err) - toast.error(tBd("toasts.openCommitWindowFailed")) - } - }, [folderId, tBd]) - - const handlePush = useCallback(async () => { - try { - await openPushWindow(folderId) - } catch (err) { - console.error("[GitActions] push failed:", err) - toast.error(tBd("toasts.openPushWindowFailed")) - } - }, [folderId, tBd]) - - const handleStash = useCallback(async () => { - try { - await openStashWindow(folderId) - } catch (err) { - console.error("[GitActions] stash failed:", err) - toast.error(t("toasts.openStashFailed")) - } - }, [folderId, t]) - - const handleMerge = useCallback(async () => { - try { - await openMergeWindow(folderId, "merge") - } catch (err) { - console.error("[GitActions] merge failed:", err) - toast.error(t("toasts.openMergeFailed")) - } - }, [folderId, t]) - - return ( -
- - - - - {tBd("openCommitWindow")} - - - - - - - {tBd("pushCode")} - - - - - - - - - - {t("merge")} - - - - {tBd("stashChanges")} - - - - - {tBd("openCommitWindow")} - - - - {tBd("pushCode")} - - - -
- ) -}) diff --git a/src/components/chat/message-input.tsx b/src/components/chat/message-input.tsx index 5fba2b7..1c0cc6f 100644 --- a/src/components/chat/message-input.tsx +++ b/src/components/chat/message-input.tsx @@ -59,6 +59,7 @@ import { type AttachFileToSessionDetail, type AppendTextToSessionDetail, } from "@/lib/session-attachment-events" +import { ConversationContextBar } from "@/components/chat/conversation-context-bar" import { ModeSelector } from "@/components/chat/mode-selector" import { SessionConfigSelector } from "@/components/chat/session-config-selector" import { @@ -1919,6 +1920,7 @@ export function MessageInput({ className )} > + {(hasImageAttachments || hasResourceAttachments) && (
{hasImageAttachments && (