@@ -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,
@@ -308,7 +315,7 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
308315 if ( starred_files ) {
309316 const allStarred = Array . isArray ( starred_files )
310317 ? starred_files
311- : ( starred_files . toArray ?.( ) ?? [ ] ) ;
318+ : starred_files . toArray ?.( ) ?? [ ] ;
312319 starredFiles = allStarred . filter (
313320 ( path ) => ! openFilePaths . has ( path ) ,
314321 ) ;
@@ -321,7 +328,7 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
321328 if ( otherStarredFiles ) {
322329 const allStarred = Array . isArray ( otherStarredFiles )
323330 ? otherStarredFiles
324- : ( otherStarredFiles . toArray ?.( ) ?? [ ] ) ;
331+ : otherStarredFiles . toArray ?.( ) ?? [ ] ;
325332 starredFiles = allStarred . filter (
326333 ( path ) => ! openFilePaths . has ( path ) ,
327334 ) ;
@@ -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 ,
@@ -355,7 +363,7 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
355363
356364 // Build ProjectInfo for bookmarked projects (excluding open projects)
357365 const bookmarkedProjectsData = useMemo ( ( ) => {
358- if ( ! bookmarksInitialized || ! project_map ) {
366+ if ( skip || ! bookmarksInitialized || ! project_map ) {
359367 return [ ] ;
360368 }
361369
@@ -377,9 +385,13 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
377385 } as ProjectInfo ;
378386 } )
379387 . filter ( ( p ) : p is ProjectInfo => p !== null ) ;
380- } , [ bookmarkedProjectIds , project_map , bookmarksInitialized ] ) ;
388+ } , [ skip , bookmarkedProjectIds , project_map , bookmarksInitialized ] ) ;
381389
382390 const appPages : AppPageInfo [ ] = useMemo ( ( ) => {
391+ if ( skip ) {
392+ return [ ] ;
393+ }
394+
383395 const pages : AppPageInfo [ ] = [ ] ;
384396
385397 const projectsLabel = intl . formatMessage ( labels . projects ) ;
@@ -412,10 +424,14 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
412424 }
413425
414426 return pages ;
415- } , [ intl , is_logged_in , is_anonymous ] ) ;
427+ } , [ skip , intl , is_logged_in , is_anonymous ] ) ;
416428
417429 // Build the complete navigation tree
418430 const treeData = useMemo ( ( ) => {
431+ if ( skip ) {
432+ return [ ] ;
433+ }
434+
419435 const currentProject =
420436 projectsData . find ( ( p ) => p . id === project_id ) || null ;
421437 const otherProjects = projectsData . filter ( ( p ) => p . id !== project_id ) ;
@@ -427,16 +443,18 @@ export function useNavigationTreeData(): NavigationTreeNode[] {
427443 appPages ,
428444 intl ,
429445 ) ;
430- } , [ projectsData , project_id , bookmarkedProjectsData , appPages , intl ] ) ;
446+ } , [ skip , projectsData , project_id , bookmarkedProjectsData , appPages , intl ] ) ;
431447
432448 return treeData ;
433449}
434450
435451/**
436452 * Hook that returns just the frame tree structure and active frames
437453 * (without the full tree data)
454+ *
455+ * @param skip - If true, skip computation and return empty values (used to avoid updates when dialog is closed)
438456 */
439- export function useActiveFrameData ( ) : {
457+ export function useActiveFrameData ( skip : boolean = false ) : {
440458 frameTreeStructure : FrameTreeStructure | null ;
441459 activeFrames : FrameInfo [ ] ;
442460 activeFileName ?: string ;
@@ -514,7 +532,8 @@ export function useActiveFrameData(): {
514532 const activeFrameTree = useRedux ( frameTreePath ) ;
515533
516534 const { activeFrames, frameTreeStructure } = useMemo ( ( ) => {
517- if ( ! activeEditorContext . activeFileName || ! activeFrameTree ) {
535+ // Short-circuit if dialog is closed
536+ if ( skip || ! activeEditorContext . activeFileName || ! activeFrameTree ) {
518537 return {
519538 activeFrames : [ ] ,
520539 frameTreeStructure : null ,
@@ -549,6 +568,7 @@ export function useActiveFrameData(): {
549568 frameTreeStructure : result . treeStructure ,
550569 } ;
551570 } , [
571+ skip ,
552572 activeFrameTree ,
553573 activeEditorContext . activeFileName ,
554574 activeEditorContext . editorSpec ,
@@ -567,9 +587,13 @@ export function useActiveFrameData(): {
567587/**
568588 * Hook that adds action handlers to tree nodes
569589 * Ties navigation to Redux actions and routing
590+ *
591+ * @param skip - If true, skip computation and return empty array (used to avoid updates when dialog is closed)
570592 */
571- export function useEnhancedNavigationTreeData ( ) : NavigationTreeNode [ ] {
572- const treeData = useNavigationTreeData ( ) ;
593+ export function useEnhancedNavigationTreeData (
594+ skip : boolean = false ,
595+ ) : NavigationTreeNode [ ] {
596+ const treeData = useNavigationTreeData ( skip ) ;
573597 const active_top_tab = useTypedRedux ( "page" , "active_top_tab" ) ;
574598
575599 // Get project_id from active_top_tab (same logic as useNavigationTreeData)
@@ -582,6 +606,10 @@ export function useEnhancedNavigationTreeData(): NavigationTreeNode[] {
582606
583607 // Enhance tree nodes with action handlers
584608 const enhancedTreeData = useMemo ( ( ) => {
609+ if ( skip || treeData . length === 0 ) {
610+ return [ ] ;
611+ }
612+
585613 const enhanceNode = ( node : NavigationTreeNode ) : NavigationTreeNode => {
586614 if ( node . navigationData ) {
587615 const navData = node . navigationData ;
@@ -720,7 +748,7 @@ export function useEnhancedNavigationTreeData(): NavigationTreeNode[] {
720748 } ;
721749
722750 return treeData . map ( enhanceNode ) ;
723- } , [ treeData , project_id , page_actions ] ) ;
751+ } , [ skip , treeData , project_id , page_actions ] ) ;
724752
725753 return enhancedTreeData ;
726754}
0 commit comments