diff --git a/.gitignore b/.gitignore index 0c3f49a..fef0f67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ elm-stuff/ elm.js +app.js diff --git a/App.elm b/App.elm new file mode 100644 index 0000000..4e0bdc8 --- /dev/null +++ b/App.elm @@ -0,0 +1,102 @@ +module App (main) where + +import StartApp +import Effects exposing (Effects, Never) +import Task exposing (Task) +import Html exposing (Html) +import Http +import Json.Decode +import Demo.Connection as Connection +import Demo.Button as Button +import Demo.User as User + + +type alias Model = + { connection : Connection.State + , users : List User.Model + } + + +type Action + = UpdateConnection Connection.Action + | FetchUsers + | UpdateUsers (Result Http.Error (List User.Model)) + + +model : Model +model = + { connection = Connection.Offline + , users = [] + } + + +init : ( Model, Effects Action ) +init = + ( model, Effects.none ) + + +update : Action -> Model -> ( Model, Effects Action ) +update action model = + case action of + UpdateConnection action' -> + let + model' = + { model | connection = Connection.update action' model.connection } + in + case action' of + Connection.Connect -> + ( model', getUsers ) + + Connection.Disconnect -> + ( { model' | users = [] }, Effects.none ) + + Connection.Connected -> + ( model', Effects.none ) + + UpdateUsers (Result.Ok users') -> + ( { model + | users = users' + , connection = Connection.update Connection.Connected model.connection + } + , Effects.none + ) + + _ -> + ( model, Effects.none ) + + +getUsers : Effects.Effects Action +getUsers = + Http.get (Json.Decode.list User.decode) "json/users.json" + |> Task.toResult + |> Task.map UpdateUsers + |> Effects.task + + +view : Signal.Address Action -> Model -> Html +view address model = + Html.div + [] + [ Button.view (Signal.forwardTo address UpdateConnection) model.connection + , User.list model.users + ] + + +app : StartApp.App Model +app = + StartApp.start + { init = init + , inputs = [] + , update = update + , view = view + } + + +main : Signal Html.Html +main = + app.html + + +port runner : Signal (Task Never ()) +port runner = + app.tasks diff --git a/Demo/Button.elm b/Demo/Button.elm new file mode 100644 index 0000000..55625d3 --- /dev/null +++ b/Demo/Button.elm @@ -0,0 +1,33 @@ +module Demo.Button (..) where + +import Html exposing (Html) +import Html.Attributes exposing (class, href) +import Html.Events exposing (onClick) +import Demo.Connection as Connection + + +view : Signal.Address Connection.Action -> Connection.State -> Html +view address state = + case state of + Connection.Offline -> + Html.a + [ class "button connect" + , href "#" + , onClick address Connection.Connect + ] + [ Html.text "Connect" ] + + Connection.Connecting -> + Html.a + [ class "button connecting" + , href "#" + ] + [ Html.text "Connecting" ] + + Connection.Online -> + Html.a + [ class "button disconnect" + , href "#" + , onClick address Connection.Disconnect + ] + [ Html.text "Disconnect" ] diff --git a/Demo/Connection.elm b/Demo/Connection.elm new file mode 100644 index 0000000..8964b56 --- /dev/null +++ b/Demo/Connection.elm @@ -0,0 +1,26 @@ +module Demo.Connection (..) where + + +type State + = Online + | Connecting + | Offline + +type Action + = Connect + | Connected + | Disconnect + + +update : Action -> State -> State +update action state = + case (state, action) of + (Offline, Connect) -> + Connecting + (Connecting, Connected) -> + Online + (Online, Disconnect) -> + Offline + _ -> + state + diff --git a/Demo/User.elm b/Demo/User.elm new file mode 100644 index 0000000..41f3a86 --- /dev/null +++ b/Demo/User.elm @@ -0,0 +1,33 @@ +module Demo.User (..) where + +import Html exposing (Html) +import Html.Attributes exposing (class) +import Json.Decode exposing (Decoder, (:=)) + + +type alias Model = + { id : Int + , name : String + } + + +view : Model -> Html +view user = + Html.li + [] + [ Html.text user.name ] + + +list : List Model -> Html +list users = + Html.ul + [ class "users" ] + <| List.map view users + + +decode : Decoder Model +decode = + Json.Decode.object2 + Model + ("id" := Json.Decode.int) + ("name" := Json.Decode.string) diff --git a/elm-package.json b/elm-package.json index 5ba415f..4168dee 100644 --- a/elm-package.json +++ b/elm-package.json @@ -11,7 +11,8 @@ "elm-lang/core": "3.0.0 <= v < 4.0.0", "evancz/elm-effects": "2.0.1 <= v < 3.0.0", "evancz/elm-html": "4.0.2 <= v < 5.0.0", + "evancz/elm-http": "3.0.0 <= v < 4.0.0", "evancz/start-app": "2.0.2 <= v < 3.0.0" }, "elm-version": "0.16.0 <= v < 0.17.0" -} +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..d50a285 --- /dev/null +++ b/index.html @@ -0,0 +1,18 @@ + + + Elm Exercise + + + + +

Online Users

+ + +
+
+ + +