From f337e05905d908df0895bd3bc49b5386d5eeae34 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Sun, 18 Jun 2023 16:19:22 +0800 Subject: [PATCH 01/22] Improve useRef type arguments for HTML elements --- src/commons/workspace/Workspace.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commons/workspace/Workspace.tsx b/src/commons/workspace/Workspace.tsx index b15423a4cd..1ee25bf16d 100644 --- a/src/commons/workspace/Workspace.tsx +++ b/src/commons/workspace/Workspace.tsx @@ -34,11 +34,11 @@ type StateProps = { const Workspace: React.FC = props => { const sideBarResizable = React.useRef(null); - const contentContainerDiv = React.useRef(null); - const editorDividerDiv = React.useRef(null); + const contentContainerDiv = React.useRef(null); + const editorDividerDiv = React.useRef(null); const leftParentResizable = React.useRef(null); const maxDividerHeight = React.useRef(null); - const sideDividerDiv = React.useRef(null); + const sideDividerDiv = React.useRef(null); const [contentContainerWidth] = useDimensions(contentContainerDiv); const [expandedSideBarWidth, setExpandedSideBarWidth] = React.useState(200); const [isSideBarExpanded, setIsSideBarExpanded] = React.useState(true); From 17b9bff793797c0e709cc20c1a4122dff3a61b2c Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Sun, 18 Jun 2023 16:22:51 +0800 Subject: [PATCH 02/22] Use named imports for React hooks --- .../mobileWorkspace/MobileWorkspace.tsx | 22 +++++++++---------- src/commons/workspace/Workspace.tsx | 20 ++++++++--------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/commons/mobileWorkspace/MobileWorkspace.tsx b/src/commons/mobileWorkspace/MobileWorkspace.tsx index 42d20b7979..5c8242bb74 100644 --- a/src/commons/mobileWorkspace/MobileWorkspace.tsx +++ b/src/commons/mobileWorkspace/MobileWorkspace.tsx @@ -1,7 +1,7 @@ import { FocusStyleManager } from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; import { Ace } from 'ace-builds'; -import React from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { DraggableEvent } from 'react-draggable'; import { useMediaQuery } from 'react-responsive'; @@ -30,16 +30,16 @@ export type MobileWorkspaceProps = { const MobileWorkspace: React.FC = props => { const isAndroid = /Android/.test(navigator.userAgent); const isPortrait = useMediaQuery({ orientation: 'portrait' }); - const [draggableReplPosition, setDraggableReplPosition] = React.useState({ x: 0, y: 0 }); + const [draggableReplPosition, setDraggableReplPosition] = useState({ x: 0, y: 0 }); // For disabling draggable Repl when in stepper tab - const [isDraggableReplDisabled, setIsDraggableReplDisabled] = React.useState(false); + const [isDraggableReplDisabled, setIsDraggableReplDisabled] = useState(false); // Get rid of the focus border on blueprint components FocusStyleManager.onlyShowFocusOnTabs(); // Handles the panel height when the mobile top controlbar is rendered in the Assessment Workspace - React.useEffect(() => { + useEffect(() => { if (props.mobileSideContentProps.workspaceLocation === 'assessment') { document.documentElement.style.setProperty( '--mobile-panel-height', @@ -59,7 +59,7 @@ const MobileWorkspace: React.FC = props => { * soft keyboard on Android devices. This is due to the viewport height changing when the soft * keyboard is up on Android devices. IOS devices are not affected. */ - React.useEffect(() => { + useEffect(() => { if (isPortrait && isAndroid) { document.documentElement.style.setProperty('overflow', 'auto'); const metaViewport = document.querySelector('meta[name=viewport]'); @@ -83,7 +83,7 @@ const MobileWorkspace: React.FC = props => { }; }, [isPortrait, isAndroid]); - const [targetKeyboardInput, setTargetKeyboardInput] = React.useState(null); + const [targetKeyboardInput, setTargetKeyboardInput] = useState(null); const clearTargetKeyboardInput = () => setTargetKeyboardInput(null); @@ -184,7 +184,7 @@ const MobileWorkspace: React.FC = props => { }; const handleEditorEval = props.editorContainerProps?.handleEditorEval; - const handleTabChangeForRepl = React.useCallback( + const handleTabChangeForRepl = useCallback( (newTabId: SideContentType, prevTabId: SideContentType) => { // Evaluate program upon pressing the run tab. if (newTabId === SideContentType.mobileEditorRun) { @@ -223,7 +223,7 @@ const MobileWorkspace: React.FC = props => { ); const onChange = props.mobileSideContentProps.onChange; - const onSideContentTabChange = React.useCallback( + const onSideContentTabChange = useCallback( ( newTabId: SideContentType, prevTabId: SideContentType, @@ -238,7 +238,7 @@ const MobileWorkspace: React.FC = props => { // Convert sidebar tabs with a side content tab ID into side content tabs. const sideBarTabs: SideContentTab[] = props.sideBarProps.tabs.filter(tab => tab.id !== undefined); - const mobileEditorTab: SideContentTab = React.useMemo( + const mobileEditorTab: SideContentTab = useMemo( () => ({ label: 'Editor', iconName: IconNames.EDIT, @@ -248,7 +248,7 @@ const MobileWorkspace: React.FC = props => { [] ); - const mobileRunTab: SideContentTab = React.useMemo( + const mobileRunTab: SideContentTab = useMemo( () => ({ label: 'Run', iconName: IconNames.PLAY, @@ -258,7 +258,7 @@ const MobileWorkspace: React.FC = props => { [] ); - const updatedMobileSideContentProps = React.useCallback(() => { + const updatedMobileSideContentProps = useCallback(() => { return { ...props.mobileSideContentProps, onChange: onSideContentTabChange, diff --git a/src/commons/workspace/Workspace.tsx b/src/commons/workspace/Workspace.tsx index 1ee25bf16d..c169707656 100644 --- a/src/commons/workspace/Workspace.tsx +++ b/src/commons/workspace/Workspace.tsx @@ -1,7 +1,7 @@ import { FocusStyleManager } from '@blueprintjs/core'; import { Enable, NumberSize, Resizable, ResizableProps, ResizeCallback } from 're-resizable'; import { Direction } from 're-resizable/lib/resizer'; -import React from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import ControlBar, { ControlBarProps } from '../controlBar/ControlBar'; import EditorContainer, { EditorContainerProps } from '../editor/EditorContainer'; @@ -33,15 +33,15 @@ type StateProps = { }; const Workspace: React.FC = props => { - const sideBarResizable = React.useRef(null); - const contentContainerDiv = React.useRef(null); - const editorDividerDiv = React.useRef(null); - const leftParentResizable = React.useRef(null); - const maxDividerHeight = React.useRef(null); - const sideDividerDiv = React.useRef(null); + const sideBarResizable = useRef(null); + const contentContainerDiv = useRef(null); + const editorDividerDiv = useRef(null); + const leftParentResizable = useRef(null); + const maxDividerHeight = useRef(null); + const sideDividerDiv = useRef(null); const [contentContainerWidth] = useDimensions(contentContainerDiv); - const [expandedSideBarWidth, setExpandedSideBarWidth] = React.useState(200); - const [isSideBarExpanded, setIsSideBarExpanded] = React.useState(true); + const [expandedSideBarWidth, setExpandedSideBarWidth] = useState(200); + const [isSideBarExpanded, setIsSideBarExpanded] = useState(true); const sideBarCollapsedWidth = 40; @@ -50,7 +50,7 @@ const Workspace: React.FC = props => { FocusStyleManager.onlyShowFocusOnTabs(); - React.useEffect(() => { + useEffect(() => { if (props.sideContentIsResizeable && maxDividerHeight.current === null) { maxDividerHeight.current = sideDividerDiv.current!.clientHeight; } From 8324d10547f06a13de9e8de7469713eca2e65120 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Sun, 18 Jun 2023 16:32:06 +0800 Subject: [PATCH 03/22] Refactor MobileWorkspace * Replace if statements with optional invocation * Move constant `SideContentTab`s out of FC body --- .../mobileWorkspace/MobileWorkspace.tsx | 98 +++++++------------ 1 file changed, 36 insertions(+), 62 deletions(-) diff --git a/src/commons/mobileWorkspace/MobileWorkspace.tsx b/src/commons/mobileWorkspace/MobileWorkspace.tsx index 5c8242bb74..1416e41f81 100644 --- a/src/commons/mobileWorkspace/MobileWorkspace.tsx +++ b/src/commons/mobileWorkspace/MobileWorkspace.tsx @@ -1,7 +1,7 @@ import { FocusStyleManager } from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; import { Ace } from 'ace-builds'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { DraggableEvent } from 'react-draggable'; import { useMediaQuery } from 'react-responsive'; @@ -88,45 +88,33 @@ const MobileWorkspace: React.FC = props => { const clearTargetKeyboardInput = () => setTargetKeyboardInput(null); const enableMobileKeyboardForEditor = (props: EditorContainerProps): EditorContainerProps => { - const onFocus = (event: any, editor?: Ace.Editor) => { - if (props.onFocus) { - props.onFocus(event, editor); - } - if (!editor) { - return; - } - setTargetKeyboardInput(editor); - }; - const onBlur = (event: any, editor?: Ace.Editor) => { - if (props.onBlur) { - props.onBlur(event, editor); - } - clearTargetKeyboardInput(); - }; return { ...props, - onFocus, - onBlur + onFocus: (event, editor?) => { + props.onFocus?.(event, editor); + if (!editor) { + return; + } + setTargetKeyboardInput(editor); + }, + onBlur: (event, editor?) => { + props.onBlur?.(event, editor); + clearTargetKeyboardInput(); + } }; }; const enableMobileKeyboardForRepl = (props: ReplProps): ReplProps => { - const onFocus = (editor: Ace.Editor) => { - if (props.onFocus) { - props.onFocus(editor); - } - setTargetKeyboardInput(editor); - }; - const onBlur = () => { - if (props.onBlur) { - props.onBlur(); - } - clearTargetKeyboardInput(); - }; return { ...props, - onFocus, - onBlur + onFocus: editor => { + props.onFocus?.(editor); + setTargetKeyboardInput(editor); + }, + onBlur: () => { + props.onBlur?.(); + clearTargetKeyboardInput(); + } }; }; @@ -188,9 +176,7 @@ const MobileWorkspace: React.FC = props => { (newTabId: SideContentType, prevTabId: SideContentType) => { // Evaluate program upon pressing the run tab. if (newTabId === SideContentType.mobileEditorRun) { - if (handleEditorEval) { - handleEditorEval(); - } + handleEditorEval?.(); } // Show the REPL upon pressing the run tab if the previous tab is not listed below. @@ -238,26 +224,6 @@ const MobileWorkspace: React.FC = props => { // Convert sidebar tabs with a side content tab ID into side content tabs. const sideBarTabs: SideContentTab[] = props.sideBarProps.tabs.filter(tab => tab.id !== undefined); - const mobileEditorTab: SideContentTab = useMemo( - () => ({ - label: 'Editor', - iconName: IconNames.EDIT, - body: null, - id: SideContentType.mobileEditor - }), - [] - ); - - const mobileRunTab: SideContentTab = useMemo( - () => ({ - label: 'Run', - iconName: IconNames.PLAY, - body: null, - id: SideContentType.mobileEditorRun - }), - [] - ); - const updatedMobileSideContentProps = useCallback(() => { return { ...props.mobileSideContentProps, @@ -274,13 +240,7 @@ const MobileWorkspace: React.FC = props => { ] } }; - }, [ - onSideContentTabChange, - mobileEditorTab, - mobileRunTab, - props.mobileSideContentProps, - sideBarTabs - ]); + }, [onSideContentTabChange, props.mobileSideContentProps, sideBarTabs]); const inAssessmentWorkspace = props.mobileSideContentProps.workspaceLocation === 'assessment'; @@ -315,3 +275,17 @@ const MobileWorkspace: React.FC = props => { }; export default MobileWorkspace; + +const mobileEditorTab: SideContentTab = { + label: 'Editor', + iconName: IconNames.EDIT, + body: null, + id: SideContentType.mobileEditor +}; + +const mobileRunTab: SideContentTab = { + label: 'Run', + iconName: IconNames.PLAY, + body: null, + id: SideContentType.mobileEditorRun +}; From 4059f273512d26b909883a6fa02293b91ea935ac Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:26:18 +0800 Subject: [PATCH 04/22] Simplify classnames call --- src/pages/playground/Playground.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/playground/Playground.tsx b/src/pages/playground/Playground.tsx index 68439dbd32..6429e96fcb 100644 --- a/src/pages/playground/Playground.tsx +++ b/src/pages/playground/Playground.tsx @@ -1043,12 +1043,12 @@ const Playground: React.FC = props => { }; return isMobileBreakpoint ? ( -
+
) : ( From 1581227449cc87a23a2f050042b1ad9ac901ece0 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:38:22 +0800 Subject: [PATCH 05/22] Remove unnecessary braces around string attributes Only done for non-UI (non-message/label) strings as these UI strings will be pulled out for internationalization in the future. --- .../EditingWorkspaceSideContentTextAreaContent.tsx | 2 +- src/commons/navigationBar/NavigationBar.tsx | 2 +- .../sideContent/content/SideContentFaceapiDisplay.tsx | 4 ++-- src/commons/sourceRecorder/SourceRecorderTable.tsx | 2 +- src/features/cseMachine/CseMachineLayout.tsx | 2 +- src/features/cseMachine/components/ControlItemComponent.tsx | 2 +- src/features/cseMachine/components/StashItemComponent.tsx | 2 +- src/features/cseMachine/components/values/FnValue.tsx | 4 ++-- src/features/cseMachine/components/values/GlobalFnValue.tsx | 4 ++-- src/features/dataVisualizer/drawable/ArrayDrawable.tsx | 6 +++--- .../adminPanel/subcomponents/AddStoriesUserPanel.tsx | 2 +- src/pages/academy/adminPanel/subcomponents/AddUserPanel.tsx | 2 +- .../adminPanel/subcomponents/NotificationConfigPanel.tsx | 2 +- .../assessmentConfigPanel/AssessmentConfigPanel.tsx | 2 +- .../subcomponents/userConfigPanel/UserConfigPanel.tsx | 2 +- src/pages/academy/dashboard/Dashboard.tsx | 2 +- .../chapterSimulator/ChapterSimulatorTextLoader.tsx | 2 +- src/pages/academy/groundControl/GroundControl.tsx | 2 +- src/pages/academy/notiPreference/NotiPreference.tsx | 2 +- 19 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/commons/editingWorkspaceSideContent/EditingWorkspaceSideContentTextAreaContent.tsx b/src/commons/editingWorkspaceSideContent/EditingWorkspaceSideContentTextAreaContent.tsx index e737cbeb93..fae6f33720 100644 --- a/src/commons/editingWorkspaceSideContent/EditingWorkspaceSideContentTextAreaContent.tsx +++ b/src/commons/editingWorkspaceSideContent/EditingWorkspaceSideContentTextAreaContent.tsx @@ -57,7 +57,7 @@ export const TextAreaContent: React.FC = props => { const makeEditingTextarea = () => (