From a16d992cbe3957333232b7478ca3ef2704ac3f2a Mon Sep 17 00:00:00 2001 From: JATIN Date: Tue, 31 Dec 2024 21:51:58 +0530 Subject: [PATCH 1/5] fix ProjectOptions closes issue #3303 The issue stemmed from the use of a setTimeout in the onBlur handler that closed the project options too quickly. Specifically, the setTimeout(() => dispatch(closeProjectOptions()), 0) was causing the options to close even if the user had not finished interacting with the menu. This was particularly problematic with trackpad input, where the timing of the events could be misinterpreted. --- client/modules/IDE/components/Sidebar.jsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/modules/IDE/components/Sidebar.jsx b/client/modules/IDE/components/Sidebar.jsx index 79ffed3b8..9b51af1ac 100644 --- a/client/modules/IDE/components/Sidebar.jsx +++ b/client/modules/IDE/components/Sidebar.jsx @@ -94,7 +94,6 @@ export default function SideBar() { aria-label={t('Sidebar.AddFolderARIA')} onClick={() => { dispatch(newFolder(rootFile.id)); - setTimeout(() => dispatch(closeProjectOptions()), 0); }} onBlur={onBlurComponent} > @@ -106,7 +105,6 @@ export default function SideBar() { aria-label={t('Sidebar.AddFileARIA')} onClick={() => { dispatch(newFile(rootFile.id)); - setTimeout(() => dispatch(closeProjectOptions()), 0); }} onBlur={onBlurComponent} > @@ -119,7 +117,6 @@ export default function SideBar() { aria-label={t('Sidebar.UploadFileARIA')} onClick={() => { dispatch(openUploadFileModal(rootFile.id)); - setTimeout(() => dispatch(closeProjectOptions()), 0); }} onBlur={onBlurComponent} > From e5ee1ccb6b2d7357dd1b7e9ae5d453f253547ea6 Mon Sep 17 00:00:00 2001 From: JATIN Date: Tue, 31 Dec 2024 21:58:19 +0530 Subject: [PATCH 2/5] fix issue#3303 ProjectOptions closes The issue stemmed from the use of a setTimeout in the onBlur handler that closed the project options too quickly. Specifically, the setTimeout(() => dispatch(closeProjectOptions()), 0) was causing the options to close even if the user had not finished interacting with the menu. This was particularly problematic with trackpad input, where the timing of the events could be misinterpreted. --- client/modules/IDE/components/Sidebar.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/modules/IDE/components/Sidebar.jsx b/client/modules/IDE/components/Sidebar.jsx index 9b51af1ac..21fb23a3b 100644 --- a/client/modules/IDE/components/Sidebar.jsx +++ b/client/modules/IDE/components/Sidebar.jsx @@ -131,4 +131,4 @@ export default function SideBar() { ); -} +} \ No newline at end of file From 9b9bfa5c5569ec0e6d3dc8a7dd02c3a8fa7acc3a Mon Sep 17 00:00:00 2001 From: JATIN Date: Wed, 5 Mar 2025 00:58:18 +0530 Subject: [PATCH 3/5] fix linting Issue --- client/modules/IDE/components/Sidebar.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/modules/IDE/components/Sidebar.jsx b/client/modules/IDE/components/Sidebar.jsx index 403ac4540..179e7dbf1 100644 --- a/client/modules/IDE/components/Sidebar.jsx +++ b/client/modules/IDE/components/Sidebar.jsx @@ -134,4 +134,4 @@ export default function SideBar() { ); -} \ No newline at end of file +} From 15d8b431bebe29a245d1abbdceeff59530ae4b2e Mon Sep 17 00:00:00 2001 From: JATIN Date: Wed, 5 Mar 2025 02:40:41 +0530 Subject: [PATCH 4/5] Using UseEffect for the Closing projectOption and Upgrading onBlur --- client/modules/IDE/components/Sidebar.jsx | 107 ++++++++++++---------- 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/client/modules/IDE/components/Sidebar.jsx b/client/modules/IDE/components/Sidebar.jsx index 179e7dbf1..7d52cbbda 100644 --- a/client/modules/IDE/components/Sidebar.jsx +++ b/client/modules/IDE/components/Sidebar.jsx @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useRef, useEffect } from 'react'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; @@ -30,21 +30,38 @@ export default function SideBar() { ); const isExpanded = useSelector((state) => state.ide.sidebarIsExpanded); const canEditProject = useSelector(selectCanEditSketch); + const isAuthenticated = useSelector(getAuthenticated); const sidebarOptionsRef = useRef(null); - const isAuthenticated = useSelector(getAuthenticated); + /** Close dropdown when clicking outside */ + useEffect(() => { + function handleClickOutside(event) { + if ( + projectOptionsVisible && + sidebarOptionsRef.current && + !sidebarOptionsRef.current.contains(event.target) + ) { + setTimeout(() => dispatch(closeProjectOptions()), 300); + } + } - const onBlurComponent = () => { - setTimeout(() => dispatch(closeProjectOptions()), 200); - }; + if (projectOptionsVisible) { + document.addEventListener('mousedown', handleClickOutside); + } else { + document.removeEventListener('mousedown', handleClickOutside); + } + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [projectOptionsVisible, dispatch]); const toggleProjectOptions = (e) => { e.preventDefault(); if (projectOptionsVisible) { dispatch(closeProjectOptions()); } else { - sidebarOptionsRef.current?.focus(); dispatch(openProjectOptions()); } }; @@ -65,69 +82,61 @@ export default function SideBar() { dispatch(collapseSidebar()); dispatch(closeProjectOptions()); }} - > - {' '} - + /> )}
-
+

{t('Sidebar.Title')}

-
+
-
    -
  • - -
  • -
  • - -
  • - {isAuthenticated && ( + {projectOptionsVisible && ( +
      +
    • + +
    • - )} -
    + {isAuthenticated && ( +
  • + +
  • + )} +
+ )}
From be4bb320f658a7767cbc008ad9a133e406f6fb70 Mon Sep 17 00:00:00 2001 From: raclim Date: Tue, 4 Mar 2025 16:41:20 -0500 Subject: [PATCH 5/5] remove comment, add back in onContextMenu --- client/modules/IDE/components/Sidebar.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/modules/IDE/components/Sidebar.jsx b/client/modules/IDE/components/Sidebar.jsx index 7d52cbbda..24fd487c9 100644 --- a/client/modules/IDE/components/Sidebar.jsx +++ b/client/modules/IDE/components/Sidebar.jsx @@ -34,7 +34,6 @@ export default function SideBar() { const sidebarOptionsRef = useRef(null); - /** Close dropdown when clicking outside */ useEffect(() => { function handleClickOutside(event) { if ( @@ -85,7 +84,10 @@ export default function SideBar() { /> )}
-
+

{t('Sidebar.Title')}