Attach dropped files in every composer (#1750)
* fix(app): attach dropped files in composer Composer parents had to expose attachment callbacks, so New Workspace only wired image drops and JSON files never became file attachments. Centralize dropped-file ingestion in Composer so all composer surfaces share the same image and file path. * fix(app): handle desktop dropped attachment paths
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { View, Text } from "react-native";
|
||||
import type { StyleProp, ViewStyle } from "react-native";
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
import Animated, { useAnimatedStyle, withTiming, useSharedValue } from "react-native-reanimated";
|
||||
import { useEffect, useMemo } from "react";
|
||||
@@ -13,6 +14,7 @@ interface FileDropZoneProps {
|
||||
onFilesDropped: (files: ImageAttachment[]) => void;
|
||||
onGenericFilesDropped?: (items: DroppedItem[]) => void;
|
||||
disabled?: boolean;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
}
|
||||
|
||||
const IS_WEB = isWeb;
|
||||
@@ -22,6 +24,7 @@ export function FileDropZone({
|
||||
onFilesDropped,
|
||||
onGenericFilesDropped,
|
||||
disabled = false,
|
||||
style,
|
||||
}: FileDropZoneProps) {
|
||||
const { t } = useTranslation();
|
||||
const { theme } = useUnistyles();
|
||||
@@ -46,6 +49,7 @@ export function FileDropZone({
|
||||
() => [styles.overlay, overlayAnimatedStyle],
|
||||
[overlayAnimatedStyle],
|
||||
);
|
||||
const containerStyle = useMemo(() => [styles.container, style], [style]);
|
||||
|
||||
// On non-web platforms, just render children
|
||||
if (!IS_WEB) {
|
||||
@@ -56,7 +60,7 @@ export function FileDropZone({
|
||||
<View
|
||||
// Cast ref for web - View renders as div on web
|
||||
ref={containerRef as unknown as React.RefObject<View>}
|
||||
style={styles.container}
|
||||
style={containerStyle}
|
||||
>
|
||||
{children}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Image, Text, View } from "react-native";
|
||||
import { StyleSheet } from "react-native-unistyles";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -26,7 +26,7 @@ import { projectIconPlaceholderLabelFromDisplayName } from "@/utils/project-disp
|
||||
import { requireWorkspaceDirectory } from "@/utils/workspace-directory";
|
||||
import { navigateToAgent } from "@/utils/navigate-to-agent";
|
||||
import { navigateToPreparedWorkspaceTab } from "@/utils/workspace-navigation";
|
||||
import type { ImageAttachment, MessagePayload } from "@/composer/types";
|
||||
import type { MessagePayload } from "@/composer/types";
|
||||
|
||||
function toProjectIconDataUri(icon: { mimeType: string; data: string } | null): string | null {
|
||||
if (!icon) {
|
||||
@@ -363,14 +363,6 @@ export function WorkspaceSetupDialog() {
|
||||
const placeholderLabel = projectIconPlaceholderLabelFromDisplayName(workspaceTitle);
|
||||
const placeholderInitial = placeholderLabel.charAt(0).toUpperCase();
|
||||
|
||||
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 isCompact = useIsCompactFormFactor();
|
||||
const iconSource = useMemo(() => (iconDataUri ? { uri: iconDataUri } : null), [iconDataUri]);
|
||||
const agentControlsWithDisabled = useMemo(
|
||||
@@ -427,7 +419,6 @@ export function WorkspaceSetupDialog() {
|
||||
snapPoints={SNAP_POINTS}
|
||||
testID="workspace-setup-dialog"
|
||||
desktopMaxWidth={640}
|
||||
onFilesDropped={handleFilesDropped}
|
||||
>
|
||||
<View style={styles.section}>
|
||||
<Composer
|
||||
@@ -447,7 +438,6 @@ export function WorkspaceSetupDialog() {
|
||||
commandDraftConfig={composerState?.commandDraftConfig}
|
||||
agentControls={agentControlsWithDisabled}
|
||||
inputWrapperStyle={styles.composerInputWrapper}
|
||||
onAddImages={handleAddImagesCallback}
|
||||
footer={composerFooter}
|
||||
/>
|
||||
</View>
|
||||
|
||||
Reference in New Issue
Block a user