@@ -11,22 +11,18 @@ import { LayoutModel } from "./layoutModel";
1111import { LayoutNode , NodeModel , TileLayoutContents } from "./types" ;
1212
1313const layoutModelMap : Map < string , LayoutModel > = new Map ( ) ;
14+ const timeoutMap : Map < string , NodeJS . Timeout | null > = new Map ( ) ;
1415
1516export function getLayoutModelForTab ( tabAtom : Atom < Tab > ) : LayoutModel {
1617 const tabData = globalStore . get ( tabAtom ) ;
1718 if ( ! tabData ) return ;
1819 const tabId = tabData . oid ;
19- if ( layoutModelMap . has ( tabId ) ) {
20- const layoutModel = layoutModelMap . get ( tabData . oid ) ;
21- if ( layoutModel ) {
22- return layoutModel ;
23- }
24- }
25- const layoutTreeStateAtom = withLayoutTreeStateAtomFromTab ( tabAtom ) ;
26- const layoutModel = new LayoutModel ( layoutTreeStateAtom , globalStore . get , globalStore . set ) ;
27- globalStore . sub ( layoutTreeStateAtom , ( ) => fireAndForget ( layoutModel . onTreeStateAtomUpdated . bind ( layoutModel ) ) ) ;
28- layoutModelMap . set ( tabId , layoutModel ) ;
29- return layoutModel ;
20+ return computeIfAbsent ( layoutModelMap , tabId , ( _ ) => {
21+ const layoutTreeStateAtom = withLayoutTreeStateAtomFromTab ( tabAtom ) ;
22+ const layoutModel = new LayoutModel ( layoutTreeStateAtom , globalStore . get , globalStore . set ) ;
23+ globalStore . sub ( layoutTreeStateAtom , ( ) => fireAndForget ( layoutModel . onTreeStateAtomUpdated . bind ( layoutModel ) ) ) ;
24+ return layoutModel ;
25+ } )
3026}
3127
3228export function getLayoutModelForTabById ( tabId : string ) {
@@ -73,25 +69,26 @@ export function useDebouncedNodeInnerRect(nodeModel: NodeModel): CSSProperties {
7369 const isResizing = useAtomValue ( nodeModel . isResizing ) ;
7470 const prefersReducedMotion = useAtomValue ( atoms . prefersReducedMotionAtom ) ;
7571 const [ innerRect , setInnerRect ] = useState < CSSProperties > ( ) ;
76- const [ innerRectDebounceTimeout , setInnerRectDebounceTimeout ] = useState < NodeJS . Timeout > ( ) ;
7772
7873 const setInnerRectDebounced = useCallback (
7974 ( nodeInnerRect : CSSProperties ) => {
8075 clearInnerRectDebounce ( ) ;
81- setInnerRectDebounceTimeout (
82- setTimeout ( ( ) => {
83- setInnerRect ( nodeInnerRect ) ;
84- } , animationTimeS * 1000 )
85- ) ;
76+ const timeout = setTimeout ( ( ) => {
77+ setInnerRect ( nodeInnerRect ) ;
78+ } , animationTimeS * 1000 ) ;
79+ computeIfAbsent ( timeoutMap , nodeModel . blockId , ( _ ) => timeout )
8680 } ,
8781 [ animationTimeS ]
8882 ) ;
89- const clearInnerRectDebounce = useCallback ( ( ) => {
90- if ( innerRectDebounceTimeout ) {
91- clearTimeout ( innerRectDebounceTimeout ) ;
92- setInnerRectDebounceTimeout ( undefined ) ;
83+ const clearInnerRectDebounce = function ( ) {
84+ if ( timeoutMap . has ( nodeModel . blockId ) ) {
85+ const innerRectDebounceTimeout = timeoutMap . get ( nodeModel . blockId ) ;
86+ if ( innerRectDebounceTimeout ) {
87+ clearTimeout ( innerRectDebounceTimeout ) ;
88+ }
89+ timeoutMap . delete ( nodeModel . blockId ) ;
9390 }
94- } , [ innerRectDebounceTimeout ] ) ;
91+ } ;
9592
9693 useEffect ( ( ) => {
9794 if ( prefersReducedMotion || isMagnified || isResizing ) {
@@ -104,3 +101,11 @@ export function useDebouncedNodeInnerRect(nodeModel: NodeModel): CSSProperties {
104101
105102 return innerRect ;
106103}
104+
105+ function computeIfAbsent < V , F > ( map : Map < V , F > , key : V , mappingFunction : ( a : V ) => F ) : F {
106+ if ( ! map . has ( key ) ) {
107+ const newValue = mappingFunction ( key ) ;
108+ map . set ( key , newValue ) ;
109+ }
110+ return map . get ( key ) ;
111+ }
0 commit comments