Update part8 and part9

This commit is contained in:
Richard Feldman
2016-04-03 08:50:35 -07:00
parent dfbff3f448
commit 63e357f146
11 changed files with 176 additions and 123 deletions

View File

@@ -1,18 +1,19 @@
module ElmHub (..) where
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Attributes exposing (class, target, href, property)
import Html.Events exposing (..)
import Http
import Auth
import Task exposing (Task)
import Effects exposing (Effects)
import Json.Decode exposing (Decoder, (:=))
import Json.Decode.Pipeline exposing (..)
import Json.Encode
import Signal exposing (Address)
searchFeed : Address String -> String -> Task x Action
searchFeed : Address String -> String -> Effects Action
searchFeed address query =
let
-- See https://developer.github.com/v3/search/#example for how to customize!
@@ -23,13 +24,15 @@ searchFeed address query =
++ query
++ "+language:elm&sort=stars&order=desc"
-- These only talk to JavaScript ports now. They don't
-- These only talk to JavaScript ports now. They never result in Actions
-- actually do any actions themselves.
task =
Signal.send address query
|> Task.map (\_ -> DoNothing)
performAction
(\_ -> DoNothing)
(\_ -> DoNothing)
(Signal.send address query)
in
Task.onError task (\_ -> Task.succeed DoNothing)
Effects.task task
responseDecoder : Decoder (List SearchResult)
@@ -39,16 +42,40 @@ responseDecoder =
searchResultDecoder : Decoder SearchResult
searchResultDecoder =
Json.Decode.object3
SearchResult
("id" := Json.Decode.int)
("full_name" := Json.Decode.string)
("stargazers_count" := Json.Decode.int)
decode SearchResult
|> required "id" Json.Decode.int
|> required "full_name" Json.Decode.string
|> required "stargazers_count" Json.Decode.int
{-| Note: this will be a standard function in the next release of Elm.
Example:
type Action =
HandleResponse String | HandleError Http.Error
performAction
(\responseString -> HandleResponse responseString)
(\httpError -> HandleError httpError)
(Http.getString "https://google.com?q=something")
-}
performAction : (a -> b) -> (y -> b) -> Task y a -> Task x b
performAction successToAction errorToAction task =
let
successTask =
Task.map successToAction task
in
Task.onError successTask (\err -> Task.succeed (errorToAction err))
type alias Model =
{ query : String
, results : List SearchResult
, errorMessage : Maybe String
}
@@ -67,6 +94,7 @@ initialModel : Model
initialModel =
{ query = "tutorial"
, results = []
, errorMessage = Nothing
}
@@ -81,12 +109,23 @@ view address model =
]
, input [ class "search-query", onInput address SetQuery, defaultValue model.query ] []
, button [ class "search-button", onClick address Search ] [ text "Search" ]
, viewErrorMessage model.errorMessage
, ul
[ class "results" ]
(List.map (viewSearchResult address) model.results)
]
viewErrorMessage : Maybe String -> Html
viewErrorMessage errorMessage =
case errorMessage of
Just message ->
div [ class "error" ] [ text message ]
Nothing ->
text ""
onInput address wrap =
on "input" targetValue (\val -> Signal.message address (wrap val))
@@ -114,6 +153,7 @@ type Action
| SetQuery String
| DeleteById ResultId
| SetResults (List SearchResult)
| SetErrorMessage (Maybe String)
| DoNothing
@@ -121,17 +161,16 @@ update : Address String -> Action -> Model -> ( Model, Effects Action )
update searchAddress action model =
case action of
Search ->
( model, Effects.task (searchFeed searchAddress model.query) )
( model, searchFeed searchAddress model.query )
SetQuery query ->
( { model | query = query }, Effects.none )
SetResults results ->
let
newModel =
{ model | results = results }
in
( newModel, Effects.none )
( { model | results = results }, Effects.none )
SetErrorMessage errorMessage ->
( { model | errorMessage = errorMessage }, Effects.none )
DeleteById idToHide ->
let