Files
elm-0.19-workshop/part6/Main.elm
Richard Feldman 5477ccd20a Add Starter.elm
2018-02-22 17:20:25 -05:00

134 lines
3.5 KiB
Elm

module Main exposing (..)
import Html exposing (..)
import Html.Attributes exposing (class, defaultValue, href, property, target)
import Html.Events exposing (..)
import Json.Starter as Json exposing (Json, Outcome(..), required)
import SampleResponse
type alias Model =
{ query : String
, results : List SearchResult
}
type alias SearchResult =
{ name : String
, id : Int
, stars : Int
}
decodeSearchResult : Json -> Result String SearchResult
decodeSearchResult json =
-- See https://developer.github.com/v3/search/#example
--
-- Look in SampleResponse.elm to see the exact JSON we'll be decoding!
case
Json.decodeObject json
-- TODO insert the appropriate strings to decode the id and stars
[ required [ "name" ]
, required []
, required []
]
of
[ String name {- TODO match the types with the other 2 `required` fields -} ] ->
Ok
{ name = ""
, id = 0
, stars = 0
}
errors ->
Err (Json.errorsToString errors)
decodeSearchResults : Json -> Result String (List SearchResult)
decodeSearchResults json =
case
Json.decodeObject json
-- TODO specify the required field for the search result items
-- based on https://developer.github.com/v3/search/#example
--
-- HINT: It's a field on the outermost object, and it holds an array.
[ required [] ]
of
[ List searchResultsJson ] ->
Json.decodeAll searchResultsJson decodeSearchResult
errors ->
Err (Json.errorsToString errors)
decodeResults : String -> List SearchResult
decodeResults rawJson =
case decodeSearchResults (Json.fromString rawJson) of
Ok searchResults ->
searchResults
_ ->
-- If it failed, we'll return no search results for now.
-- We could improve this by displaying an error to the user!
[]
initialModel : Model
initialModel =
{ query = "tutorial"
, results = decodeResults SampleResponse.json
}
view : Model -> Html Msg
view model =
div [ class "content" ]
[ header []
[ h1 [] [ text "ElmHub" ]
, span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
]
, input [ class "search-query", onInput SetQuery, defaultValue model.query ] []
, button [ class "search-button" ] [ text "Search" ]
, ul [ class "results" ]
(List.map viewSearchResult model.results)
]
viewSearchResult : SearchResult -> Html Msg
viewSearchResult result =
li []
[ span [ class "star-count" ] [ text (toString result.stars) ]
, a [ href ("https://github.com/" ++ result.name), target "_blank" ]
[ text result.name ]
, button [ class "hide-result", onClick (DeleteById result.id) ]
[ text "X" ]
]
type Msg
= SetQuery String
| DeleteById Int
update : Msg -> Model -> Model
update msg model =
case msg of
SetQuery query ->
{ model | query = query }
DeleteById idToHide ->
let
newResults =
List.filter (\{ id } -> id /= idToHide) model.results
in
{ model | results = newResults }
main : Program Never Model Msg
main =
Html.beginnerProgram
{ view = view
, update = update
, model = initialModel
}