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:
Red J Adaya 2024-09-11 14:06:27 +08:00 committed by GitHub
parent 8f0cd5adcf
commit f6fc0125fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 36 deletions

View File

@ -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;

View File

@ -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) => {