Skip to content

Commit ff12017

Browse files
authored
Merge 83b3393 into bc4e3ed
2 parents bc4e3ed + 83b3393 commit ff12017

File tree

7 files changed

+83
-114
lines changed

7 files changed

+83
-114
lines changed

src/commons/assessmentWorkspace/AssessmentWorkspace.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
644644
};
645645

646646
return {
647-
mobileControlBarProps: {
647+
controlBarProps: {
648648
...controlBarProps(questionId)
649649
},
650650
...sideContentProps(props, questionId),
@@ -825,7 +825,7 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
825825
mcqProps: mcqProps,
826826
replProps: replProps,
827827
sideBarProps: sideBarProps,
828-
mobileSideContentProps: mobileSideContentProps(questionId)
828+
sideContentProps: mobileSideContentProps(questionId)
829829
};
830830

831831
return (

src/commons/mobileWorkspace/MobileWorkspace.tsx

Lines changed: 55 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { FocusStyleManager } from '@blueprintjs/core';
22
import { IconNames } from '@blueprintjs/icons';
33
import { Ace } from 'ace-builds';
4-
import React from 'react';
4+
import React, { useCallback, useEffect, useState } from 'react';
55
import { DraggableEvent } from 'react-draggable';
66
import { useMediaQuery } from 'react-responsive';
77

@@ -16,33 +16,33 @@ import DraggableRepl from './DraggableRepl';
1616
import MobileKeyboard from './MobileKeyboard';
1717
import MobileSideContent, { MobileSideContentProps } from './mobileSideContent/MobileSideContent';
1818

19-
export type MobileWorkspaceProps = StateProps;
19+
export type MobileWorkspaceProps = {
20+
sideContentProps: MobileSideContentProps;
2021

21-
type StateProps = {
22+
// The following are shared with WorkspaceProps
2223
editorContainerProps?: EditorContainerProps; // Either editorProps or mcqProps must be provided
2324
hasUnsavedChanges?: boolean; // Not used in Playground
2425
mcqProps?: McqChooserProps; // Not used in Playground
2526
replProps: ReplProps;
2627
sideBarProps: {
2728
tabs: SideBarTab[];
2829
};
29-
mobileSideContentProps: MobileSideContentProps;
3030
};
3131

3232
const MobileWorkspace: React.FC<MobileWorkspaceProps> = props => {
3333
const isAndroid = /Android/.test(navigator.userAgent);
3434
const isPortrait = useMediaQuery({ orientation: 'portrait' });
35-
const [draggableReplPosition, setDraggableReplPosition] = React.useState({ x: 0, y: 0 });
35+
const [draggableReplPosition, setDraggableReplPosition] = useState({ x: 0, y: 0 });
3636

3737
// For disabling draggable Repl when in stepper tab
38-
const [isDraggableReplDisabled, setIsDraggableReplDisabled] = React.useState(false);
38+
const [isDraggableReplDisabled, setIsDraggableReplDisabled] = useState(false);
3939

4040
// Get rid of the focus border on blueprint components
4141
FocusStyleManager.onlyShowFocusOnTabs();
4242

4343
// Handles the panel height when the mobile top controlbar is rendered in the Assessment Workspace
44-
React.useEffect(() => {
45-
if (props.mobileSideContentProps.workspaceLocation === 'assessment') {
44+
useEffect(() => {
45+
if (props.sideContentProps.workspaceLocation === 'assessment') {
4646
document.documentElement.style.setProperty(
4747
'--mobile-panel-height',
4848
'calc(100% - 100px - 1.1rem)'
@@ -61,7 +61,7 @@ const MobileWorkspace: React.FC<MobileWorkspaceProps> = props => {
6161
* soft keyboard on Android devices. This is due to the viewport height changing when the soft
6262
* keyboard is up on Android devices. IOS devices are not affected.
6363
*/
64-
React.useEffect(() => {
64+
useEffect(() => {
6565
if (isPortrait && isAndroid) {
6666
document.documentElement.style.setProperty('overflow', 'auto');
6767
const metaViewport = document.querySelector('meta[name=viewport]');
@@ -85,50 +85,38 @@ const MobileWorkspace: React.FC<MobileWorkspaceProps> = props => {
8585
};
8686
}, [isPortrait, isAndroid]);
8787

88-
const [targetKeyboardInput, setTargetKeyboardInput] = React.useState<Ace.Editor | null>(null);
88+
const [targetKeyboardInput, setTargetKeyboardInput] = useState<Ace.Editor | null>(null);
8989

9090
const clearTargetKeyboardInput = () => setTargetKeyboardInput(null);
9191

9292
const enableMobileKeyboardForEditor = (props: EditorContainerProps): EditorContainerProps => {
93-
const onFocus = (event: any, editor?: Ace.Editor) => {
94-
if (props.onFocus) {
95-
props.onFocus(event, editor);
96-
}
97-
if (!editor) {
98-
return;
99-
}
100-
setTargetKeyboardInput(editor);
101-
};
102-
const onBlur = (event: any, editor?: Ace.Editor) => {
103-
if (props.onBlur) {
104-
props.onBlur(event, editor);
105-
}
106-
clearTargetKeyboardInput();
107-
};
10893
return {
10994
...props,
110-
onFocus,
111-
onBlur
95+
onFocus: (event, editor?) => {
96+
props.onFocus?.(event, editor);
97+
if (!editor) {
98+
return;
99+
}
100+
setTargetKeyboardInput(editor);
101+
},
102+
onBlur: (event, editor?) => {
103+
props.onBlur?.(event, editor);
104+
clearTargetKeyboardInput();
105+
}
112106
};
113107
};
114108

115109
const enableMobileKeyboardForRepl = (props: ReplProps): ReplProps => {
116-
const onFocus = (editor: Ace.Editor) => {
117-
if (props.onFocus) {
118-
props.onFocus(editor);
119-
}
120-
setTargetKeyboardInput(editor);
121-
};
122-
const onBlur = () => {
123-
if (props.onBlur) {
124-
props.onBlur();
125-
}
126-
clearTargetKeyboardInput();
127-
};
128110
return {
129111
...props,
130-
onFocus,
131-
onBlur
112+
onFocus: editor => {
113+
props.onFocus?.(editor);
114+
setTargetKeyboardInput(editor);
115+
},
116+
onBlur: () => {
117+
props.onBlur?.();
118+
clearTargetKeyboardInput();
119+
}
132120
};
133121
};
134122

@@ -186,13 +174,11 @@ const MobileWorkspace: React.FC<MobileWorkspaceProps> = props => {
186174
};
187175

188176
const handleEditorEval = props.editorContainerProps?.handleEditorEval;
189-
const handleTabChangeForRepl = React.useCallback(
177+
const handleTabChangeForRepl = useCallback(
190178
(newTabId: SideContentType, prevTabId: SideContentType) => {
191179
// Evaluate program upon pressing the run tab.
192180
if (newTabId === SideContentType.mobileEditorRun) {
193-
if (handleEditorEval) {
194-
handleEditorEval();
195-
}
181+
handleEditorEval?.();
196182
}
197183

198184
// Show the REPL upon pressing the run tab if the previous tab is not listed below.
@@ -224,8 +210,8 @@ const MobileWorkspace: React.FC<MobileWorkspaceProps> = props => {
224210
[handleEditorEval]
225211
);
226212

227-
const onChange = props.mobileSideContentProps.onChange;
228-
const onSideContentTabChange = React.useCallback(
213+
const onChange = props.sideContentProps.onChange;
214+
const onSideContentTabChange = useCallback(
229215
(
230216
newTabId: SideContentType,
231217
prevTabId: SideContentType,
@@ -240,50 +226,24 @@ const MobileWorkspace: React.FC<MobileWorkspaceProps> = props => {
240226
// Convert sidebar tabs with a side content tab ID into side content tabs.
241227
const sideBarTabs: SideContentTab[] = props.sideBarProps.tabs.filter(tab => tab.id !== undefined);
242228

243-
const mobileEditorTab: SideContentTab = React.useMemo(
244-
() => ({
245-
label: 'Editor',
246-
iconName: IconNames.EDIT,
247-
body: null,
248-
id: SideContentType.mobileEditor
249-
}),
250-
[]
251-
);
252-
253-
const mobileRunTab: SideContentTab = React.useMemo(
254-
() => ({
255-
label: 'Run',
256-
iconName: IconNames.PLAY,
257-
body: null,
258-
id: SideContentType.mobileEditorRun
259-
}),
260-
[]
261-
);
262-
263-
const updatedMobileSideContentProps = React.useCallback(() => {
229+
const updatedMobileSideContentProps = useCallback(() => {
264230
return {
265-
...props.mobileSideContentProps,
231+
...props.sideContentProps,
266232
onChange: onSideContentTabChange,
267233
tabs: {
268234
beforeDynamicTabs: [
269235
...sideBarTabs,
270236
mobileEditorTab,
271-
...props.mobileSideContentProps.tabs.beforeDynamicTabs
237+
...props.sideContentProps.tabs.beforeDynamicTabs
272238
],
273-
afterDynamicTabs: [...props.mobileSideContentProps.tabs.afterDynamicTabs, mobileRunTab]
239+
afterDynamicTabs: [...props.sideContentProps.tabs.afterDynamicTabs, mobileRunTab]
274240
}
275241
};
276-
}, [
277-
onSideContentTabChange,
278-
mobileEditorTab,
279-
mobileRunTab,
280-
props.mobileSideContentProps,
281-
sideBarTabs
282-
]);
242+
}, [onSideContentTabChange, props.sideContentProps, sideBarTabs]);
283243

284244
const inAssessmentWorkspace =
285-
props.mobileSideContentProps.workspaceLocation === 'assessment' ||
286-
props.mobileSideContentProps.workspaceLocation === 'githubAssessment';
245+
props.sideContentProps.workspaceLocation === 'assessment' ||
246+
props.sideContentProps.workspaceLocation === 'githubAssessment';
287247

288248
return (
289249
<div className="workspace mobile-workspace">
@@ -293,9 +253,7 @@ const MobileWorkspace: React.FC<MobileWorkspaceProps> = props => {
293253
/>
294254

295255
{/* Render the top ControlBar when it is the Assessment Workspace */}
296-
{inAssessmentWorkspace && (
297-
<ControlBar {...props.mobileSideContentProps.mobileControlBarProps} />
298-
)}
256+
{inAssessmentWorkspace && <ControlBar {...props.sideContentProps.controlBarProps} />}
299257

300258
<div>
301259
<div className="mobile-editor-panel">{createWorkspaceInput()}</div>
@@ -316,3 +274,17 @@ const MobileWorkspace: React.FC<MobileWorkspaceProps> = props => {
316274
};
317275

318276
export default MobileWorkspace;
277+
278+
const mobileEditorTab: SideContentTab = {
279+
label: 'Editor',
280+
iconName: IconNames.EDIT,
281+
body: null,
282+
id: SideContentType.mobileEditor
283+
};
284+
285+
const mobileRunTab: SideContentTab = {
286+
label: 'Run',
287+
iconName: IconNames.PLAY,
288+
body: null,
289+
id: SideContentType.mobileEditorRun
290+
};

src/commons/mobileWorkspace/mobileSideContent/MobileSideContent.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type StateProps = {
2424
};
2525

2626
type MobileControlBarProps = {
27-
mobileControlBarProps: ControlBarProps;
27+
controlBarProps: ControlBarProps;
2828
};
2929

3030
const renderTab = (tab: SideContentTab, isIOS: boolean, workspaceLocation?: WorkspaceLocation) => {
@@ -60,7 +60,7 @@ const renderTab = (tab: SideContentTab, isIOS: boolean, workspaceLocation?: Work
6060
const MobileSideContent: React.FC<MobileSideContentProps> = ({
6161
selectedTabId,
6262
renderActiveTabPanelOnly,
63-
mobileControlBarProps,
63+
controlBarProps,
6464
...otherProps
6565
}) => {
6666
const isIOS = /iPhone|iPod/.test(navigator.platform);
@@ -118,7 +118,7 @@ const MobileSideContent: React.FC<MobileSideContentProps> = ({
118118
{/* Render the bottom ControlBar 'Cog' button only in the Playground or Sicp Workspace */}
119119
{(otherProps.workspaceLocation === 'playground' ||
120120
otherProps.workspaceLocation === 'sicp') && (
121-
<MobileControlBar {...mobileControlBarProps} />
121+
<MobileControlBar {...controlBarProps} />
122122
)}
123123
</Tabs>
124124
</div>

src/commons/workspace/Workspace.tsx

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { FocusStyleManager } from '@blueprintjs/core';
22
import { Enable, NumberSize, Resizable, ResizableProps, ResizeCallback } from 're-resizable';
33
import { Direction } from 're-resizable/lib/resizer';
4-
import * as React from 'react';
4+
import React, { useEffect, useRef, useState } from 'react';
55

66
import ControlBar, { ControlBarProps } from '../controlBar/ControlBar';
77
import EditorContainer, { EditorContainerProps } from '../editor/EditorContainer';
@@ -12,37 +12,34 @@ import SideBar, { SideBarTab } from '../sideBar/SideBar';
1212
import SideContent, { SideContentProps } from '../sideContent/SideContent';
1313
import { useDimensions } from '../utils/Hooks';
1414

15-
export type WorkspaceProps = DispatchProps & StateProps;
16-
17-
type DispatchProps = {
18-
handleSideContentHeightChange: (height: number) => void;
19-
};
20-
21-
type StateProps = {
15+
export type WorkspaceProps = {
2216
// Either editorProps or mcqProps must be provided
2317
controlBarProps: ControlBarProps;
18+
sideContentHeight?: number;
19+
sideContentProps: SideContentProps;
20+
sideContentIsResizeable?: boolean;
21+
handleSideContentHeightChange: (height: number) => void;
22+
23+
// The following are shared with MobileWorkspaceProps
2424
editorContainerProps?: EditorContainerProps;
2525
hasUnsavedChanges?: boolean;
2626
mcqProps?: McqChooserProps;
2727
replProps: ReplProps;
2828
sideBarProps: {
2929
tabs: SideBarTab[];
3030
};
31-
sideContentHeight?: number;
32-
sideContentProps: SideContentProps;
33-
sideContentIsResizeable?: boolean;
3431
};
3532

3633
const Workspace: React.FC<WorkspaceProps> = props => {
37-
const sideBarResizable = React.useRef<Resizable | null>(null);
38-
const contentContainerDiv = React.useRef<HTMLDivElement | null>(null);
39-
const editorDividerDiv = React.useRef<HTMLDivElement | null>(null);
40-
const leftParentResizable = React.useRef<Resizable | null>(null);
41-
const maxDividerHeight = React.useRef<number | null>(null);
42-
const sideDividerDiv = React.useRef<HTMLDivElement | null>(null);
34+
const sideBarResizable = useRef<Resizable | null>(null);
35+
const contentContainerDiv = useRef<HTMLDivElement>(null);
36+
const editorDividerDiv = useRef<HTMLDivElement>(null);
37+
const leftParentResizable = useRef<Resizable | null>(null);
38+
const maxDividerHeight = useRef<number | null>(null);
39+
const sideDividerDiv = useRef<HTMLDivElement>(null);
4340
const [contentContainerWidth] = useDimensions(contentContainerDiv);
44-
const [expandedSideBarWidth, setExpandedSideBarWidth] = React.useState<number>(200);
45-
const [isSideBarExpanded, setIsSideBarExpanded] = React.useState<boolean>(true);
41+
const [expandedSideBarWidth, setExpandedSideBarWidth] = useState(200);
42+
const [isSideBarExpanded, setIsSideBarExpanded] = useState(true);
4643

4744
const sideBarCollapsedWidth = 40;
4845

@@ -51,7 +48,7 @@ const Workspace: React.FC<WorkspaceProps> = props => {
5148

5249
FocusStyleManager.onlyShowFocusOnTabs();
5350

54-
React.useEffect(() => {
51+
useEffect(() => {
5552
if (props.sideContentIsResizeable && maxDividerHeight.current === null) {
5653
maxDividerHeight.current = sideDividerDiv.current!.clientHeight;
5754
}

src/pages/githubAssessments/GitHubAssessmentWorkspace.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ const GitHubAssessmentWorkspace: React.FC = () => {
10351035
const sideContent = sideContentProps();
10361036

10371037
return {
1038-
mobileControlBarProps: {
1038+
controlBarProps: {
10391039
...controlBarProps()
10401040
},
10411041
...sideContent,
@@ -1134,7 +1134,7 @@ const GitHubAssessmentWorkspace: React.FC = () => {
11341134
sideBarProps: sideBarProps,
11351135
hasUnsavedChanges: hasUnsavedChanges,
11361136
mcqProps: mcqProps,
1137-
mobileSideContentProps: mobileSideContentProps()
1137+
sideContentProps: mobileSideContentProps()
11381138
};
11391139

11401140
if (isLoading) {

src/pages/playground/Playground.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,8 +1035,8 @@ const Playground: React.FC<PlaygroundProps> = props => {
10351035
editorContainerProps: editorContainerProps,
10361036
replProps: replProps,
10371037
sideBarProps: sideBarProps,
1038-
mobileSideContentProps: {
1039-
mobileControlBarProps: {
1038+
sideContentProps: {
1039+
controlBarProps: {
10401040
editorButtons: [
10411041
autorunButtons,
10421042
chapterSelectButton,

src/pages/sourcecast/Sourcecast.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,8 @@ const Sourcecast: React.FC = () => {
387387
editorContainerProps,
388388
replProps,
389389
sideBarProps,
390-
mobileSideContentProps: {
391-
mobileControlBarProps: {
390+
sideContentProps: {
391+
controlBarProps: {
392392
editorButtons: [autorunButtons, chapterSelectButton]
393393
},
394394
selectedTabId: selectedTab,

0 commit comments

Comments
 (0)