@@ -8,20 +8,24 @@ declare var DEBUG: boolean;
88import { useMemo } from "react" ;
99import { useIntl } from "react-intl" ;
1010
11+ import { switchAccountPage } from "@cocalc/frontend/account/util" ;
1112import {
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" ;
1722import { useBookmarkedProjects } from "@cocalc/frontend/projects/use-bookmarked-projects" ;
1823import {
24+ getRandomColor ,
1925 path_to_tab ,
2026 trunc_middle ,
2127 unreachable ,
22- getRandomColor ,
2328} from "@cocalc/util/misc" ;
24-
2529import {
2630 buildNavigationTree ,
2731 PageInfo ,
@@ -32,11 +36,6 @@ import {
3236 type ProjectInfo ,
3337} from "./build-tree" ;
3438import 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" ;
4039import {
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}
0 commit comments