@@ -1038,20 +1038,6 @@ module Settings = {
1038
1038
}
1039
1039
1040
1040
module ControlPanel = {
1041
- let codeFromResult = (result : FinalResult .t ): string => {
1042
- open Api
1043
- switch result {
1044
- | FinalResult .Comp (comp ) =>
1045
- switch comp {
1046
- | CompilationResult .Success ({js_code }) => js_code
1047
- | UnexpectedError (_ )
1048
- | Unknown (_ , _ )
1049
- | Fail (_ ) => "/* No JS code generated */"
1050
- }
1051
- | Nothing
1052
- | Conv (_ ) => "/* No JS code generated */"
1053
- }
1054
- }
1055
1041
module Button = {
1056
1042
@react.component
1057
1043
let make = (~children , ~onClick = ?) =>
@@ -1130,23 +1116,73 @@ module ControlPanel = {
1130
1116
~state : CompilerManagerHook .state ,
1131
1117
~dispatch : CompilerManagerHook .action => unit ,
1132
1118
~editorCode : React .ref <string >,
1133
- ~runOutput ,
1134
- ~toggleRunOutput ,
1119
+ ~setCurrentTab : (tab => tab ) => unit ,
1135
1120
) => {
1136
1121
let children = switch state {
1137
1122
| Init => React .string ("Initializing..." )
1138
1123
| SwitchingCompiler (_ready , _version ) => React .string ("Switching Compiler..." )
1139
- | Compiling (_ , _ )
1124
+ | Compiling (_ )
1125
+ | Executing (_ )
1140
1126
| Ready (_ ) =>
1141
1127
let onFormatClick = evt => {
1142
1128
ReactEvent .Mouse .preventDefault (evt )
1143
1129
dispatch (Format (editorCode .current ))
1144
1130
}
1145
1131
1132
+ let autoRun = switch state {
1133
+ | CompilerManagerHook .Executing ({state : {autoRun : true }})
1134
+ | Compiling ({state : {autoRun : true }})
1135
+ | Ready ({autoRun : true }) => true
1136
+ | _ => false
1137
+ }
1138
+
1139
+ let runCode = () => {
1140
+ setCurrentTab (_ => Output )
1141
+ dispatch (RunCode )
1142
+ }
1143
+
1144
+ let onKeyDown = event => {
1145
+ switch (
1146
+ event -> ReactEvent .Keyboard .metaKey || event -> ReactEvent .Keyboard .ctrlKey ,
1147
+ event -> ReactEvent .Keyboard .key ,
1148
+ ) {
1149
+ | (true , "e" ) =>
1150
+ event -> ReactEvent .Keyboard .preventDefault
1151
+ runCode ()
1152
+ | _ => ()
1153
+ }
1154
+ }
1155
+
1156
+ React .useEffect (() => {
1157
+ Webapi .Window .addEventListener ("keydown" , onKeyDown )
1158
+ Some (() => Webapi .Window .removeEventListener ("keydown" , onKeyDown ))
1159
+ }, [])
1160
+
1161
+ let runButtonText = {
1162
+ let userAgent = Webapi .Window .Navigator .userAgent
1163
+ let run = "Run"
1164
+ if userAgent -> String .includes ("iPhone" ) || userAgent -> String .includes ("Android" ) {
1165
+ run
1166
+ } else if userAgent -> String .includes ("Mac" ) {
1167
+ ` ${run} (⌘ + E)`
1168
+ } else {
1169
+ ` ${run} (Ctrl + E)`
1170
+ }
1171
+ }
1172
+
1146
1173
<div className = "flex flex-row gap-x-2" >
1147
- <ToggleButton checked = runOutput onChange = {_ => toggleRunOutput ()}>
1174
+ <ToggleButton
1175
+ checked = autoRun
1176
+ onChange = {_ => {
1177
+ switch state {
1178
+ | Ready ({autoRun : false }) => setCurrentTab (_ => Output )
1179
+ | _ => ()
1180
+ }
1181
+ dispatch (ToggleAutoRun )
1182
+ }}>
1148
1183
{React .string ("Auto-run" )}
1149
1184
</ToggleButton >
1185
+ <Button onClick = {_ => runCode ()}> {React .string (runButtonText )} </Button >
1150
1186
<Button onClick = onFormatClick > {React .string ("Format" )} </Button >
1151
1187
<ShareButton actionIndicatorKey />
1152
1188
</div >
@@ -1176,78 +1212,27 @@ module OutputPanel = {
1176
1212
~compilerState : CompilerManagerHook .state ,
1177
1213
~editorCode : React .ref <string >,
1178
1214
~currentTab : tab ,
1179
- ~runOutput ,
1180
1215
) => {
1181
- /*
1182
- We need the prevState to understand different
1183
- state transitions, and to be able to keep displaying
1184
- old results until those transitions are done.
1185
-
1186
- Goal was to reduce the UI flickering during different
1187
- state transitions
1188
- */
1189
- let prevState = React .useRef (None )
1190
-
1191
- let cmCode = switch prevState .current {
1192
- | Some (prev ) =>
1193
- switch (prev , compilerState ) {
1194
- | (_ , Ready ({result : Nothing })) => None
1195
- | (Ready (prevReady ), Ready (ready )) =>
1196
- switch (prevReady .result , ready .result ) {
1197
- | (_ , Comp (Success (_ ))) => ControlPanel .codeFromResult (ready .result )-> Some
1198
- | _ => None
1199
- }
1200
- | (_ , Ready ({result : Comp (Success (_ )) as result })) =>
1201
- ControlPanel .codeFromResult (result )-> Some
1202
- | (Ready ({result : Comp (Success (_ )) as result }), Compiling (_ , _ )) =>
1203
- ControlPanel .codeFromResult (result )-> Some
1204
- | _ => None
1205
- }
1206
- | None =>
1207
- switch compilerState {
1208
- | Ready (ready ) => ControlPanel .codeFromResult (ready .result )-> Some
1209
- | _ => None
1210
- }
1211
- }
1212
-
1213
- prevState .current = Some (compilerState )
1214
-
1215
- let resultPane = switch compilerState {
1216
- | Compiling (ready , _ )
1217
- | Ready (ready ) =>
1218
- switch ready .result {
1219
- | Comp (Success (_ ))
1220
- | Conv (Success (_ )) => React .null
1221
- | _ =>
1222
- <ResultPane
1223
- targetLang = ready .targetLang
1224
- compilerVersion = ready .selected .compilerVersion
1225
- result = ready .result
1226
- />
1227
- }
1228
-
1229
- | _ => React .null
1230
- }
1231
-
1232
- let (code , showCm ) = switch cmCode {
1233
- | None => ("" , false )
1234
- | Some (code ) => (code , true )
1235
- }
1236
-
1237
- let codeElement =
1238
- <pre className = {"whitespace-pre-wrap p-4 " ++ (showCm ? "block" : "hidden" )}>
1239
- {HighlightJs .renderHLJS (~code , ~darkmode = true , ~lang = "js" , ())}
1240
- </pre >
1241
-
1242
1216
let output =
1243
1217
<div className = "text-gray-20" >
1244
- resultPane
1245
- codeElement
1218
+ {switch compilerState {
1219
+ | Compiling ({previousJsCode : Some (jsCode )})
1220
+ | Executing ({jsCode })
1221
+ | Ready ({result : Comp (Success ({jsCode }))}) =>
1222
+ <pre className = {"whitespace-pre-wrap p-4 " }>
1223
+ {HighlightJs .renderHLJS (~code = jsCode , ~darkmode = true , ~lang = "js" , ())}
1224
+ </pre >
1225
+ | Ready ({result : Conv (Success (_ ))}) => React .null
1226
+ | Ready ({result , targetLang , selected }) =>
1227
+ <ResultPane targetLang compilerVersion = selected .compilerVersion result />
1228
+ | _ => React .null
1229
+ }}
1246
1230
</div >
1247
1231
1248
1232
let errorPane = switch compilerState {
1249
- | Compiling (ready , _ )
1233
+ | Compiling ({ state : ready } )
1250
1234
| Ready (ready )
1235
+ | Executing ({state : ready })
1251
1236
| SwitchingCompiler (ready , _ ) =>
1252
1237
<ResultPane
1253
1238
targetLang = ready .targetLang
@@ -1260,7 +1245,8 @@ module OutputPanel = {
1260
1245
1261
1246
let settingsPane = switch compilerState {
1262
1247
| Ready (ready )
1263
- | Compiling (ready , _ )
1248
+ | Compiling ({state : ready })
1249
+ | Executing ({state : ready })
1264
1250
| SwitchingCompiler (ready , _ ) =>
1265
1251
let config = ready .selected .config
1266
1252
let setConfig = config => compilerDispatch (UpdateConfig (config ))
@@ -1273,7 +1259,9 @@ module OutputPanel = {
1273
1259
let prevSelected = React .useRef (0 )
1274
1260
1275
1261
let selected = switch compilerState {
1276
- | Compiling (_ , _ ) => prevSelected .current
1262
+ | Executing (_ )
1263
+ | Compiling (_ ) =>
1264
+ prevSelected .current
1277
1265
| Ready (ready ) =>
1278
1266
switch ready .result {
1279
1267
| Comp (Success (_ ))
@@ -1285,10 +1273,10 @@ module OutputPanel = {
1285
1273
1286
1274
prevSelected .current = selected
1287
1275
1288
- let ( logs , setLogs ) = React . useState ( _ => [] )
1276
+ let appendLog = ( level , content ) => compilerDispatch ( AppendLog ({ level , content }) )
1289
1277
1290
1278
let tabs = [
1291
- (Output , <OutputPanel runOutput compilerState logs setLogs />),
1279
+ (Output , <OutputPanel compilerState appendLog />),
1292
1280
(JavaScript , output ),
1293
1281
(Problems , errorPane ),
1294
1282
(Settings , settingsPane ),
@@ -1483,7 +1471,7 @@ let make = (~versions: array<string>) => {
1483
1471
}
1484
1472
1485
1473
None
1486
- }, [ compilerState ] )
1474
+ }, ( compilerState , compilerDispatch ) )
1487
1475
1488
1476
let (layout , setLayout ) = React .useState (_ =>
1489
1477
Webapi .Window .innerWidth < breakingPoint ? Column : Row
@@ -1632,8 +1620,8 @@ let make = (~versions: array<string>) => {
1632
1620
}
1633
1621
1634
1622
let cmHoverHints = switch compilerState {
1635
- | Ready ({result : FinalResult .Comp (Success ({type_hints }))}) =>
1636
- Array .map (type_hints , hint => {
1623
+ | Ready ({result : FinalResult .Comp (Success ({typeHints }))}) =>
1624
+ Array .map (typeHints , hint => {
1637
1625
switch hint {
1638
1626
| TypeDeclaration ({start , end , hint })
1639
1627
| Binding ({start , end , hint })
@@ -1693,17 +1681,13 @@ let make = (~versions: array<string>) => {
1693
1681
</button >
1694
1682
})
1695
1683
1696
- let (runOutput , setRunOutput ) = React .useState (() => false )
1697
- let toggleRunOutput = () => setRunOutput (prev => ! prev )
1698
-
1699
1684
<main className = {"flex flex-col bg-gray-100 overflow-hidden" }>
1700
1685
<ControlPanel
1701
1686
actionIndicatorKey = {Int .toString (actionCount )}
1702
1687
state = compilerState
1703
1688
dispatch = compilerDispatch
1704
1689
editorCode
1705
- runOutput
1706
- toggleRunOutput
1690
+ setCurrentTab
1707
1691
/>
1708
1692
<div
1709
1693
className = {` flex ${layout == Column ? "flex-col" : "flex-row" }` }
@@ -1758,7 +1742,7 @@ let make = (~versions: array<string>) => {
1758
1742
{React .array (headers )}
1759
1743
</div >
1760
1744
<div ref = {ReactDOM .Ref .domRef (subPanelRef )} className = "overflow-auto" >
1761
- <OutputPanel currentTab compilerDispatch compilerState editorCode runOutput />
1745
+ <OutputPanel currentTab compilerDispatch compilerState editorCode />
1762
1746
</div >
1763
1747
</div >
1764
1748
</div >
0 commit comments