Open project and workspace folders from the sidebar (#2491)

* feat(app): open project folder from project context menu (#2487)

* refactor(app): give file manager action a home

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
This commit is contained in:
Kamil
2026-07-28 00:48:29 +02:00
committed by GitHub
co-authored by Mohamed Boudra
parent f8dd0fc2e0
commit 89c2fac3c6
11 changed files with 84 additions and 0 deletions
@@ -0,0 +1,54 @@
import { useCallback } from "react";
import { useTranslation } from "react-i18next";
import { FolderOpen } from "lucide-react-native";
import { withUnistyles } from "react-native-unistyles";
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
import { getIsElectron } from "@/constants/platform";
import { useToast } from "@/contexts/toast-context";
import type { Theme } from "@/styles/theme";
import { openDesktopTarget, useDesktopOpenTargets } from "@/workspace/desktop-open-targets";
interface OpenInFileManagerMenuItemProps {
path?: string | null;
testID: string;
}
const ThemedFolderOpen = withUnistyles(FolderOpen);
const foregroundMutedColorMapping = (theme: Theme) => ({
color: theme.colors.foregroundMuted,
});
const leadingIcon = <ThemedFolderOpen size={14} uniProps={foregroundMutedColorMapping} />;
export function OpenInFileManagerMenuItem({ path, testID }: OpenInFileManagerMenuItemProps) {
const { t } = useTranslation();
const toast = useToast();
const isElectron = getIsElectron();
const workspacePath = path?.trim() ?? "";
const { targets } = useDesktopOpenTargets({
isLocalExecution: isElectron && workspacePath.length > 0,
});
const fileManagerTarget = targets.find((target) => target.kind === "file-manager");
const openInFileManager = useCallback(() => {
if (!fileManagerTarget || workspacePath.length === 0) return;
void openDesktopTarget({
editorId: fileManagerTarget.id,
workspacePath,
}).catch((error) => {
console.warn("[open-in-file-manager] open failed", error);
toast.error(t("sidebar.project.actions.openFolderFailed"));
});
}, [fileManagerTarget, t, toast, workspacePath]);
if (!isElectron || !fileManagerTarget || workspacePath.length === 0) {
return null;
}
return (
<DropdownMenuItem testID={testID} leading={leadingIcon} onSelect={openInFileManager}>
{t("sidebar.project.actions.openFolder")}
</DropdownMenuItem>
);
}