Last active
February 8, 2016 18:26
-
-
Save dtjm/9d3486138c7ea685002d to your computer and use it in GitHub Desktop.
What is my IP? in Elm
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
{ | |
"version": "1.0.0", | |
"summary": "helpful summary of your project, less than 80 characters", | |
"repository": "https://github.com/user/project.git", | |
"license": "BSD3", | |
"source-directories": [ | |
"." | |
], | |
"exposed-modules": [], | |
"dependencies": { | |
"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" | |
} |
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
module Main (..) where | |
import Effects | |
import Html | |
import Html.Attributes exposing (style) | |
import Html.Events as Events | |
import Http | |
import Json.Decode exposing ((:=)) | |
import StartApp | |
import Task | |
import Time | |
initialModel = | |
{ ip = "" | |
, requestInProgress = False | |
} | |
view address model = | |
Html.div | |
[] | |
[ Html.h1 [] [ Html.text "what is my IP?" ] | |
, Html.pre [] [ Html.text model.ip ] | |
, Html.button | |
[ Events.onClick address Click ] | |
[ Html.text "Get my IP" | |
] | |
, statusView model | |
] | |
statusView model = | |
let | |
text = | |
case model.requestInProgress of | |
True -> | |
"request in progress" | |
False -> | |
"no request in progress" | |
in | |
Html.div | |
[ style [ ( "color", "red" ) ] ] | |
[ Html.text text ] | |
type Action | |
= Click | |
| HandleResponse Response | |
| Tick Time.Time | |
type Response | |
= Success String | |
| Fail String | |
ipDecoder = | |
("ip" := Json.Decode.string) | |
httpErrToAction : Http.Error -> Action | |
httpErrToAction e = | |
case e of | |
Http.Timeout -> | |
HandleResponse (Fail "timeout") | |
Http.NetworkError -> | |
HandleResponse (Fail "network error") | |
Http.UnexpectedPayload s -> | |
HandleResponse (Fail ("unexpected payload: " ++ s)) | |
Http.BadResponse code msg -> | |
HandleResponse | |
(Fail | |
("bad response: HTTP " | |
++ toString code | |
++ ": " | |
++ msg | |
) | |
) | |
getMyIp : Effects.Effects Action | |
getMyIp = | |
Http.get | |
ipDecoder | |
"https://api.ipify.org?format=json" | |
|> Task.toResult | |
|> Task.map | |
(\x -> | |
case x of | |
Err y -> | |
httpErrToAction y | |
Ok y -> | |
HandleResponse (Success y) | |
) | |
|> Effects.task | |
update action model = | |
case action of | |
Click -> | |
( { model | |
| ip = "fetching..." | |
, requestInProgress = True | |
} | |
, Effects.batch [ getMyIp, Effects.tick Tick ] | |
) | |
HandleResponse r -> | |
case r of | |
Success ip -> | |
( { model | |
| ip = ip | |
, requestInProgress = False | |
} | |
, Effects.none | |
) | |
Fail reason -> | |
( { model | |
| ip = "failed: " ++ reason | |
, requestInProgress = False | |
} | |
, Effects.none | |
) | |
Tick t -> | |
let | |
newModel = | |
if model.requestInProgress then | |
{ model | ip = model.ip ++ "." } | |
else | |
model | |
tickEffect = | |
if model.requestInProgress then | |
Effects.tick Tick | |
else | |
Effects.none | |
in | |
( newModel, tickEffect ) | |
ticker : Signal.Signal Action | |
ticker = | |
Signal.map (\t -> Tick t) (Time.every Time.millisecond) | |
app = | |
StartApp.start | |
{ init = ( initialModel, Effects.none ) | |
, update = update | |
, view = view | |
, inputs = [] | |
} | |
main = | |
app.html | |
port tasks : Signal (Task.Task Effects.Never ()) | |
port tasks = | |
app.tasks |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demo: https://dl.dropboxusercontent.com/u/222781/year/screencast%202016-02-06%2015-52-42.gif