feat: add workspace files to chat from Files and Changes
* feat(app): open changed files from context menu * fix(app): preserve changed-file row behavior * feat(app): add changed files to open chats * feat(app): share file actions across explorer and changes * feat(app): attach workspace files to focused chat * feat(app): drag workspace files into chat * refactor(app): use file actions menu for changed files * fix(app): open changed-file actions on right click * test(app): cover direct file attachment flow * fix(app): enable add to chat on native * fix(app): align workspace file pane rows * refactor(app): simplify workspace file attachments * fix(app): preserve uploaded file draft attachments --------- Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
This commit is contained in:
co-authored by
Mohamed Boudra
parent
42ee5a5949
commit
bd937850b3
@@ -0,0 +1,56 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useHosts } from "@/runtime/host-runtime";
|
||||
import { useDownloadStore } from "@/stores/download-store";
|
||||
import { useFileExplorerActions } from "@/hooks/use-file-explorer-actions";
|
||||
|
||||
interface UseFileDownloadParams {
|
||||
serverId: string;
|
||||
workspaceId?: string | null;
|
||||
workspaceRoot: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stable callback that downloads a single workspace file by its
|
||||
* workspace-relative path. Shared by the file explorer tree and the git diff
|
||||
* pane so both surfaces download through the same host token + download-store
|
||||
* pipeline instead of duplicating the plumbing.
|
||||
*/
|
||||
export function useFileDownload({
|
||||
serverId,
|
||||
workspaceId,
|
||||
workspaceRoot,
|
||||
}: UseFileDownloadParams): (input: { fileName: string; path: string }) => void {
|
||||
const daemons = useHosts();
|
||||
const daemonProfile = useMemo(
|
||||
() => daemons.find((daemon) => daemon.serverId === serverId),
|
||||
[daemons, serverId],
|
||||
);
|
||||
const normalizedWorkspaceRoot = useMemo(() => workspaceRoot.trim(), [workspaceRoot]);
|
||||
const workspaceScopeId = useMemo(
|
||||
() => workspaceId?.trim() || normalizedWorkspaceRoot,
|
||||
[normalizedWorkspaceRoot, workspaceId],
|
||||
);
|
||||
const { requestFileDownloadToken } = useFileExplorerActions({
|
||||
serverId,
|
||||
workspaceId,
|
||||
workspaceRoot: normalizedWorkspaceRoot,
|
||||
});
|
||||
const startDownload = useDownloadStore((state) => state.startDownload);
|
||||
|
||||
return useCallback(
|
||||
({ fileName, path }) => {
|
||||
if (!workspaceScopeId) {
|
||||
return;
|
||||
}
|
||||
void startDownload({
|
||||
serverId,
|
||||
scopeId: workspaceScopeId,
|
||||
fileName,
|
||||
path,
|
||||
daemonProfile,
|
||||
requestFileDownloadToken: (targetPath) => requestFileDownloadToken(targetPath),
|
||||
});
|
||||
},
|
||||
[daemonProfile, requestFileDownloadToken, serverId, startDownload, workspaceScopeId],
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user