Skip to content

Commit 36a4269

Browse files
committed
frontend/aria/hotkey: compute tree only when dialog is visible
1 parent 24cb036 commit 36a4269

File tree

4 files changed

+49
-37
lines changed

4 files changed

+49
-37
lines changed

src/packages/frontend/app/hotkey/build-tree.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import {
99
ACCOUNT_MAIN_MENU_ITEMS,
1010
PREFERENCES_SUB_TABS,
1111
} from "@cocalc/frontend/account/account-preferences-config";
12-
import { isIntlMessage, labels } from "@cocalc/frontend/i18n";
13-
import type { IntlMessage } from "@cocalc/frontend/i18n";
14-
import AIAvatar from "@cocalc/frontend/components/ai-avatar";
1512
import { Icon, IconName } from "@cocalc/frontend/components";
13+
import AIAvatar from "@cocalc/frontend/components/ai-avatar";
1614
import { filenameIcon } from "@cocalc/frontend/file-associations";
15+
import type { IntlMessage } from "@cocalc/frontend/i18n";
16+
import { isIntlMessage, labels } from "@cocalc/frontend/i18n";
1717
import type { FixedTab } from "@cocalc/frontend/project/page/file-tab";
1818
import { FIXED_PROJECT_TABS } from "@cocalc/frontend/project/page/file-tab";
1919
import { COLORS } from "@cocalc/util/theme";

src/packages/frontend/app/hotkey/dialog.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import {
1919
} from "@cocalc/frontend/misc/local-storage";
2020
import { RenderFrameTree } from "./render-frame-tree";
2121
import type { AppPageAction, FrameInfo } from "./build-tree";
22+
import {
23+
useActiveFrameData,
24+
useEnhancedNavigationTreeData,
25+
} from "./use-navigation-data";
2226
import { focusFrameWithRetry } from "./util";
2327

2428
// Extended TreeDataNode with navigation data
@@ -53,11 +57,6 @@ export interface NavigationTreeNode extends TreeDataNode {
5357
interface QuickNavigationDialogProps {
5458
visible: boolean;
5559
onClose: () => void;
56-
treeData: NavigationTreeNode[];
57-
frameTreeStructure?: any; // Frame tree visualization structure
58-
activeFrames?: FrameInfo[]; // Current active frames for keyboard shortcuts
59-
activeFileName?: string; // Path to currently open file
60-
activeProjectId?: string; // ID of currently active project
6160
}
6261

6362
/**
@@ -260,13 +259,13 @@ function saveExpandedKeys(
260259
export const QuickNavigationDialog: React.FC<QuickNavigationDialogProps> = ({
261260
visible,
262261
onClose,
263-
treeData,
264-
frameTreeStructure,
265-
activeFrames,
266-
activeFileName,
267-
activeProjectId,
268262
}) => {
269263
const intl = useIntl();
264+
// Compute navigation tree data only when dialog is visible
265+
// Pass skip=!visible to skip computation when dialog is closed
266+
const treeData = useEnhancedNavigationTreeData(!visible);
267+
const { frameTreeStructure, activeFrames, activeFileName, activeProjectId } =
268+
useActiveFrameData(!visible);
270269
const searchInputRef = useRef<any>(null);
271270
const treeContainerRef = useRef<HTMLDivElement>(null);
272271
const [searchValue, setSearchValue] = useState("");

src/packages/frontend/app/hotkey/use-navigation-data.ts

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,24 @@ declare var DEBUG: boolean;
88
import { useMemo } from "react";
99
import { useIntl } from "react-intl";
1010

11+
import { switchAccountPage } from "@cocalc/frontend/account/util";
1112
import {
1213
redux,
1314
useActions,
14-
useTypedRedux,
1515
useRedux,
16+
useTypedRedux,
1617
} from "@cocalc/frontend/app-framework";
18+
import type { EditorSpec } from "@cocalc/frontend/frame-editors/frame-tree/types";
19+
import { labels } from "@cocalc/frontend/i18n";
20+
import type { FixedTab } from "@cocalc/frontend/project/page/file-tab";
21+
import { FIXED_PROJECT_TABS } from "@cocalc/frontend/project/page/file-tab";
1722
import { useBookmarkedProjects } from "@cocalc/frontend/projects/use-bookmarked-projects";
1823
import {
24+
getRandomColor,
1925
path_to_tab,
2026
trunc_middle,
2127
unreachable,
22-
getRandomColor,
2328
} from "@cocalc/util/misc";
24-
2529
import {
2630
buildNavigationTree,
2731
PageInfo,
@@ -32,11 +36,6 @@ import {
3236
type ProjectInfo,
3337
} from "./build-tree";
3438
import type { NavigationTreeNode } from "./dialog";
35-
import { switchAccountPage } from "@cocalc/frontend/account/util";
36-
import { labels } from "@cocalc/frontend/i18n";
37-
import type { EditorSpec } from "@cocalc/frontend/frame-editors/frame-tree/types";
38-
import type { FixedTab } from "@cocalc/frontend/project/page/file-tab";
39-
import { FIXED_PROJECT_TABS } from "@cocalc/frontend/project/page/file-tab";
4039
import {
4140
ensureFrameFilePath,
4241
focusFrameWithRetry,
@@ -171,8 +170,12 @@ function extractFramesFromTree(
171170
* - Current project (prioritized)
172171
* - All other projects
173172
* - Account pages (hardcoded, always available)
173+
*
174+
* @param skip - If true, skip computation and return empty array (used to avoid updates when dialog is closed)
174175
*/
175-
export function useNavigationTreeData(): NavigationTreeNode[] {
176+
export function useNavigationTreeData(
177+
skip: boolean = false,
178+
): NavigationTreeNode[] {
176179
const intl = useIntl();
177180
const is_logged_in = useTypedRedux("account", "is_logged_in");
178181
const is_anonymous = useTypedRedux("account", "is_anonymous");
@@ -216,6 +219,10 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
216219
// This would improve navigation for frequently-used files across all projects,
217220
// following accessibility best practices for quick navigation dialogs
218221
const projectsData = useMemo(() => {
222+
// Short-circuit if dialog is closed
223+
if (skip) {
224+
return [];
225+
}
219226
// if (DEBUG) {
220227
// console.log("useNavigationTreeData - Building projectsData:", {
221228
// openProjectsLength: open_projects?.size,
@@ -339,6 +346,7 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
339346
})
340347
.filter((p): p is ProjectInfo => p !== null);
341348
}, [
349+
skip,
342350
project_map,
343351
open_projects,
344352
project_id,
@@ -435,8 +443,10 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
435443
/**
436444
* Hook that returns just the frame tree structure and active frames
437445
* (without the full tree data)
446+
*
447+
* @param skip - If true, skip computation and return empty values (used to avoid updates when dialog is closed)
438448
*/
439-
export function useActiveFrameData(): {
449+
export function useActiveFrameData(skip: boolean = false): {
440450
frameTreeStructure: FrameTreeStructure | null;
441451
activeFrames: FrameInfo[];
442452
activeFileName?: string;
@@ -514,7 +524,8 @@ export function useActiveFrameData(): {
514524
const activeFrameTree = useRedux(frameTreePath);
515525

516526
const { activeFrames, frameTreeStructure } = useMemo(() => {
517-
if (!activeEditorContext.activeFileName || !activeFrameTree) {
527+
// Short-circuit if dialog is closed
528+
if (skip || !activeEditorContext.activeFileName || !activeFrameTree) {
518529
return {
519530
activeFrames: [],
520531
frameTreeStructure: null,
@@ -549,6 +560,7 @@ export function useActiveFrameData(): {
549560
frameTreeStructure: result.treeStructure,
550561
};
551562
}, [
563+
skip,
552564
activeFrameTree,
553565
activeEditorContext.activeFileName,
554566
activeEditorContext.editorSpec,
@@ -567,9 +579,13 @@ export function useActiveFrameData(): {
567579
/**
568580
* Hook that adds action handlers to tree nodes
569581
* Ties navigation to Redux actions and routing
582+
*
583+
* @param skip - If true, skip computation and return empty array (used to avoid updates when dialog is closed)
570584
*/
571-
export function useEnhancedNavigationTreeData(): NavigationTreeNode[] {
572-
const treeData = useNavigationTreeData();
585+
export function useEnhancedNavigationTreeData(
586+
skip: boolean = false,
587+
): NavigationTreeNode[] {
588+
const treeData = useNavigationTreeData(skip);
573589
const active_top_tab = useTypedRedux("page", "active_top_tab");
574590

575591
// Get project_id from active_top_tab (same logic as useNavigationTreeData)
@@ -582,6 +598,11 @@ export function useEnhancedNavigationTreeData(): NavigationTreeNode[] {
582598

583599
// Enhance tree nodes with action handlers
584600
const enhancedTreeData = useMemo(() => {
601+
// If we're skipping, treeData will be empty array
602+
if (treeData.length === 0) {
603+
return [];
604+
}
605+
585606
const enhanceNode = (node: NavigationTreeNode): NavigationTreeNode => {
586607
if (node.navigationData) {
587608
const navData = node.navigationData;
@@ -720,7 +741,9 @@ export function useEnhancedNavigationTreeData(): NavigationTreeNode[] {
720741
};
721742

722743
return treeData.map(enhanceNode);
723-
}, [treeData, project_id, page_actions]);
744+
}, [treeData, project_id, page_actions, skip]);
745+
746+
console.log("returning", enhancedTreeData);
724747

725748
return enhancedTreeData;
726749
}

src/packages/frontend/app/page.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ import { Icon } from "@cocalc/frontend/components/icon";
2929
import {
3030
GlobalHotkeyDetector,
3131
QuickNavigationDialog,
32-
useActiveFrameData,
33-
useEnhancedNavigationTreeData,
3432
} from "@cocalc/frontend/app/hotkey";
3533
import Next from "@cocalc/frontend/components/next";
3634
import { FileUsePage } from "@cocalc/frontend/file-use/page";
@@ -131,9 +129,6 @@ export const Page: React.FC = () => {
131129
const quick_nav_hotkey_delay =
132130
other_settings?.get("quick_nav_hotkey_delay") ?? DEFAULT_HOTKEY_DELAY_MS;
133131
const [quick_nav_visible, setQuickNavVisible] = useState<boolean>(false);
134-
const quick_nav_tree_data = useEnhancedNavigationTreeData();
135-
const { frameTreeStructure, activeFrames, activeFileName, activeProjectId } =
136-
useActiveFrameData();
137132

138133
const accountIsReady = useTypedRedux("account", "is_ready");
139134
const account_id = useTypedRedux("account", "account_id");
@@ -427,11 +422,6 @@ export const Page: React.FC = () => {
427422
<QuickNavigationDialog
428423
visible={quick_nav_visible}
429424
onClose={() => setQuickNavVisible(false)}
430-
treeData={quick_nav_tree_data}
431-
frameTreeStructure={frameTreeStructure}
432-
activeFrames={activeFrames}
433-
activeFileName={activeFileName}
434-
activeProjectId={activeProjectId}
435425
/>
436426
</div>
437427
);

0 commit comments

Comments
 (0)