11import  {  FocusStyleManager  }  from  '@blueprintjs/core' ; 
22import  {  IconNames  }  from  '@blueprintjs/icons' ; 
33import  {  Ace  }  from  'ace-builds' ; 
4- import  React  from  'react' ; 
4+ import  React ,   {   useCallback ,   useEffect ,   useState   }  from  'react' ; 
55import  {  DraggableEvent  }  from  'react-draggable' ; 
66import  {  useMediaQuery  }  from  'react-responsive' ; 
77
@@ -16,33 +16,33 @@ import DraggableRepl from './DraggableRepl';
1616import  MobileKeyboard  from  './MobileKeyboard' ; 
1717import  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
3232const  MobileWorkspace : React . FC < MobileWorkspaceProps >  =  props  =>  { 
3333  const  isAndroid  =  / A n d r o i d / . 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
318276export  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+ } ; 
0 commit comments