module Page.Landing exposing ( Model , Msg , view , init , update , subscriptions ) 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, greetWidgetText : String, greeting : String } type DownMsgLanding = Greeting String | TimeUpdate String decodeDownMsgLanding : Decode.Decoder DownMsgLanding decodeDownMsgLanding = let t = Decode.map Greeting (Decode.field "Greeting" Decode.string) in Decode.oneOf [ Decode.map Greeting (Decode.field "Greeting" Decode.string) , Decode.map TimeUpdate (Decode.field "TimeUpdate" Decode.string) ] decodeDownMsg : Decode.Decoder Msg decodeDownMsg = let decoder = Decode.field "Landing" decodeDownMsgLanding in Decode.map DownMsg decoder type UpMsgLanding = RequestGreet String encodeUpMsgLanding : UpMsgLanding -> Value encodeUpMsgLanding msg = case msg of RequestGreet name -> Encode.object [ ( "Landing", Encode.object [ ( "RequestGreet", Encode.string name ) ] ) ] type Msg = DownMsg DownMsgLanding | UpMsg UpMsgLanding | DecodeError Decode.Error | GreetWidgetText String | NoOp init : () -> Model init flags = { time = "time not yet set", greetWidgetText = "", greeting = "" } subscriptions : Model -> Sub Msg subscriptions model = Ports.socketOnEvent (Websockets.EventHandlers (\_ -> NoOp) (\_ -> NoOp) (\_ -> NoOp) (\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 DownMsg (TimeUpdate time) -> ( {model | time = time}, Cmd.none ) DownMsg (Greeting greeting) -> ( {model | greeting = greeting}, Cmd.none) UpMsg upMsgLanding -> ( model, upMsgLanding |> encodeUpMsgLanding |> Ports.socketSend ) GreetWidgetText text -> ( {model | greetWidgetText = text}, Cmd.none ) _ -> (model, Cmd.none) greetWidget : Model -> Element Msg greetWidget model = let idleBlue = Element.rgb255 18 147 217 focusBlue = Element.rgb255 18 125 184 myButton = Element.Input.button [ Element.Background.color idleBlue , Element.mouseOver [Element.Background.color focusBlue] , Element.width (Element.fill |> Element.maximum 100) , Element.height (Element.fill |> Element.maximum 50) ] { onPress = Just <| UpMsg <| RequestGreet model.greetWidgetText , label = Element.text "Greet" } placeholder = case model.greetWidgetText of "" -> Just <| Element.Input.placeholder [] <| Element.text "Type Your Name" _ -> Just <| Element.Input.placeholder [] <| Element.text "" textInput = Element.Input.text [ Element.width (Element.fill |> Element.maximum 400) , Element.height Element.fill ] { onChange = GreetWidgetText , text = model.greetWidgetText , placeholder = placeholder , label = Element.Input.labelHidden "Enter your name" } nameInput = Element.row [] [ textInput , myButton] in Element.column [] [ nameInput , Element.text model.greeting ] view : Model -> Element Msg view model = Element.column [] [ Element.text "Landing" , Element.text <| "Current time is : " ++ model.time , greetWidget model ]