feat: improve terminal scrollbar and pane focus handling
This commit is contained in:
@@ -57,7 +57,7 @@ type WorkspaceDesktopTabsRowProps = {
|
||||
onSelectNewTabOption: (selection: NewTabSelection) => void;
|
||||
newTabAgentOptionId: NewTabOptionId;
|
||||
onReorderTabs: (nextTabs: WorkspaceTabDescriptor[]) => void;
|
||||
onNewTerminalTab: () => void;
|
||||
onNewTerminalTab: (input: { paneId?: string }) => void;
|
||||
onSplitRight: () => void;
|
||||
onSplitDown: () => void;
|
||||
externalDndContext?: boolean;
|
||||
@@ -346,7 +346,7 @@ export function WorkspaceDesktopTabsRow({
|
||||
data={tabs}
|
||||
keyExtractor={(tab) => `${tab.tab.key}:${tab.tab.kind}`}
|
||||
useDragHandle
|
||||
disabled={tabs.length < 2}
|
||||
disabled={!externalDndContext && tabs.length < 2}
|
||||
onDragEnd={(nextTabs) => onReorderTabs(nextTabs.map((tab) => tab.tab))}
|
||||
externalDndContext={externalDndContext}
|
||||
activeId={activeDragTabId}
|
||||
@@ -428,7 +428,7 @@ export function WorkspaceDesktopTabsRow({
|
||||
</Tooltip>
|
||||
<Tooltip delayDuration={0} enabledOnDesktop enabledOnMobile={false}>
|
||||
<TooltipTrigger
|
||||
onPress={onNewTerminalTab}
|
||||
onPress={() => onNewTerminalTab({ paneId })}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="New terminal tab"
|
||||
style={({ hovered, pressed }) => [
|
||||
|
||||
@@ -554,13 +554,13 @@ function WorkspaceScreenContent({
|
||||
});
|
||||
const terminals = terminalsQuery.data?.terminals ?? [];
|
||||
const createTerminalMutation = useMutation({
|
||||
mutationFn: async () => {
|
||||
mutationFn: async (input?: { paneId?: string }) => {
|
||||
if (!client) {
|
||||
throw new Error("Host is not connected");
|
||||
}
|
||||
return await client.createTerminal(normalizedWorkspaceId);
|
||||
},
|
||||
onSuccess: (payload) => {
|
||||
onSuccess: (payload, input) => {
|
||||
const createdTerminal = payload.terminal;
|
||||
if (createdTerminal) {
|
||||
queryClient.setQueryData<ListTerminalsPayload>(
|
||||
@@ -588,6 +588,9 @@ function WorkspaceScreenContent({
|
||||
if (!workspaceKey) {
|
||||
return;
|
||||
}
|
||||
if (input?.paneId) {
|
||||
focusWorkspacePane(workspaceKey, input.paneId);
|
||||
}
|
||||
const tabId = useWorkspaceLayoutStore
|
||||
.getState()
|
||||
.openTab(workspaceKey, { kind: "terminal", terminalId: createdTerminal.id });
|
||||
@@ -1133,14 +1136,14 @@ function WorkspaceScreenContent({
|
||||
openWorkspaceDraftTab();
|
||||
}, [openWorkspaceDraftTab]);
|
||||
|
||||
const handleCreateTerminal = useCallback(() => {
|
||||
const handleCreateTerminal = useCallback((input?: { paneId?: string }) => {
|
||||
if (createTerminalMutation.isPending) {
|
||||
return;
|
||||
}
|
||||
if (!normalizedWorkspaceId.startsWith("/")) {
|
||||
return;
|
||||
}
|
||||
createTerminalMutation.mutate();
|
||||
createTerminalMutation.mutate(input);
|
||||
}, [createTerminalMutation, normalizedWorkspaceId]);
|
||||
|
||||
const handleSelectSwitcherTab = useCallback(
|
||||
@@ -1162,6 +1165,23 @@ function WorkspaceScreenContent({
|
||||
[focusWorkspacePane, handleCreateDraftTab, persistenceKey]
|
||||
);
|
||||
|
||||
const handleCreateDraftSplit = useCallback(
|
||||
(input: { targetPaneId: string; position: "left" | "right" | "top" | "bottom" }) => {
|
||||
if (!persistenceKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
const paneId = splitWorkspacePaneEmpty(persistenceKey, input);
|
||||
if (!paneId) {
|
||||
return;
|
||||
}
|
||||
|
||||
focusWorkspacePane(persistenceKey, paneId);
|
||||
openWorkspaceDraftTab();
|
||||
},
|
||||
[focusWorkspacePane, openWorkspaceDraftTab, persistenceKey, splitWorkspacePaneEmpty]
|
||||
);
|
||||
|
||||
const runCloseFlowForTab = useCallback(
|
||||
async (input: { tabId: string; action: () => Promise<void> }): Promise<void> => {
|
||||
const normalizedTabId = input.tabId.trim();
|
||||
@@ -1569,26 +1589,18 @@ function WorkspaceScreenContent({
|
||||
}
|
||||
|
||||
if (action.id === "workspace.pane.split.right") {
|
||||
const activePaneTabId = focusedPaneTabState.activeTabId;
|
||||
if (activePaneTabId) {
|
||||
splitWorkspacePane(persistenceKey, {
|
||||
tabId: activePaneTabId,
|
||||
targetPaneId: focusedPane.id,
|
||||
position: "right",
|
||||
});
|
||||
}
|
||||
handleCreateDraftSplit({
|
||||
targetPaneId: focusedPane.id,
|
||||
position: "right",
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action.id === "workspace.pane.split.down") {
|
||||
const activePaneTabId = focusedPaneTabState.activeTabId;
|
||||
if (activePaneTabId) {
|
||||
splitWorkspacePane(persistenceKey, {
|
||||
tabId: activePaneTabId,
|
||||
targetPaneId: focusedPane.id,
|
||||
position: "bottom",
|
||||
});
|
||||
}
|
||||
handleCreateDraftSplit({
|
||||
targetPaneId: focusedPane.id,
|
||||
position: "bottom",
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1647,9 +1659,9 @@ function WorkspaceScreenContent({
|
||||
[
|
||||
closeWorkspaceTab,
|
||||
focusWorkspacePane,
|
||||
handleCreateDraftSplit,
|
||||
moveWorkspaceTabToPane,
|
||||
persistenceKey,
|
||||
splitWorkspacePane,
|
||||
focusedPaneTabState.activeTabId,
|
||||
focusedPaneTabState.pane,
|
||||
workspaceLayout,
|
||||
@@ -2023,7 +2035,7 @@ function WorkspaceScreenContent({
|
||||
splitWorkspacePane(persistenceKey, input);
|
||||
}}
|
||||
onSplitPaneEmpty={(input) => {
|
||||
splitWorkspacePaneEmpty(persistenceKey, input);
|
||||
handleCreateDraftSplit(input);
|
||||
}}
|
||||
onMoveTabToPane={(tabId, toPaneId) => {
|
||||
moveWorkspaceTabToPane(persistenceKey, tabId, toPaneId);
|
||||
|
||||
Reference in New Issue
Block a user