mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-04 18:59:08 +01:00
fix issue where tabs are immediately visible while they're still stacked on load (#362)
This fixes the visual bug where the active tab seems to be the first tab and then switches to the actual active tab after the tabs are positioned.
This commit is contained in:
parent
8f0cd5adcf
commit
f6fc0125fd
@ -9,6 +9,7 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
.tab-inner {
|
.tab-inner {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -51,9 +51,6 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
const tabsWrapperRef = useRef<HTMLDivElement>(null);
|
const tabsWrapperRef = useRef<HTMLDivElement>(null);
|
||||||
const tabRefs = useRef<React.RefObject<HTMLDivElement>[]>([]);
|
const tabRefs = useRef<React.RefObject<HTMLDivElement>[]>([]);
|
||||||
const addBtnRef = useRef<HTMLDivElement>(null);
|
const addBtnRef = useRef<HTMLDivElement>(null);
|
||||||
const draggingTimeoutIdRef = useRef<NodeJS.Timeout>(null);
|
|
||||||
const scrollToNewTabTimeoutIdRef = useRef<NodeJS.Timeout>(null);
|
|
||||||
const newTabIdTimeoutIdRef = useRef<NodeJS.Timeout>(null);
|
|
||||||
const draggingRemovedRef = useRef(false);
|
const draggingRemovedRef = useRef(false);
|
||||||
const draggingTabDataRef = useRef({
|
const draggingTabDataRef = useRef({
|
||||||
tabId: "",
|
tabId: "",
|
||||||
@ -119,9 +116,7 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
setDragStartPositions(newStartPositions);
|
setDragStartPositions(newStartPositions);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const debouncedSaveTabsPosition = debounce(100, () => saveTabsPosition());
|
const setSizeAndPosition = (animate?: boolean) => {
|
||||||
|
|
||||||
const updateSizeAndPosition = (animate?: boolean) => {
|
|
||||||
const tabBar = tabBarRef.current;
|
const tabBar = tabBarRef.current;
|
||||||
if (tabBar === null) return;
|
if (tabBar === null) return;
|
||||||
|
|
||||||
@ -166,6 +161,7 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
}
|
}
|
||||||
ref.current.style.width = `${newTabWidth}px`;
|
ref.current.style.width = `${newTabWidth}px`;
|
||||||
ref.current.style.transform = `translate3d(${index * newTabWidth}px,0,0)`;
|
ref.current.style.transform = `translate3d(${index * newTabWidth}px,0,0)`;
|
||||||
|
ref.current.style.opacity = "1";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -188,8 +184,8 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleResizeTabs = useCallback(() => {
|
const handleResizeTabs = useCallback(() => {
|
||||||
updateSizeAndPosition();
|
setSizeAndPosition();
|
||||||
debouncedSaveTabsPosition();
|
debounce(100, () => saveTabsPosition())();
|
||||||
}, [tabIds, newTabId, isFullScreen]);
|
}, [tabIds, newTabId, isFullScreen]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -203,28 +199,13 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
// Check if all tabs are loaded
|
// Check if all tabs are loaded
|
||||||
const allLoaded = tabIds.length > 0 && tabIds.every((id) => tabsLoaded[id]);
|
const allLoaded = tabIds.length > 0 && tabIds.every((id) => tabsLoaded[id]);
|
||||||
if (allLoaded) {
|
if (allLoaded) {
|
||||||
updateSizeAndPosition(newTabId === null && prevAllLoadedRef.current);
|
setSizeAndPosition(newTabId === null && prevAllLoadedRef.current);
|
||||||
saveTabsPosition();
|
saveTabsPosition();
|
||||||
if (!prevAllLoadedRef.current) {
|
if (!prevAllLoadedRef.current) {
|
||||||
prevAllLoadedRef.current = true;
|
prevAllLoadedRef.current = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [tabIds, tabsLoaded, newTabId, handleResizeTabs, saveTabsPosition]);
|
}, [tabIds, tabsLoaded, newTabId, saveTabsPosition]);
|
||||||
|
|
||||||
// Make sure timeouts are cleared when component is unmounted
|
|
||||||
useEffect(() => {
|
|
||||||
return () => {
|
|
||||||
if (draggingTimeoutIdRef.current) {
|
|
||||||
clearTimeout(draggingTimeoutIdRef.current);
|
|
||||||
}
|
|
||||||
if (scrollToNewTabTimeoutIdRef.current) {
|
|
||||||
clearTimeout(scrollToNewTabTimeoutIdRef.current);
|
|
||||||
}
|
|
||||||
if (newTabIdTimeoutIdRef.current) {
|
|
||||||
clearTimeout(newTabIdTimeoutIdRef.current);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const getDragDirection = (currentX: number) => {
|
const getDragDirection = (currentX: number) => {
|
||||||
let dragDirection;
|
let dragDirection;
|
||||||
@ -381,7 +362,7 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dragged) {
|
if (dragged) {
|
||||||
draggingTimeoutIdRef.current = setTimeout(() => {
|
debounce(300, () => {
|
||||||
// Reset styles
|
// Reset styles
|
||||||
tabRefs.current.forEach((ref) => {
|
tabRefs.current.forEach((ref) => {
|
||||||
ref.current.style.zIndex = "0";
|
ref.current.style.zIndex = "0";
|
||||||
@ -391,7 +372,7 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
setDraggingTab(null);
|
setDraggingTab(null);
|
||||||
// Update workspace tab ids
|
// Update workspace tab ids
|
||||||
services.ObjectService.UpdateWorkspaceTabIds(workspace.oid, tabIds);
|
services.ObjectService.UpdateWorkspaceTabIds(workspace.oid, tabIds);
|
||||||
}, 300);
|
})();
|
||||||
} else {
|
} else {
|
||||||
// Reset styles
|
// Reset styles
|
||||||
tabRefs.current.forEach((ref) => {
|
tabRefs.current.forEach((ref) => {
|
||||||
@ -427,10 +408,6 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
|
|
||||||
document.addEventListener("mousemove", handleMouseMove);
|
document.addEventListener("mousemove", handleMouseMove);
|
||||||
document.addEventListener("mouseup", handleMouseUp);
|
document.addEventListener("mouseup", handleMouseUp);
|
||||||
|
|
||||||
if (draggingTimeoutIdRef.current) {
|
|
||||||
clearTimeout(draggingTimeoutIdRef.current);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[tabIds, dragStartPositions]
|
[tabIds, dragStartPositions]
|
||||||
@ -452,16 +429,14 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
tabsWrapperRef.current.style.transition;
|
tabsWrapperRef.current.style.transition;
|
||||||
tabsWrapperRef.current.style.setProperty("--tabs-wrapper-transition", "width 0.1s ease");
|
tabsWrapperRef.current.style.setProperty("--tabs-wrapper-transition", "width 0.1s ease");
|
||||||
|
|
||||||
scrollToNewTabTimeoutIdRef.current = setTimeout(() => {
|
debounce(300, () => {
|
||||||
if (scrollableRef.current) {
|
if (scrollableRef.current) {
|
||||||
const { viewport } = osInstanceRef.current.elements();
|
const { viewport } = osInstanceRef.current.elements();
|
||||||
viewport.scrollLeft = tabIds.length * tabWidthRef.current;
|
viewport.scrollLeft = tabIds.length * tabWidthRef.current;
|
||||||
}
|
}
|
||||||
}, 30);
|
})();
|
||||||
|
|
||||||
newTabIdTimeoutIdRef.current = setTimeout(() => {
|
debounce(100, () => setNewTabId(null))();
|
||||||
setNewTabId(null);
|
|
||||||
}, 100);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCloseTab = (event: React.MouseEvent<HTMLButtonElement, MouseEvent> | null, tabId: string) => {
|
const handleCloseTab = (event: React.MouseEvent<HTMLButtonElement, MouseEvent> | null, tabId: string) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user