feat: add drag-and-drop image upload to new agent screen

This commit is contained in:
Mohamed Boudra
2026-01-08 10:31:58 +07:00
parent a515f1fd03
commit 80886592ac
+35 -20
View File
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type { ImageAttachment } from "@/components/message-input";
import { import {
View, View,
Text, Text,
@@ -15,6 +16,7 @@ import {
GitOptionsSection, GitOptionsSection,
WorkingDirectoryDropdown, WorkingDirectoryDropdown,
} from "@/components/agent-form/agent-form-dropdowns"; } from "@/components/agent-form/agent-form-dropdowns";
import { FileDropZone } from "@/components/file-drop-zone";
import { useDaemonRequest } from "@/hooks/use-daemon-request"; import { useDaemonRequest } from "@/hooks/use-daemon-request";
import type { SessionOutboundMessage } from "@server/server/messages"; import type { SessionOutboundMessage } from "@server/server/messages";
import { useAgentFormState, type CreateAgentInitialValues } from "@/hooks/use-agent-form-state"; import { useAgentFormState, type CreateAgentInitialValues } from "@/hooks/use-agent-form-state";
@@ -168,6 +170,16 @@ export default function HomeScreen() {
const [branchNameEdited, setBranchNameEdited] = useState(false); const [branchNameEdited, setBranchNameEdited] = useState(false);
const [worktreeSlugEdited, setWorktreeSlugEdited] = useState(false); const [worktreeSlugEdited, setWorktreeSlugEdited] = useState(false);
const shouldSyncBaseBranchRef = useRef(true); const shouldSyncBaseBranchRef = useRef(true);
const addImagesRef = useRef<((images: ImageAttachment[]) => void) | null>(null);
const handleFilesDropped = useCallback((files: ImageAttachment[]) => {
addImagesRef.current?.(files);
}, []);
const handleAddImagesCallback = useCallback((addImages: (images: ImageAttachment[]) => void) => {
addImagesRef.current = addImages;
}, []);
const createNewBranch = isolationMode === "branch" || isolationMode === "worktree"; const createNewBranch = isolationMode === "branch" || isolationMode === "worktree";
const createWorktree = isolationMode === "worktree"; const createWorktree = isolationMode === "worktree";
const openDropdownSheet = useCallback( const openDropdownSheet = useCallback(
@@ -670,26 +682,27 @@ export default function HomeScreen() {
: "Automatic"; : "Automatic";
return ( return (
<View style={styles.container}> <FileDropZone onFilesDropped={handleFilesDropped}>
<View style={styles.agentPanel}> <View style={styles.container}>
<MenuHeader <View style={styles.agentPanel}>
title="New Agent" <MenuHeader
rightContent={ title="New Agent"
<Pressable rightContent={
style={styles.hostBadge} <Pressable
onPress={() => openDropdownSheet("host")} style={styles.hostBadge}
> onPress={() => openDropdownSheet("host")}
<Monitor size={14} color={theme.colors.mutedForeground} /> >
<Text style={styles.hostBadgeLabel}>{hostLabel}</Text> <Monitor size={14} color={theme.colors.mutedForeground} />
<View <Text style={styles.hostBadgeLabel}>{hostLabel}</Text>
style={[ <View
styles.hostStatusDot, style={[
hostEntry?.status === "online" && styles.hostStatusDotOnline, styles.hostStatusDot,
]} hostEntry?.status === "online" && styles.hostStatusDotOnline,
/> ]}
</Pressable> />
} </Pressable>
/> }
/>
<ScrollView style={styles.contentContainer} contentContainerStyle={styles.configScrollContent}> <ScrollView style={styles.contentContainer} contentContainerStyle={styles.configScrollContent}>
<View style={styles.configSection}> <View style={styles.configSection}>
@@ -930,10 +943,12 @@ export default function HomeScreen() {
value={promptText} value={promptText}
onChangeText={setPromptText} onChangeText={setPromptText}
autoFocus autoFocus
onAddImages={handleAddImagesCallback}
/> />
</View> </View>
</View> </View>
</View> </View>
</FileDropZone>
); );
} }