5import Data.Array (foldMap)
7import Data.Array as Array
8import Data.Array.NonEmpty as NEA
9import Data.Either (Either(..))
10import Data.Maybe (Maybe(..), fromMaybe, isJust)
11import Data.Nullable (Nullable)
12import Data.Nullable as Nullable
13import Data.String as String
14import Data.Tuple.Nested ((/\))
16import Effect.Aff (launchAff_)
17import Effect.Class (liftEffect)
18import JSS (jss, jssClasses)
19import Justifill (justifill)
20import Milkis.Impl (FetchImpl)
21import React.Basic (JSX, ReactComponent, fragment)
22import React.Basic.DOM (unsafeCreateDOMComponent)
23import React.Basic.DOM as R
24import React.Basic.Helpers (jsx)
25import React.Basic.Hooks (ReactChildren, component, componentWithChildren, element, reactChildrenToArray, useEffect, useState)
26import React.Basic.Hooks as React
27import Unsafe.Coerce (unsafeCoerce)
28import Yoga.Box.Component as Box
29import Yoga.ClickAway.Component as ClickAway
30import Yoga.CompileEditor.Component (mkCompileEditor)
31import Yoga.Compiler.Api (apiCompiler)
32import Yoga.Compiler.Types (Compiler)
33import Yoga.FillInTheGaps.Component as FillInTheGaps
34import Yoga.FillInTheGaps.Logic (findResult, parseSegments, toCode)
35import Yoga.Header.Component (mkHeader)
36import Yoga.Helpers ((?||))
37import Yoga.InlineCode.Component as InlineCode
38import Yoga.Modal.Component as Modal
39import Yoga.Theme (fromTheme)
40import Yoga.Theme.CSSBaseline (mkCssBaseline)
41import Yoga.Theme.Default (darkTheme)
42import Yoga.Theme.Provider (mkThemeProvider)
43import Yoga.Theme.Styles (makeStylesJSS)
44import Yoga.Theme.Types (CSSTheme)
45import Yoga.Typography.Header (HeadingLevel(..), mkH)
46import Yoga.Typography.Paragraph (mkP)
47import Yoga.WithSidebar.Component (makeComponent) as WithSidebar
53 , menuLinks ∷ Array { name ∷ String, link ∷ String }
63 { mdxType ∷ Nullable String
64 , children ∷ Nullable String
65 , className ∷ Nullable String
74 { children ∷ ReactChildren JSX
75 , siteInfo ∷ SiteQueryResult
78mkLayout fetchImpl = do
79 themeProvider <- mkThemeProvider
80 mdxProviderComponent <- mkMdxProviderComponent (apiCompiler fetchImpl)
81 componentWithChildren "MDXLayout" \{ children, siteInfo } -> React.do
83 $ element themeProvider
84 { theme: fromTheme darkTheme
86 [ element mdxProviderComponent
93mkSecret ∷ Effect (ReactComponent { kids ∷ Array JSX, visible ∷ Boolean, register ∷ Effect Unit })
95 component "Secret" \{ kids, visible, register } -> React.do
97 unless visible register
101 { style: R.css { visibility: if visible then "visible" else "hidden" }
105isQuiz ∷ JSX -> Boolean
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)
112mkMdxProviderComponent ∷
117 { children ∷ ReactChildren JSX
118 , siteInfo ∷ SiteQueryResult
121mkMdxProviderComponent compiler = do
122 cssBaseline <- mkCssBaseline
123 editor <- mkCompileEditor compiler
124 fillInTheGaps <- FillInTheGaps.makeComponent
125 box <- Box.makeComponent
128 yogaInlineCode <- InlineCode.makeComponent
129 modal <- Modal.makeComponent
130 clickAway <- ClickAway.makeComponent
136 $ jssClasses \(theme ∷ CSSTheme) ->
138 { fontFamily: theme.codeFontFamily # NEA.head
139 , backgroundColor: theme.interfaceColour
141 , border: "1px solid #383c39"
143 , borderRadius: "3px"
147 , flexDirection: "row"
150 componentWithChildren "MDXProviderComponent" \{ children, siteInfo } -> React.do
151 classes <- useStyles {}
152 visibleThrough /\ updateVisible <- useState 1
153 questions /\ updateQuestions <- useState []
154 maybeModal /\ updateModal <- useState Nothing
156 baseline child = element cssBaseline { kids: child }
158 kids = reactChildrenToArray children
160 foldVisible ∷ { i ∷ Int, acc ∷ Array JSX } -> JSX -> { i ∷ Int, acc ∷ Array JSX }
161 foldVisible { i, acc } a =
162 if i >= visibleThrough then
166 { i: i + 1, acc: A.snoc acc a }
168 { i, acc: A.snoc acc a }
170 visibleKids = kids # A.foldl foldVisible { i: 0, acc: [] ∷ Array JSX } # _.acc
175 [ jsx header { className: "" } [ R.text siteInfo.site.siteMetadata.title ]
176 , element sidebar { links: siteInfo.site.siteMetadata.menuLinks }
177 , jsx box {} visibleKids
184 element h ({ level: H2, text: props.children, className: Nothing })
187 element h { level: H3, text: props.children, className: Nothing }
190 element h { level: H4, text: props.children, className: Nothing }
191 , hr: (const $ R.hr {})
195 { children: [ element p { text: props.children } ]
199 R.span { className: classes.code, children: props.children }
201 \(props ∷ PreProps) -> do
203 childrenQ = Nullable.toMaybe props.children
205 propsQ = (_.props >>> Nullable.toMaybe) =<< childrenQ
207 mdxTypeQ = (_.mdxType >>> Nullable.toMaybe) =<< propsQ
209 childrenQ2 = (_.children >>> Nullable.toMaybe) =<< propsQ
211 classNameQ = (_.className >>> Nullable.toMaybe) =<< propsQ
213 isCode = fromMaybe false (mdxTypeQ <#> eq "code")
218 (fromMaybe 200 >>> show >>> (_ <> "px")) do
221 ( String.split (String.Pattern "\n") code
223 # \x -> (x * 12) + 100
226 language = fromMaybe "" (classNameQ >>= String.stripPrefix (String.Pattern "language-"))
228 segmentsQ = parseSegments (codeQ ?|| "")
229 case isCode, language, segmentsQ of
230 true, "purescript", Just initialSegments ->
232 [ element fillInTheGaps
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)
241 updateModal (const $ Just { title: "Failed", kids: [R.text "Try again"] })
246 { initialCode: fromMaybe "" codeQ
250 false, _, _ -> element (unsafeCreateDOMComponent "pre") props
254 [ element mdxProvider
258 , components: mdxComponents
260 , maybeModal # foldMap
263 element clickAway { allowEscape: Just true, onClick: updateModal (const Nothing), style: Nothing },
264 element modal (justifill modalProps)
270 withSidebar <- WithSidebar.makeComponent
273 $ jssClasses \(theme ∷ CSSTheme) ->
277 , flexDirection: "row"
282 component "Sidebar" \{ links } -> React.do
283 classes <- useStyles {}
285 $ element withSidebar
287 { sidebarChildren: [ R.div_ [ R.text "hahahaha" ] ]
288 , notSidebarChildren: [] ∷ Array JSX
292foreign import mdxProvider ∷
295 { components ∷ { | r } -- TODO Don't lie
296 , children ∷ Array JSX
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list