@@ -1,17 +1,20 @@
11module PSLayout where
22
33import Prelude
4+
5+import Data.Array (foldMap)
46import Data.Array as A
57import Data.Array as Array
68import Data.Array.NonEmpty as NEA
7−import Data.Function.Uncurried (mkFn2)
9+import Data.Either (Either(..))
810import Data.Maybe (Maybe(..), fromMaybe, isJust)
9−import Data.Nullable (Nullable, toMaybe)
11+import Data.Nullable (Nullable)
1012import Data.Nullable as Nullable
1113import Data.String as String
1214import Data.Tuple.Nested ((/\))
13−import Debug.Trace (spy)
1415import Effect (Effect)
16+import Effect.Aff (launchAff_)
17+import Effect.Class (liftEffect)
1518import JSS (jss, jssClasses)
1619import Justifill (justifill)
1720import Milkis.Impl (FetchImpl)
@@ -23,14 +26,16 @@ import React.Basic.Hooks (ReactChildren, component, componentWithChildren, eleme
2326import React.Basic.Hooks as React
2427import Unsafe.Coerce (unsafeCoerce)
2528import Yoga.Box.Component as Box
29+import Yoga.ClickAway.Component as ClickAway
2630import Yoga.CompileEditor.Component (mkCompileEditor)
2731import Yoga.Compiler.Api (apiCompiler)
2832import Yoga.Compiler.Types (Compiler)
2933import Yoga.FillInTheGaps.Component as FillInTheGaps
30−import Yoga.FillInTheGaps.Logic (complete, parseSegments)
34+import Yoga.FillInTheGaps.Logic (findResult, parseSegments, toCode)
3135import Yoga.Header.Component (mkHeader)
3236import Yoga.Helpers ((?||))
3337import Yoga.InlineCode.Component as InlineCode
38+import Yoga.Modal.Component as Modal
3439import Yoga.Theme (fromTheme)
3540import Yoga.Theme.CSSBaseline (mkCssBaseline)
3641import Yoga.Theme.Default (darkTheme)
@@ -97,6 +102,13 @@ mkSecret = do
97102 , children: kids
98103 }
99104
105+isQuiz ∷ JSX -> Boolean
106+isQuiz a =
107+ (unsafeCoerce a).props.mdxType == "pre"
108+ && ((unsafeCoerce a).props.children.props.className == "language-purescript")
109+ && ((unsafeCoerce a).props.children.props.mdxType == "code")
110+ && ((unsafeCoerce a).props.children.props.children # parseSegments # isJust)
111+
100112mkMdxProviderComponent ∷
101113 ∀ r.
102114 { | Compiler r } ->
@@ -114,6 +126,8 @@ mkMdxProviderComponent compiler = do
114126 sidebar <- mkSidebar
115127 header <- mkHeader
116128 yogaInlineCode <- InlineCode.makeComponent
129+ modal <- Modal.makeComponent
130+ clickAway <- ClickAway.makeComponent
117131 h <- mkH
118132 p <- mkP
119133 secret <- mkSecret
@@ -136,6 +150,8 @@ mkMdxProviderComponent compiler = do
136150 componentWithChildren "MDXProviderComponent" \{ children, siteInfo } -> React.do
137151 classes <- useStyles {}
138152 visibleThrough /\ updateVisible <- useState 1
153+ questions /\ updateQuestions <- useState []
154+ maybeModal /\ updateModal <- useState Nothing
139155 let
140156 baseline child = element cssBaseline { kids: child }
141157
@@ -146,10 +162,7 @@ mkMdxProviderComponent compiler = do
146162 if i >= visibleThrough then
147163 { i, acc }
148164 else
149− if (unsafeCoerce a).props.mdxType == "pre"
150− && ((unsafeCoerce a).props.children.props.className == "language-purescript")
151− && ((unsafeCoerce a).props.children.props.mdxType == "code")
152− && ((unsafeCoerce a).props.children.props.children # parseSegments # isJust) then
165+ if isQuiz a then
153166 { i: i + 1, acc: A.snoc acc a }
154167 else
155168 { i, acc: A.snoc acc a }
@@ -218,11 +231,14 @@ mkMdxProviderComponent compiler = do
218231 jsx box {}
219232 [ element fillInTheGaps
220233 { initialSegments
221− , update:
222− \segs ->
223− when (complete segs)
224− $ updateVisible
225− (_ + 1)
234+ , incantate: \segments -> launchAff_ do
235+ let code = toCode segments
236+ result <- compiler.compileAndRun { code }
237+ liftEffect case result of
238+ Right r | String.stripSuffix (String.Pattern "\n") r.stdout == (findResult $ join segments) ->
239+ updateVisible (_ + 1)
240+ _ ->
241+ updateModal (const $ Just { title: "Failed", kids: [R.text "Try again"] })
226242 }
227243 ]
228244 true, _, _ ->
@@ -241,6 +257,13 @@ mkMdxProviderComponent compiler = do
241257 ]
242258 , components: mdxComponents
243259 }
260+ , maybeModal # foldMap
261+ (\modalProps ->
262+ fragment [
263+ element clickAway { allowEscape: Just true, onClick: updateModal (const Nothing), style: Nothing },
264+ element modal (justifill modalProps)
265+ ]
266+ )
244267 ]
245268
246269mkSidebar = do