git.iko.soy/rowtype-yoga/psfp
on master help sign in
Server called from backend
commit6f9bfc9c98234bfeffdd6c43ec4e00a0a747a631 authorMark Eibes <mark.eibes@gmail.com> dateSat 26 Oct 2019, 00:51 (7 years ago) parentd78b06e
6 files changed+95−25
.gitignore+2 client/.storybook/middleware.js+11 client/spago.dhall+1 client/src/Monaco/Editor.purs+6−21 client/stories/EditorStories.purs+69−2 playground/src/Main.purs+6−2
.gitignore+2
@@ -30,3 +30,5 @@ playground/.psc*
3030playground/.purs*
3131playground/.psa*
3232playground/.spago
33+
34+playground/src/Main.purs
client/.storybook/middleware.jsnew file+11
@@ -0,0 +1,11 @@
1+const express = require('express')
2+const request = require('request');
3+
4+const expressMiddleWare = router => {
5+ router.use('/api', (req, res) => {
6+ var url = "http://localhost:14188" + req.url;
7+ req.pipe(request({ qs:req.query, uri: url, json: true })).pipe(res);
8+ })
9+}
10+
11+module.exports = expressMiddleWare
client/spago.dhall+1
@@ -10,6 +10,7 @@ You can edit this file as you like.
1010 , "debug"
1111 , "effect"
1212 , "matryoshka"
13+ , "milkis"
1314 , "psci-support"
1415 , "pseudo-random"
1516 , "react-basic"
client/src/Monaco/Editor.purs+6−21
@@ -5,19 +5,15 @@ import Prelude
55import CSS.Safer (cssSafer)
66import Control.Promise (Promise)
77import Control.Promise as Promise
8−import Data.Maybe (Maybe(..))
9−import Data.Nullable (notNull, null)
8+import Data.Nullable (Nullable, notNull)
109import Effect (Effect)
1110import Effect.Aff (Aff)
1211import Effect.Class (liftEffect)
13−import Effect.Class.Console (warn)
1412import Effect.Uncurried (EffectFn2, mkEffectFn2)
1513import Foreign (Foreign, unsafeToForeign)
1614import Prim.Row (class Union)
1715import React.Basic (JSX, ReactComponent, element, fragment)
18−import React.Basic.DOM as R
19−import React.Basic.Events (handler_)
20−import React.Basic.Hooks (component, readRefMaybe, useRef, writeRef)
16+import React.Basic.Hooks (Ref, component, writeRef)
2117import React.Basic.Hooks as React
2218import React.Basic.Hooks.Aff (useAff)
2319import React.Helpers (wrapperDiv)
@@ -85,7 +81,7 @@ initEditor = do
8581 registerLanguageImpl monaco "purescript" # liftEffect
8682 setMonarchTokensProviderImpl monaco "purescript" purescriptSyntax # liftEffect
8783
88−mkEditor ∷ Effect (ReactComponent {})
84+mkEditor ∷ Effect (ReactComponent { editorRef ∷ Ref (Nullable _) })
8985mkEditor = do
9086 useStyles <-
9187 makeStyles \(theme ∷ CSSTheme) ->
@@ -100,25 +96,14 @@ mkEditor = do
10096 , backgroundColor: theme.backgroundColour
10197 }
10298 }
103− component "Editor" \{} -> React.do
99+ component "Editor" \{ editorRef } -> React.do
104100 classes <- useStyles
105− ref <- useRef null
106101 useAff unit initEditor
107102 theme <- useTheme
108103 let themeName = if theme.isLight then lightThemeName else darkThemeName
109104 pure
110105 $ fragment
111− [ R.button
112− { onClick:
113− handler_ do
114− maybeEditor <- readRefMaybe ref
115− case maybeEditor of
116− Nothing -> pure unit
117− Just ed -> do
118− v <- getValue ed
119− warn $ "Value: " <> v
120− }
121− , wrapperDiv { className: classes.wrapper }
106+ [ wrapperDiv { className: classes.wrapper }
122107 $ element editor
123108 { theme: themeName
124109 , options:
@@ -136,6 +121,6 @@ mkEditor = do
136121 , language: "purescript"
137122 -- https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
138123 , editorDidMount:
139− mkEffectFn2 \_ -> notNull >>> writeRef ref
124+ mkEffectFn2 \_ -> notNull >>> writeRef editorRef
140125 }
141126 ]
client/stories/EditorStories.purs+69−2
@@ -2,15 +2,82 @@ module EditorStories where
22
33import Prelude hiding (add)
44
5+import Data.Foldable (for_)
6+import Data.Nullable (null)
7+import Data.Tuple.Nested ((/\))
8+import Debug.Trace (spy)
59import Decorator.FullScreen (fullScreenDecorator)
6−import Editor (mkEditor)
10+import Editor (getValue, mkEditor)
711import Effect (Effect)
12+import Effect.Aff (Aff, launchAff_)
13+import Effect.Class (liftEffect)
14+import Milkis as M
15+import Milkis.Impl.Window (windowFetch)
16+import React.Basic (ReactComponent)
17+import React.Basic.DOM as R
18+import React.Basic.Events (handler_)
19+import React.Basic.Hooks (component, element, fragment, readRefMaybe, useRef, useState)
20+import React.Basic.Hooks as React
21+import Shared.Json (readAff)
22+import Shared.Models.Body as Body
23+import Simple.JSON (writeJSON)
824import Storybook.React (Storybook, add, addDecorator, storiesOf)
925
1026stories ∷ Effect Storybook
1127stories = do
1228 storiesOf "Editor" do
1329 addDecorator fullScreenDecorator
14− add "The Editor" mkEditor
30+ add "The Editor" mkCompileEditor
1531 [ {}
1632 ]
33+
34+mkCompileEditor ∷ Effect (ReactComponent {})
35+mkCompileEditor = do
36+ editor <- mkEditor
37+ component "StorybookEditor" \{} -> React.do
38+ editorRef <- useRef null
39+ compileResult /\ modifyCompileResult <- useState ""
40+ let
41+ setCompileResult = modifyCompileResult <<< const
42+ pure
43+ $ fragment
44+ [ R.button
45+ { children: pure $ R.text "Compile"
46+ , onClick:
47+ handler_ do
48+ maybeEditor <- (readRefMaybe editorRef)
49+ for_ maybeEditor \ed -> do
50+ code <- getValue ed
51+ launchAff_ do
52+ res <- compile { code }
53+ res2 <- run
54+ setCompileResult res2.stdout # liftEffect
55+
56+
57+ }
58+ , R.textarea
59+ { value: compileResult
60+ , disabled: true
61+ }
62+ , element editor { editorRef }
63+ ]
64+
65+fetch ∷ M.Fetch
66+fetch = M.fetch windowFetch
67+
68+compile ∷ Body.CompileRequest -> Aff Body.CompileResult
69+compile body = do
70+ fetch (M.URL "/api/compile")
71+ { method: M.postMethod
72+ , body: spy "Body" $ writeJSON body
73+ , headers: M.makeHeaders { "Content-Type": "application/json" }
74+ }
75+ >>= M.json
76+ >>= readAff
77+
78+run ∷ Aff Body.RunResult
79+run = do
80+ fetch (M.URL "/api/run")
81+ { method: M.postMethod }
82+ >>= M.json
83+ >>= readAff
playground/src/Main.purs+6−2
@@ -1,4 +1,8 @@
11module Main where
2+
23import Prelude
3−import Effect.Console (log)
4−main = log "Freddy"
4+import Effect.Console
5+
6+main = log message
7+
8+message = "Du bist " <> show 7 <> " Jahre alt."