fix(app): make cmd+o work regardless of sidebar visibility
The worktree.new keyboard handler was registered inside ProjectHeaderRow, which only mounts when the sidebar is open. Register a single global handler in the app layout keyed off the navigation-active workspace selection.
This commit is contained in:
@@ -64,6 +64,7 @@ import { ProjectPickerModal } from "@/components/project-picker-modal";
|
|||||||
import { KeyboardShortcutsDialog } from "@/components/keyboard-shortcuts-dialog";
|
import { KeyboardShortcutsDialog } from "@/components/keyboard-shortcuts-dialog";
|
||||||
import { WorkspaceSetupDialog } from "@/components/workspace-setup-dialog";
|
import { WorkspaceSetupDialog } from "@/components/workspace-setup-dialog";
|
||||||
import { useKeyboardShortcuts } from "@/hooks/use-keyboard-shortcuts";
|
import { useKeyboardShortcuts } from "@/hooks/use-keyboard-shortcuts";
|
||||||
|
import { useActiveWorktreeNewAction } from "@/hooks/use-active-worktree-new-action";
|
||||||
import { queryClient } from "@/query/query-client";
|
import { queryClient } from "@/query/query-client";
|
||||||
import {
|
import {
|
||||||
WEB_NOTIFICATION_CLICK_EVENT,
|
WEB_NOTIFICATION_CLICK_EVENT,
|
||||||
@@ -443,6 +444,8 @@ function AppContainer({
|
|||||||
cycleTheme,
|
cycleTheme,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useActiveWorktreeNewAction();
|
||||||
|
|
||||||
const containerStyle = useMemo(
|
const containerStyle = useMemo(
|
||||||
() => ({ flex: 1 as const, backgroundColor: theme.colors.surface0 }),
|
() => ({ flex: 1 as const, backgroundColor: theme.colors.surface0 }),
|
||||||
[theme.colors.surface0],
|
[theme.colors.surface0],
|
||||||
|
|||||||
@@ -797,17 +797,6 @@ function ProjectHeaderRow({
|
|||||||
const mergeWorkspaces = useSessionStore((state) => state.mergeWorkspaces);
|
const mergeWorkspaces = useSessionStore((state) => state.mergeWorkspaces);
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
useKeyboardActionHandler({
|
|
||||||
handlerId: `worktree-new-${project.projectKey}`,
|
|
||||||
actions: ["worktree.new"],
|
|
||||||
enabled: isProjectActive && canCreateWorktree && Boolean(serverId),
|
|
||||||
priority: 0,
|
|
||||||
handle: () => {
|
|
||||||
handleBeginWorkspaceSetup();
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const interaction = useLongPressDragInteraction({
|
const interaction = useLongPressDragInteraction({
|
||||||
drag,
|
drag,
|
||||||
menuController,
|
menuController,
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { useCallback } from "react";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import { useKeyboardActionHandler } from "@/hooks/use-keyboard-action-handler";
|
||||||
|
import type { KeyboardActionId } from "@/keyboard/keyboard-action-dispatcher";
|
||||||
|
import { useNavigationActiveWorkspaceSelection } from "@/stores/navigation-active-workspace-store";
|
||||||
|
import { useSessionStore } from "@/stores/session-store";
|
||||||
|
import { buildHostNewWorkspaceRoute } from "@/utils/host-routes";
|
||||||
|
import { projectDisplayNameFromProjectId } from "@/utils/project-display-name";
|
||||||
|
|
||||||
|
const WORKTREE_NEW_ACTIONS: readonly KeyboardActionId[] = ["worktree.new"];
|
||||||
|
|
||||||
|
export function useActiveWorktreeNewAction() {
|
||||||
|
const selection = useNavigationActiveWorkspaceSelection();
|
||||||
|
const serverId = selection?.serverId ?? null;
|
||||||
|
const workspaceId = selection?.workspaceId ?? null;
|
||||||
|
|
||||||
|
const workingDir = useSessionStore((state) => {
|
||||||
|
if (!serverId || !workspaceId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const workspace = state.sessions[serverId]?.workspaces?.get(workspaceId);
|
||||||
|
if (!workspace || workspace.projectKind !== "git") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return workspace.projectRootPath;
|
||||||
|
});
|
||||||
|
|
||||||
|
const displayName = useSessionStore((state) => {
|
||||||
|
if (!serverId || !workspaceId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const workspace = state.sessions[serverId]?.workspaces?.get(workspaceId);
|
||||||
|
if (!workspace || workspace.projectKind !== "git") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return workspace.projectDisplayName || projectDisplayNameFromProjectId(workspace.projectId);
|
||||||
|
});
|
||||||
|
|
||||||
|
const handle = useCallback(() => {
|
||||||
|
if (!serverId || !workingDir) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
router.navigate(
|
||||||
|
buildHostNewWorkspaceRoute(serverId, workingDir, {
|
||||||
|
displayName: displayName ?? undefined,
|
||||||
|
}) as never,
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}, [serverId, workingDir, displayName]);
|
||||||
|
|
||||||
|
useKeyboardActionHandler({
|
||||||
|
handlerId: "worktree-new-active",
|
||||||
|
actions: WORKTREE_NEW_ACTIONS,
|
||||||
|
enabled: serverId !== null && workingDir !== null,
|
||||||
|
priority: 0,
|
||||||
|
handle,
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user