From eb555aab3ba57631e76d3dc01bb389495f90d1c5 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Sun, 18 Feb 2024 14:45:10 +1000 Subject: [PATCH] Invoke Tauri command from Gleam --- src/videopls.gleam | 81 ++++++++++++++++++++++++++++++++-------------- style.css | 10 ++++++ 2 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/videopls.gleam b/src/videopls.gleam index 051315b..10b28ee 100644 --- a/src/videopls.gleam +++ b/src/videopls.gleam @@ -1,62 +1,93 @@ import gleam/int import gleam/javascript/promise.{type Promise} -import gleam/io import lustre -import lustre/attribute +import lustre/attribute as attr import lustre/element.{type Element} import lustre/element/html import lustre/event +import lustre/effect.{type Effect} pub fn main() { - let app = lustre.simple(init, update, view) + let app = lustre.application(init, update, view) let assert Ok(dispatch) = lustre.start(app, "#app", Nil) dispatch } -type Model = - Int +type Model { + Model(count: Int, greeting: String, name: String) +} -fn init(_) -> Model { - 0 +fn init(_) -> #(Model, Effect(Msg)) { + #(Model(0, "", ""), effect.none()) } pub type Msg { Increment Decrement Greet + GotGreeting(String) + UpdateName(String) } -fn update(model: Model, msg: Msg) -> Model { +fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) { case msg { - Increment -> model + 1 - Decrement -> model - 1 - Greet -> { - { - use greeting <- promise.await(greet("Gleam")) - case greeting { - Ok(g) -> io.print(g) - Error(e) -> io.print("greeting err: " <> e) - } - promise.resolve(#()) - } - model - } + Increment -> #(Model(..model, count: model.count + 1), effect.none()) + Decrement -> #(Model(..model, count: model.count - 1), effect.none()) + Greet -> #(model, get_greeting(model.name)) + GotGreeting(greeting) -> #( + Model(..model, greeting: greeting), + effect.none(), + ) + UpdateName(name) -> #(Model(..model, name: name), effect.none()) } } +fn get_greeting(name: String) -> Effect(Msg) { + effect.from(do_get_greeting(name, _)) +} + +fn do_get_greeting(name: String, dispatch: fn(Msg) -> Nil) -> Nil { + greet(name) + // |> promise.await() + |> promise.map(fn(response) { + case response { + Ok(greeting) -> GotGreeting(greeting) + Error(err) -> GotGreeting("Error: " <> err) + } + }) + |> promise.tap(dispatch) + + Nil +} + @external(javascript, "./ffi/commands.js", "greet") pub fn greet(name: String) -> Promise(Result(String, String)) +fn update_name(text: String) -> Msg { + UpdateName(text) +} + +// -- VIEW + fn view(model: Model) -> Element(Msg) { - let count = int.to_string(model) + let count = int.to_string(model.count) html.div([], [ html.h1([], [element.text("Gleam + Vite + Tauri")]), - html.p([attribute.style([#("text-align", "center")])], [ - element.text("Gleam counter " <> count <> " ✨"), + html.div([attr.class("field text-center")], [ + html.label([attr.for("greet_name")], [element.text("Name")]), + element.text(" "), + html.input([ + attr.type_("text"), + attr.name("greet_name"), + event.on_input(update_name), + ]), ]), - html.p([attribute.style([#("text-align", "center")])], [ + html.p([attr.class("text-center")], [ + element.text(model.greeting <> " " <> count <> " ✨"), + ]), + html.div([attr.class("text-center")], [ html.button([event.on_click(Decrement)], [element.text("-")]), html.button([event.on_click(Increment)], [element.text("+")]), html.button([event.on_click(Greet)], [element.text("Greet")]), diff --git a/style.css b/style.css index ac96d73..e6646a1 100644 --- a/style.css +++ b/style.css @@ -64,6 +64,13 @@ h1 { color: #888; } +.field { + margin-top: 0.5em; +} +.text-center { + text-align: center; +} + button { border-radius: 8px; border: 1px solid transparent; @@ -83,6 +90,9 @@ button:focus, button:focus-visible { outline: 4px auto -webkit-focus-ring-color; } +label { + font-weight: bold; +} @media (prefers-color-scheme: light) { :root {