From bdaee5113002dc4979808ed294bbd99bce799805 Mon Sep 17 00:00:00 2001 From: Yehowshua Immanuel Date: Sun, 5 Jan 2025 21:25:10 -0500 Subject: [PATCH] Saving work before I start a notable re-factor Going to make major changes to how messages are routed/handled. --- backend/src/landing.rs | 11 ++++- backend/src/main.rs | 19 ++------- frontend/src/Page/Landing.elm | 79 +++++++++++++++++++++++++---------- 3 files changed, 69 insertions(+), 40 deletions(-) diff --git a/backend/src/landing.rs b/backend/src/landing.rs index eb7af31..22ae6f5 100644 --- a/backend/src/landing.rs +++ b/backend/src/landing.rs @@ -2,6 +2,13 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize)] -pub struct Landing { - pub time : String +pub enum DownMsg { + Greeting(String), + TimeUpdate(String), +} + + +#[derive(Serialize)] +pub enum UpMsg { + RequestGreet(String) } diff --git a/backend/src/main.rs b/backend/src/main.rs index d9b1fe7..afb4f56 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -9,22 +9,9 @@ use chrono::Local; mod landing; - -/// Greeting API structures -#[derive(Serialize, Deserialize)] -struct GreetingRequest { - name: String, -} - #[derive(Serialize)] -struct GreetingResponse { - message: String, -} - - -#[derive(Serialize)] -enum ToFrontend { - Landing(landing::Landing) +enum DownMsg { + Landing(landing::DownMsg), } /// WebSocket actor @@ -37,7 +24,7 @@ impl Actor for MyWebSocket { info!("WebSocket actor started"); ctx.run_interval(Duration::from_secs(1), |_, ctx| { let current_time = Local::now().format("%H:%M:%S").to_string(); - let message = ToFrontend::Landing(landing::Landing { time: current_time }); + let message = DownMsg::Landing(landing::DownMsg::TimeUpdate(current_time)); if let Ok(json_message) = serde_json::to_string(&message) { ctx.text(json_message); diff --git a/frontend/src/Page/Landing.elm b/frontend/src/Page/Landing.elm index 534c40c..a4e7aba 100644 --- a/frontend/src/Page/Landing.elm +++ b/frontend/src/Page/Landing.elm @@ -10,36 +10,52 @@ import Element exposing (Element) import Websockets import Ports import Json.Decode as Decode +import Json.Encode as Encode exposing (Value) import Html.Attributes exposing (placeholder) import Element.Input +import Element.Background type alias Model = { - time : String - } -type alias Landing = { - time : String + time : String, + greetWidgetText : String } +type DownMsgLanding + = Greeting String + | TimeUpdate String + +decodeDownMsgLanding : Decode.Decoder DownMsgLanding +decodeDownMsgLanding = + Decode.oneOf + [ Decode.map Greeting (Decode.field "Greeting" Decode.string) + , Decode.map TimeUpdate (Decode.field "TimeUpdate" Decode.string) + ] + +decodeDownMsg : Decode.Decoder Msg +decodeDownMsg = + Decode.map DownMsg decodeDownMsgLanding + +type UpMsgLanding = RequestGreet String + +encodeUpMsgLanding : UpMsgLanding -> Value +encodeUpMsgLanding msg = + case msg of + RequestGreet name -> + Encode.object + [ ( "RequestGreet", Encode.string name ) ] + type Msg - = ToFrontend Landing + = DownMsg DownMsgLanding + | UpMsg UpMsgLanding | DecodeError Decode.Error | GreetWidgetText String | NoOp init : () -> Model init flags = { - time = "time not yet set" + time = "time not yet set", + greetWidgetText = "" } -decodeToFrontend message = - let - decodeTime = Decode.field "time" Decode.string |> Decode.map Landing - decodeLanding = Decode.field "Landing" decodeTime |> Decode.map ToFrontend - decodedMessage = Decode.decodeString decodeLanding message - in - case decodedMessage of - Ok decoded -> decoded - Err err -> DecodeError err - subscriptions : Model -> Sub Msg subscriptions model = Ports.socketOnEvent @@ -47,23 +63,42 @@ subscriptions model = (\_ -> NoOp) (\_ -> NoOp) (\_ -> NoOp) - (\message -> (message.data |> decodeToFrontend)) + (\message -> + case Decode.decodeString decodeDownMsg message.data of + Ok msg -> msg + Err err -> DecodeError err + ) (\_ -> NoOp) ) update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of - ToFrontend landing -> ( {model | time = landing.time}, Cmd.none ) + DownMsg (TimeUpdate time) -> ( {model | time = time}, Cmd.none ) + GreetWidgetText text -> ( {model | greetWidgetText = text}, Cmd.none ) _ -> (model, Cmd.none) -greetWidget = +greetWidget : Model -> Element Msg +greetWidget model = let + idleBlue = Element.Background.color <| Element.rgb255 18 147 217 + focusBlue = Element.Background.color <| Element.rgb255 18 125 184 + + myButton = Element.Input.button + [ idleBlue + , Element.focused [ focusBlue ] + ] + { onPress = Just <| DownMsg <| Greeting model.greetWidgetText + , label = Element.text "My Button" + } + placeholder = case model.greetWidgetText of + "" -> Just <| Element.Input.placeholder [] <| Element.text "Type Your Name" + _ -> Just <| Element.Input.placeholder [] <| Element.text "" textInput = Element.Input.text [] { onChange = GreetWidgetText - , text = "text" - , placeholder = Nothing + , text = model.greetWidgetText + , placeholder = placeholder , label = Element.Input.labelHidden "Greet" } in @@ -75,5 +110,5 @@ view model = Element.column [] [ Element.text "Landing" , Element.text <| "Current time is : " ++ model.time - , greetWidget + , greetWidget model ]