Skip to content

Commit b217275

Browse files
committed
fix issue wavetermdev#1625
1 parent 0d7439e commit b217275

File tree

1 file changed

+27
-22
lines changed

1 file changed

+27
-22
lines changed

frontend/layout/lib/layoutModelHooks.ts

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,18 @@ import { LayoutModel } from "./layoutModel";
1111
import { LayoutNode, NodeModel, TileLayoutContents } from "./types";
1212

1313
const layoutModelMap: Map<string, LayoutModel> = new Map();
14+
const timeoutMap: Map<string, NodeJS.Timeout | null> = new Map();
1415

1516
export 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

3228
export 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

Comments
 (0)