This commit is contained in:
Mark Eibes 2021-01-21 21:09:35 +01:00
parent 491e24e42f
commit cf0f24c5c7
4 changed files with 184 additions and 0 deletions

22
client/src/Main.js Normal file
View File

@ -0,0 +1,22 @@
'use strict';
var ReactDOMServer = require('react-dom/server');
var ReactDOM = require('react-dom');
exports.isServerSide = typeof document === 'undefined';
exports.renderToString = ReactDOMServer.renderToString;
exports.createRoot = function(elem) {
return function() {
return ReactDOM.createRoot(elem);
}
}
exports.renderRoot = function(component) {
return function(root) {
return function() {
root.render(component)
}
}
}

46
client/src/Main.purs Normal file
View File

@ -0,0 +1,46 @@
module Example (main) where
import Prelude
import Container.Component (mkContainer)
import Data.Maybe (fromJust)
import Effect (Effect)
import Effect.Console (log)
import Partial.Unsafe (unsafePartial)
import React.Basic (JSX, element)
import Theme (fromTheme)
import Theme.Default (darkTheme)
import Web.DOM (Element)
import Web.DOM.NonElementParentNode (getElementById) as DOM
import Web.HTML (window) as DOM
import Web.HTML.HTMLDocument (toNonElementParentNode) as DOM
import Web.HTML.Window (document) as DOM
main ∷ Effect Unit
main = do
container <- mkContainer
let
appEl = element container { theme: fromTheme darkTheme, children: [] }
if isServerSide then
void (log (renderToString appEl))
else
void do
window <- DOM.window
document <- DOM.document window
let
node = DOM.toNonElementParentNode document
elem <- DOM.getElementById "app" node
let
element' = unsafePartial (fromJust elem)
root <- createRoot element'
renderRoot appEl root
-- ReactDOM.render appEl element'
foreign import isServerSide ∷ Boolean
foreign import renderToString ∷ JSX -> String
foreign import data ReactRoot ∷ Type
foreign import createRoot ∷ Element -> Effect ReactRoot
foreign import renderRoot ∷ JSX -> ReactRoot -> Effect Unit

View File

@ -0,0 +1,77 @@
module Editor.Component where
import Prelude
import CSS.Safer (cssSafer)
import Data.Nullable (Nullable, notNull)
import Editor (defineThemeImpl, editor, initMonaco, nightOwlTheme, purescriptSyntax, registerLanguageImpl, setMonarchTokensProviderImpl, vsCodeTheme)
import Effect (Effect)
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Effect.Uncurried (mkEffectFn2)
import Foreign (unsafeToForeign)
import React.Basic (ReactComponent, element, fragment)
import React.Basic.Hooks (Ref, component, writeRef)
import React.Basic.Hooks as React
import React.Basic.Hooks.Aff (useAff)
import React.Helpers (wrapperDiv)
import Theme.Styles (makeStyles, useTheme)
import Theme.Types (CSSTheme)
darkThemeName ∷ String
darkThemeName = "NightOwl"
lightThemeName ∷ String
lightThemeName = "VSCode"
initEditor ∷ Aff Unit
initEditor = do
monaco <- initMonaco
defineThemeImpl monaco darkThemeName nightOwlTheme # liftEffect
defineThemeImpl monaco lightThemeName vsCodeTheme # liftEffect
registerLanguageImpl monaco "purescript" # liftEffect
setMonarchTokensProviderImpl monaco "purescript" purescriptSyntax # liftEffect
mkEditor ∷ Effect (ReactComponent { editorRef ∷ Ref (Nullable _) })
mkEditor = do
useStyles <-
makeStyles \(theme ∷ CSSTheme) ->
{ wrapper:
cssSafer
{ margin: "0"
, boxSizing: "border-box"
, padding: "35px 40px"
, width: "100%"
, height: "100%"
, borderRadius: "32px"
, backgroundColor: theme.backgroundColour
}
}
component "Editor" \{ editorRef } -> React.do
classes <- useStyles
useAff unit initEditor
theme <- useTheme
let
themeName = if theme.isLight then lightThemeName else darkThemeName
pure
$ fragment
[ wrapperDiv { className: classes.wrapper }
$ element editor
{ theme: themeName
, options:
unsafeToForeign
{ fontFamily: "PragmataPro"
, fontLigatures: true
, fontSize: "16pt"
, lineNumbers: "off"
, glyphMargin: false
, folding: false
, lineDecorationsWidth: 0
, lineNumbersMinChars: 0
, minimap: { enabled: false }
}
, language: "purescript"
-- https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
, editorDidMount:
mkEffectFn2 \_ -> notNull >>> writeRef editorRef
}
]

View File

@ -0,0 +1,39 @@
module Playground.Handler where
import Prelude
import Data.Maybe (Maybe)
import Effect.Aff.Class (liftAff)
import Effect.Class (class MonadEffect, liftEffect)
import Node.Buffer (Buffer)
import Node.Buffer as Buffer
import Node.Encoding (Encoding(..))
import Node.Express.Handler (HandlerM)
import Node.Express.Request (getBody')
import Node.Express.Response as Response
import Playground.Playground (asErrorWithCode, compileCode, runCode)
import Shared.Json (readAff)
import Shared.Models.Body (RunResult)
import Shared.Models.Body as Body
import Simple.JSON (write)
toBody ∷ ∀ r m. MonadEffect m => { stdout ∷ Buffer, stderr ∷ Buffer | r } -> m RunResult
toBody result = liftEffect $ ado
stdout <- Buffer.toString UTF8 result.stdout
stderr <- Buffer.toString UTF8 result.stderr
let (code ∷ Maybe Int) = asErrorWithCode result >>= _.code
in { code, stdout, stderr } ∷ RunResult
compileHandler ∷ HandlerM Unit
compileHandler = do
body <- getBody'
json <- readAff body # liftAff
result <- compileCode (json ∷ Body.CompileRequest).code # liftAff
Response.send $ write ({ result } ∷ Body.CompileResult)
runHandler ∷ HandlerM Unit
runHandler = do
result <- liftAff do
result <- runCode
toBody result
Response.send $ write (result ∷ Body.RunResult)