Created
April 29, 2022 19:57
-
-
Save tjdevries/001889135b15c66a2d1c32e8920882cb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
port module Main exposing (..) | |
import Browser | |
import Html exposing (Html, button, div, h1, input, li, text, ul) | |
import Html.Attributes exposing (placeholder, type_, value) | |
import Html.Events exposing (on, onClick, onInput) | |
import Json.Decode as D | |
import Json.Decode exposing (Decoder, field, int, string, andThen, fail, succeed) | |
main : Program () Model Msg | |
main = | |
Browser.element | |
{ init = init | |
, update = update | |
, view = view | |
, subscriptions = subscriptions | |
} | |
type alias Model = | |
{ draft : String | |
, messages : List String | |
} | |
init : () -> ( Model, Cmd Msg ) | |
init _ = | |
( { draft = "", messages = [] } | |
, Cmd.none | |
) | |
type Msg | |
= DraftChanged String | |
| Recv String | |
| Send | |
type DependingOnWhatYouMean | |
= OptionOne | |
dependsStart : Decoder DependingOnWhatYouMean | |
dependsStart = | |
field "variant" string | |
|> andThen dependsWhatYouMeanHelp | |
dependsWhatYouMeanHelp : String -> Decoder DependingOnWhatYouMean | |
dependsWhatYouMeanHelp version = | |
case version of | |
"display" -> | |
succeed OptionOne | |
_ -> | |
fail <| | |
"Trying to decode info, but version " | |
++ version ++ " is not supported." | |
-- Use the `sendMessage` port when someone presses ENTER or clicks | |
-- the "Send" button. Check out index.html to see the corresponding | |
-- JS where this is piped into a WebSocket. | |
-- | |
type alias DisplayMsg = | |
{ type_ : String, data : String } | |
type alias ResponseMsg = | |
DisplayMsg | |
update : Msg -> Model -> ( Model, Cmd Msg ) | |
update msg model = | |
case msg of | |
DraftChanged draft -> | |
( { model | draft = draft } | |
, Cmd.none | |
) | |
Send -> | |
( { model | draft = "" } | |
, sendMessage model.draft | |
) | |
Recv message -> | |
let | |
something = D.decodeString dependsStart message | |
in | |
case something of | |
Ok OptionOne -> | |
( { model | messages = model.messages ++ [ message ] }, Cmd.none ) | |
Err _ -> | |
( { model | messages = model.messages ++ [ message ] }, Cmd.none ) | |
-- view : Int -> Html Msg | |
-- view model = | |
-- div [] | |
-- [ button [ onClick Decrement ] [ text "-" ] | |
-- , div [] [ text (String.fromInt model) ] | |
-- , button [ onClick Increment ] [ text "+" ] | |
-- ] | |
-- | |
port sendMessage : String -> Cmd msg | |
port messageReceiver : (String -> msg) -> Sub msg | |
-- SUBSCRIPTIONS | |
-- Subscribe to the `messageReceiver` port to hear about messages coming in | |
-- from JS. Check out the index.html file to see how this is hooked up to a | |
-- WebSocket. | |
-- | |
subscriptions : Model -> Sub Msg | |
subscriptions _ = | |
messageReceiver Recv | |
view : Model -> Html Msg | |
view model = | |
div [] | |
[ h1 [] [ text "Echo Chat" ] | |
, ul [] | |
(List.map (\msg -> li [] [ text msg ]) model.messages) | |
, input | |
[ type_ "text" | |
, placeholder "Draft" | |
, onInput DraftChanged | |
, on "keydown" (ifIsEnter Send) | |
, value model.draft | |
] | |
[] | |
, button [ onClick Send ] [ text "Send" ] | |
] | |
ifIsEnter : msg -> D.Decoder msg | |
ifIsEnter msg = | |
D.field "key" D.string | |
|> D.andThen | |
(\key -> | |
if key == "Enter" then | |
D.succeed msg | |
else | |
D.fail "some other key" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment