Improve files view behavior and Open In integration (#579)

* feat: open focused file in selected desktop app

* fix: make file tree indicators match active open tabs

* fix: limit preview functionality to markdown files only

* feat: add Open In action to file editor toolbar. add antigravity to openin app list
This commit is contained in:
Iuliia Ivashko
2026-03-03 01:07:03 +02:00
committed by GitHub
parent 604ac682c2
commit bcbc2646fd
7 changed files with 421 additions and 110 deletions
+10 -1
View File
@@ -23,6 +23,7 @@ import { useSessionStore } from '@/stores/useSessionStore';
import { useProjectsStore } from '@/stores/useProjectsStore';
import { useQuotaAutoRefresh, useQuotaStore } from '@/stores/useQuotaStore';
import { useDirectoryStore } from '@/stores/useDirectoryStore';
import { useFilesViewTabsStore } from '@/stores/useFilesViewTabsStore';
import { useGitHubAuthStore } from '@/stores/useGitHubAuthStore';
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
@@ -506,6 +507,14 @@ export const Header: React.FC<HeaderProps> = ({
return worktreeDirectory || sessionDirectory || draftDirectory;
}, [draftDirectory, sessionDirectory, worktreeDirectory]);
const selectedFilePath = useFilesViewTabsStore((state) => {
const directory = normalize(openDirectory || '');
if (!directory) {
return null;
}
return state.byRoot[directory]?.selectedPath ?? null;
});
const actionDirectory = React.useMemo(() => {
return normalize(openDirectory || activeProject?.path || '');
}, [activeProject?.path, openDirectory]);
@@ -1084,7 +1093,7 @@ export const Header: React.FC<HeaderProps> = ({
</TooltipContent>
</Tooltip>
)}
<OpenInAppButton directory={openDirectory} className="mr-1" />
<OpenInAppButton directory={openDirectory} activeFilePath={selectedFilePath} className="mr-1" />
<DropdownMenu
open={isDesktopServicesOpen}
onOpenChange={(open) => {
@@ -305,13 +305,20 @@ export const SidebarFilesTree: React.FC = () => {
const inFlightDirsRef = React.useRef<Set<string>>(new Set());
const EMPTY_PATHS: string[] = React.useMemo(() => [], []);
const EMPTY_CONTEXT_TABS: Array<{ mode: string; targetPath: string | null }> = React.useMemo(() => [], []);
const expandedPaths = useFilesViewTabsStore((state) => (root ? (state.byRoot[root]?.expandedPaths ?? EMPTY_PATHS) : EMPTY_PATHS));
const openPaths = useFilesViewTabsStore((state) => (root ? (state.byRoot[root]?.openPaths ?? EMPTY_PATHS) : EMPTY_PATHS));
const selectedPath = useFilesViewTabsStore((state) => (root ? (state.byRoot[root]?.selectedPath ?? null) : null));
const setSelectedPath = useFilesViewTabsStore((state) => state.setSelectedPath);
const addOpenPath = useFilesViewTabsStore((state) => state.addOpenPath);
const removeOpenPathsByPrefix = useFilesViewTabsStore((state) => state.removeOpenPathsByPrefix);
const toggleExpandedPath = useFilesViewTabsStore((state) => state.toggleExpandedPath);
const contextTabs = useUIStore((state) => (root ? (state.contextPanelByDirectory[root]?.tabs ?? EMPTY_CONTEXT_TABS) : EMPTY_CONTEXT_TABS));
const openContextFilePaths = React.useMemo(() => new Set(
contextTabs
.map((tab) => (tab.mode === 'file' ? tab.targetPath : null))
.filter((targetPath): targetPath is string => typeof targetPath === 'string' && targetPath.length > 0)
.map((targetPath) => normalizePath(targetPath))
), [contextTabs]);
// Context menu state
const [contextMenuPath, setContextMenuPath] = React.useState<string | null>(null);
@@ -552,7 +559,7 @@ export const SidebarFilesTree: React.FC = () => {
// --- Git status helpers (matching FilesView) ---
const getFileStatus = React.useCallback((path: string): FileStatus | null => {
if (openPaths.includes(path)) return 'open';
if (openContextFilePaths.has(path)) return 'open';
if (gitStatus?.files) {
const relative = path.startsWith(root + '/') ? path.slice(root.length + 1) : path;
@@ -564,7 +571,7 @@ export const SidebarFilesTree: React.FC = () => {
}
}
return null;
}, [openPaths, gitStatus, root]);
}, [openContextFilePaths, gitStatus, root]);
const getFolderBadge = React.useCallback((dirPath: string): { modified: number; added: number } | null => {
if (!gitStatus?.files) return null;