diff options
Diffstat (limited to 'docs/src/app.gleam')
-rw-r--r-- | docs/src/app.gleam | 134 |
1 files changed, 97 insertions, 37 deletions
diff --git a/docs/src/app.gleam b/docs/src/app.gleam index a84d040..d448ef7 100644 --- a/docs/src/app.gleam +++ b/docs/src/app.gleam @@ -1,24 +1,18 @@ // IMPORTS --------------------------------------------------------------------- -import app/page/api/lustre as lustre_api -import app/page/api/lustre/attribute as attribute_api -import app/page/api/lustre/effect as effect_api -import app/page/api/lustre/element as element_api -import app/page/api/lustre/element/html as html_api -import app/page/api/lustre/element/svg as svg_api -import app/page/api/lustre/event as event_api -import app/page/docs/components as components_docs -import app/page/docs/managing_state as managing_state_docs -import app/page/docs/quickstart as quickstart_docs -import app/page/docs/server_side_rendering as server_side_rendering_docs -import app/page/docs/side_effects as side_effects_docs +import app/layout +import gleam/function +import gleam/map.{Map} import lustre +import lustre/attribute +import lustre/effect.{Effect} import lustre/element.{Element} +import lustre/element/html // MAIN ------------------------------------------------------------------------ pub fn main(route: Route) -> fn(Msg) -> Nil { - let app = lustre.simple(init, update, view) + let app = lustre.application(init, update, view) let assert Ok(dispatch) = lustre.start(app, "body", route) dispatch @@ -27,51 +21,117 @@ pub fn main(route: Route) -> fn(Msg) -> Nil { // MODEL ----------------------------------------------------------------------- type Model { - Model(route: Route) + Model(route: Route, content: String, history: Map(String, String)) } -fn init(route: Route) -> Model { - Model(route) +fn init(route: Route) -> #(Model, Effect(Msg)) { + let content = "" + let history = map.new() + let model = Model(route, content, history) + let effects = case route.path { + "/" -> fetch_post("/docs/quickstart", history) + _ -> fetch_post(route.path, history) + } + + #(model, effects) } // UPDATE ---------------------------------------------------------------------- pub type Msg { OnRouteChange(Route) + GotPost(String, String) } pub type Route { Route(path: String, hash: String) } -fn update(model: Model, msg: Msg) -> Model { +fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) { + // We need to do this because Gleam doesn't support record field access in + // guards just yet. + let current_path = model.route.path + case msg { - OnRouteChange(route) -> Model(..model, route: route) + OnRouteChange(Route(path: "/", hash: _) as route) -> #( + Model(..model, route: route), + fetch_post("/docs/quickstart", model.history), + ) + + // Only fetch the markdown + OnRouteChange(Route(path: path, hash: _) as route) if path != current_path -> #( + Model(..model, route: route), + fetch_post(path, model.history), + ) + + GotPost(path, content) -> #( + Model( + ..model, + content: content, + history: map.insert(model.history, path, content), + ), + effect.none(), + ) + } +} + +fn fetch_post(path: String, history: Map(String, String)) -> Effect(Msg) { + use dispatch <- effect.from + + case map.get(history, path) { + Ok(content) -> dispatch(GotPost(path, content)) + Error(_) -> + fetch_post_content(path, function.compose(GotPost(path, _), dispatch)) } } +@external(javascript, "./app.ffi.mjs", "fetch_post") +fn fetch_post_content(path: String, dispatch: fn(String) -> Nil) -> Nil + // VIEW ------------------------------------------------------------------------ fn view(model: Model) -> Element(Msg) { case model.route.path { - "/" -> quickstart_docs.view() - - "/api" -> lustre_api.view() - "/api/lustre" -> lustre_api.view() - "/api/lustre/attribute" -> attribute_api.view() - "/api/lustre/effect" -> effect_api.view() - "/api/lustre/element" -> element_api.view() - "/api/lustre/element/html" -> html_api.view() - "/api/lustre/element/svg" -> svg_api.view() - "/api/lustre/event" -> event_api.view() - - "/docs" -> quickstart_docs.view() - "/docs/quickstart" -> quickstart_docs.view() - "/docs/managing-state" -> managing_state_docs.view() - "/docs/side-effects" -> side_effects_docs.view() - "/docs/components" -> components_docs.view() - "/docs/server-side-rendering" -> server_side_rendering_docs.view() - - _ -> quickstart_docs.view() + "/" -> + html.body( + [], + [ + html.div( + [ + attribute.class( + "w-screen h-screen flex justify-center items-center", + ), + attribute.style([ + #("background-color", "hsla(226,0%,100%,1)"), + #( + "background-image", + " radial-gradient(at 62% 13%, hsla(170,76%,60%,1) 0px, transparent 65%), + radial-gradient(at 67% 42%, hsla(234,89%,70%,1) 0px, transparent 65%), + radial-gradient(at 10% 7%, hsla(213,93%,57%,1) 0px, transparent 65%), + radial-gradient(at 32% 46%, hsla(291,93%,80%,1) 0px, transparent 65%)", + ), + ]), + ], + [ + html.hgroup( + [], + [ + html.h1( + [attribute.class("text-8xl")], + [element.text("Lustre.")], + ), + html.p( + [attribute.class("pl-1")], + [element.text("Web apps from space!")], + ), + ], + ), + ], + ), + layout.docs_section(model.content), + ], + ) + + _ -> layout.docs_page(model.content) } } |