Update part4 and part5

This commit is contained in:
Richard Feldman
2016-06-19 23:30:37 -07:00
parent 5cf0bf1321
commit 908ca61c77
4 changed files with 170 additions and 208 deletions

View File

@@ -1,29 +1,25 @@
module Main (..) where module Main exposing (..)
import Html exposing (..) import Html exposing (..)
import Html.App
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Auth
import StartApp.Simple as StartApp
import Json.Encode
import Signal exposing (Address)
type alias Model = type alias Model =
{ query : String { query : String
, results : List SearchResult , results : List SearchResult
} }
type alias SearchResult = type alias SearchResult =
{ id : ResultId { id : ResultId
, name : String , name : String
, stars : Int , stars : Int
} }
type alias ResultId = type alias ResultId =
Int Int
@@ -32,93 +28,80 @@ type alias ResultId =
initialModel : Model initialModel : Model
initialModel = initialModel =
{ query = "tutorial" { query = "tutorial"
, results = , results =
[ { id = 1 [ { id = 1
, name = "TheSeamau5/elm-checkerboardgrid-tutorial" , name = "TheSeamau5/elm-checkerboardgrid-tutorial"
, stars = 66 , stars = 66
} }
, { id = 2 , { id = 2
, name = "grzegorzbalcerek/elm-by-example" , name = "grzegorzbalcerek/elm-by-example"
, stars = 41 , stars = 41
} }
, { id = 3 , { id = 3
, name = "sporto/elm-tutorial-app" , name = "sporto/elm-tutorial-app"
, stars = 35 , stars = 35
} }
, { id = 4 , { id = 4
, name = "jvoigtlaender/Elm-Tutorium" , name = "jvoigtlaender/Elm-Tutorium"
, stars = 10 , stars = 10
} }
, { id = 5 , { id = 5
, name = "sporto/elm-tutorial-assets" , name = "sporto/elm-tutorial-assets"
, stars = 7 , stars = 7
} }
]
}
view : Address Action -> Model -> Html
view address model =
div
[ class "content" ]
[ header
[]
[ h1 [] [ text "ElmHub" ]
, span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
] ]
, input
[ class "search-query"
-- TODO when we receive onInput, set the query in the model
, defaultValue model.query
]
[]
, button [ class "search-button" ] [ text "Search" ]
, ul
[ class "results" ]
(List.map (viewSearchResult address) model.results)
]
onInput : Address Action -> (String -> Action) -> Attribute
onInput address wrap =
on "input" targetValue (\val -> Signal.message address (wrap val))
defaultValue str =
property "defaultValue" (Json.Encode.string str)
viewSearchResult : Address Action -> SearchResult -> Html
viewSearchResult address result =
li
[]
[ span [ class "star-count" ] [ text (toString result.stars) ]
, a
[ href ("https://github.com/" ++ result.name), target "_blank" ]
[ text result.name ]
, button
-- TODO add an onClick handler that sends a DeleteById action
[ class "hide-result" ]
[ text "X" ]
]
type Action
= SetQuery String
| DeleteById ResultId
update : Action -> Model -> Model
update action model =
-- TODO if we get a SetQuery action, use it to set the model's query field,
-- and if we get a DeleteById action, delete the appropriate result
model
main =
StartApp.start
{ view = view
, update = update
, model = initialModel
} }
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"
-- TODO when we receive onInput, set the query in the model
, 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
-- TODO add an onClick handler that sends a DeleteById action
[ class "hide-result" ]
[ text "X" ]
]
type Msg
= SetQuery String
| DeleteById ResultId
update : Msg -> Model -> Model
update msg model =
-- TODO if we get a SetQuery action, use it to set the model's query field,
-- and if we get a DeleteById action, delete the appropriate result
model
main : Program Never
main =
Html.App.beginnerProgram
{ view = view
, update = update
, model = initialModel
}

View File

@@ -8,9 +8,8 @@
], ],
"exposed-modules": [], "exposed-modules": [],
"dependencies": { "dependencies": {
"elm-lang/core": "3.0.0 <= v < 4.0.0", "elm-lang/core": "4.0.1 <= v < 5.0.0",
"evancz/elm-html": "4.0.0 <= v < 5.0.0", "elm-lang/html": "1.0.0 <= v < 2.0.0"
"evancz/start-app": "2.0.0 <= v < 3.0.0"
}, },
"elm-version": "0.16.0 <= v < 0.17.0" "elm-version": "0.17.0 <= v < 0.18.0"
} }

View File

@@ -1,30 +1,25 @@
module Main (..) where module Main exposing (..)
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (class, target, href, property) import Html.App
import Html.Attributes exposing (class, target, href, property, defaultValue)
import Html.Events exposing (..) import Html.Events exposing (..)
import Auth import Json.Decode exposing (Decoder)
import StartApp.Simple as StartApp
import Http
import Task exposing (Task)
import Effects exposing (Effects)
import Json.Decode exposing (Decoder, (:=))
import Json.Decode.Pipeline exposing (..) import Json.Decode.Pipeline exposing (..)
import Json.Encode
import Signal exposing (Address)
main : Program Never
main = main =
StartApp.start Html.App.beginnerProgram
{ view = view { view = view
, update = update , update = update
, model = initialModel , model = initialModel
} }
sampleJson : String sampleJson : String
sampleJson = sampleJson =
""" """
{ {
"total_count": 40, "total_count": 40,
"incomplete_results": false, "incomplete_results": false,
@@ -68,114 +63,100 @@ sampleJson =
responseDecoder : Decoder (List SearchResult) responseDecoder : Decoder (List SearchResult)
responseDecoder = responseDecoder =
"items" := Json.Decode.list searchResultDecoder Json.Decode.at [ "items" ] (Json.Decode.list searchResultDecoder)
searchResultDecoder : Decoder SearchResult searchResultDecoder : Decoder SearchResult
searchResultDecoder = searchResultDecoder =
-- See https://developer.github.com/v3/search/#example -- See https://developer.github.com/v3/search/#example
-- TODO replace these `hardcoded` with calls to `require` -- TODO replace these `hardcoded` with calls to `require`
decode SearchResult decode SearchResult
|> hardcoded 0 |> hardcoded 0
|> hardcoded "" |> hardcoded ""
|> hardcoded 0 |> hardcoded 0
type alias Model = type alias Model =
{ query : String { query : String
, results : List SearchResult , results : List SearchResult
} }
type alias SearchResult = type alias SearchResult =
{ id : ResultId { id : ResultId
, name : String , name : String
, stars : Int , stars : Int
} }
type alias ResultId = type alias ResultId =
Int Int
initialModel : Model initialModel : Model
initialModel = initialModel =
{ query = "tutorial" { query = "tutorial"
, results = decodeResults sampleJson , results = decodeResults sampleJson
} }
decodeResults : String -> List SearchResult decodeResults : String -> List SearchResult
decodeResults json = decodeResults json =
case Json.Decode.decodeString responseDecoder json of case Json.Decode.decodeString responseDecoder json of
Ok results -> Ok results ->
results results
Err err -> Err err ->
[] []
view : Address Action -> Model -> Html view : Model -> Html Msg
view address model = view model =
div div [ class "content" ]
[ class "content" ] [ header []
[ header [ h1 [] [ text "ElmHub" ]
[] , span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
[ 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)
] ]
, input [ class "search-query", onInput address SetQuery, defaultValue model.query ] []
, button [ class "search-button" ] [ text "Search" ]
, ul
[ class "results" ]
(List.map (viewSearchResult address) model.results)
]
onInput address wrap = viewSearchResult : SearchResult -> Html Msg
on "input" targetValue (\val -> Signal.message address (wrap val)) 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" ]
]
defaultValue str = type Msg
property "defaultValue" (Json.Encode.string str) = SetQuery String
| DeleteById ResultId
| SetResults (List SearchResult)
viewSearchResult : Address Action -> SearchResult -> Html update : Msg -> Model -> Model
viewSearchResult address result = update msg model =
li case msg of
[] SetQuery query ->
[ span [ class "star-count" ] [ text (toString result.stars) ] { model | query = query }
, a
[ href ("https://github.com/" ++ result.name), target "_blank" ]
[ text result.name ]
, button
[ class "hide-result", onClick address (DeleteById result.id) ]
[ text "X" ]
]
SetResults results ->
let
newModel =
{ model | results = results }
in
newModel
type Action DeleteById idToHide ->
= SetQuery String let
| DeleteById ResultId newResults =
| SetResults (List SearchResult) List.filter (\{ id } -> id /= idToHide) model.results
in
{ model | results = newResults }
update : Action -> Model -> Model
update action model =
case action of
SetQuery query ->
{ model | query = query }
SetResults results ->
let
newModel =
{ model | results = results }
in
newModel
DeleteById idToHide ->
let
newResults =
List.filter (\{ id } -> id /= idToHide) model.results
in
{ model | results = newResults }

View File

@@ -4,16 +4,15 @@
"repository": "https://github.com/rtfeldman/elm-workshop.git", "repository": "https://github.com/rtfeldman/elm-workshop.git",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"source-directories": [ "source-directories": [
".", ".." ".",
".."
], ],
"exposed-modules": [], "exposed-modules": [],
"dependencies": { "dependencies": {
"NoRedInk/elm-decode-pipeline": "1.0.0 <= v < 2.0.0", "NoRedInk/elm-decode-pipeline": "1.0.0 <= v < 2.0.0",
"elm-lang/core": "3.0.0 <= v < 4.0.0", "elm-lang/core": "4.0.1 <= v < 5.0.0",
"evancz/elm-effects": "2.0.0 <= v < 3.0.0", "elm-lang/html": "1.0.0 <= v < 2.0.0",
"evancz/elm-html": "4.0.0 <= v < 5.0.0", "evancz/elm-http": "3.0.1 <= v < 4.0.0"
"evancz/elm-http": "3.0.0 <= v < 4.0.0",
"evancz/start-app": "2.0.0 <= v < 3.0.0"
}, },
"elm-version": "0.16.0 <= v < 0.17.0" "elm-version": "0.17.0 <= v < 0.18.0"
} }