Shift everything forward a partg

This commit is contained in:
Richard Feldman
2016-09-01 01:38:15 -07:00
parent b5c164b53f
commit 46f4efc78b
43 changed files with 521 additions and 521 deletions

View File

@@ -1,23 +0,0 @@
module Main exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
elmHubHeader =
header []
[ -- TODO wrap the following text in an <h1>
text "ElmHub"
, span [ class "tagline" ]
[{- TODO put some text in here that says:
"Like GitHub, but for Elm things."
-}
]
]
main =
div [ class "content" ]
[ -- TODO put the header here
ul [ class "results" ] []
]

View File

@@ -1,25 +0,0 @@
Part 1
======
The instructor will paste notes from the lesson, including code examples from
Q&A, in [this document](https://docs.google.com/document/d/1ApuSOk9DP0YsQrxhW7-WE8UOEAV4PPnLDDeqUOL2o5k/edit?usp=sharing).
## Installation
```bash
elm-package install
```
(Answer `y` when prompted.)
## Building
```bash
elm-live Main.elm --open --output=elm.js
```
## References
* [html-to-elm](http://mbylstra.github.io/html-to-elm/) - paste in HTML, get elm-html code
* [elm-html documentation](http://package.elm-lang.org/packages/elm-lang/html/latest)
* [record syntax](http://elm-lang.org/docs/syntax#records) (e.g. `{ foo = 1, bar = 2 }`)

View File

@@ -4,35 +4,20 @@ import Html exposing (..)
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
model =
{ result =
{ id = 1
, name = "TheSeamau5/elm-checkerboardgrid-tutorial"
, stars = 66
}
}
elmHubHeader = elmHubHeader =
header [] header []
[ h1 [] [ text "ElmHub" ] [ -- TODO wrap the following text in an <h1>
, span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ] text "ElmHub"
] , span [ class "tagline" ]
[{- TODO put some text in here that says:
"Like GitHub, but for Elm things."
view model = -}
div [ class "content" ]
[ elmHubHeader
, ul [ class "results" ]
[ li []
[ span [ class "star-count" ] [{- TODO display the number of stars -}]
-- TODO use the model to put a link here that points to
-- https://github.com/TheSeamau5/elm-checkerboardgrid-tutorial
-- by prepending the "https://github.com/" part.
]
] ]
] ]
main = main =
view model div [ class "content" ]
[ -- TODO put the header here
ul [ class "results" ] []
]

View File

@@ -1,20 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>ElmHub</title>
<script type="text/javascript" src="elm.js"></script>
<link rel="stylesheet" href="style.css">
<link rel="icon" type="image/png" href="elm-hub.png">
</head>
<body>
</body>
<script type="text/javascript">
var app = Elm.Main.fullscreen();
</script>
</html>

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,35 +1,15 @@
module Main exposing (..) module Main exposing (..)
import Html exposing (..) import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
initialModel = model =
{ query = "tutorial" { result =
, results = { id = 1
[ { id = 1 , name = "TheSeamau5/elm-checkerboardgrid-tutorial"
, name = "TheSeamau5/elm-checkerboardgrid-tutorial" , stars = 66
, stars = 66 }
}
, { id = 2
, name = "grzegorzbalcerek/elm-by-example"
, stars = 41
}
, { id = 3
, name = "sporto/elm-tutorial-app"
, stars = 35
}
, { id = 4
, name = "jvoigtlaender/Elm-Tutorium"
, stars = 10
}
, { id = 5
, name = "sporto/elm-tutorial-assets"
, stars = 7
}
]
} }
@@ -43,31 +23,16 @@ elmHubHeader =
view model = view model =
div [ class "content" ] div [ class "content" ]
[ elmHubHeader [ elmHubHeader
, ul [ class "results" ] (List.map viewSearchResult model.results) , ul [ class "results" ]
[ li []
[ span [ class "star-count" ] [{- TODO display the number of stars -}]
-- TODO use the model to put a link here that points to
-- https://github.com/TheSeamau5/elm-checkerboardgrid-tutorial
-- by prepending the "https://github.com/" part.
]
]
] ]
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 DELETE_BY_ID msg
[ class "hide-result" ]
[ text "X" ]
]
update msg model =
-- TODO if msg.operation == "DELETE_BY_ID",
-- then return a new model without the given ID present anymore.
model
main = main =
Html.beginnerProgram view model
{ view = view
, update = update
, model = initialModel
}

View File

@@ -1,4 +1,4 @@
Part 2 Part 1
====== ======
The instructor will paste notes from the lesson, including code examples from The instructor will paste notes from the lesson, including code examples from
@@ -20,7 +20,6 @@ elm-live Main.elm --open --output=elm.js
``` ```
## References ## References
* [html-to-elm](http://mbylstra.github.io/html-to-elm/) - paste in HTML, get elm-html code
* [Type Annotation syntax reference](http://elm-lang.org/docs/syntax#type-annotations) * [elm-html documentation](http://package.elm-lang.org/packages/elm-lang/html/latest)
* [`type alias` syntax reference](http://elm-lang.org/docs/syntax#type-aliases) * [record syntax](http://elm-lang.org/docs/syntax#records) (e.g. `{ foo = 1, bar = 2 }`)
* [`List.map` documentation](http://package.elm-lang.org/packages/elm-lang/core/3.0.0/List#map)

View File

@@ -6,27 +6,6 @@ import Html.Attributes exposing (..)
import Html.Events exposing (onClick) import Html.Events exposing (onClick)
type alias Model =
{ query : String
, results : List SearchResult
}
type alias SearchResult =
{ id : Int
, name : String
, stars : Int
}
type alias Msg =
{ operation : String
, data : Int
}
{-| TODO add a type annotation to this value
-}
initialModel = initialModel =
{ query = "tutorial" { query = "tutorial"
, results = , results =
@@ -54,8 +33,6 @@ initialModel =
} }
{-| TODO add a type annotation to this function
-}
elmHubHeader = elmHubHeader =
header [] header []
[ h1 [] [ text "ElmHub" ] [ h1 [] [ text "ElmHub" ]
@@ -63,8 +40,6 @@ elmHubHeader =
] ]
{-| TODO add a type annotation to this function
-}
view model = view model =
div [ class "content" ] div [ class "content" ]
[ elmHubHeader [ elmHubHeader
@@ -72,28 +47,22 @@ view model =
] ]
{-| TODO add a type annotation to this function
-}
viewSearchResult result = viewSearchResult result =
li [] li []
[ span [ class "star-count" ] [ text (toString result.stars) ] [ span [ class "star-count" ] [ text (toString result.stars) ]
, a [ href ("https://github.com/" ++ result.name), target "_blank" ] , a [ href ("https://github.com/" ++ result.name), target "_blank" ]
[ text result.name ] [ text result.name ]
, button , button
[ class "hide-result", onClick { operation = "DELETE_BY_ID", data = result.id } ] -- TODO add an onClick handler that sends a DELETE_BY_ID msg
[ class "hide-result" ]
[ text "X" ] [ text "X" ]
] ]
{-| TODO add a type annotation to this function
-}
update msg model = update msg model =
if msg.operation == "DELETE_BY_ID" then -- TODO if msg.operation == "DELETE_BY_ID",
{ model -- then return a new model without the given ID present anymore.
| results = List.filter (\result -> result.id /= msg.data) model.results model
}
else
model
main = main =

View File

@@ -1,4 +1,4 @@
Part 3 Part 2
====== ======
The instructor will paste notes from the lesson, including code examples from The instructor will paste notes from the lesson, including code examples from
@@ -21,5 +21,6 @@ elm-live Main.elm --open --output=elm.js
## References ## References
* [`onClick` documentation](http://package.elm-lang.org/packages/evancz/elm-html/4.0.2/Html-Events#onClick) * [Type Annotation syntax reference](http://elm-lang.org/docs/syntax#type-annotations)
* [record update syntax reference](http://elm-lang.org/docs/syntax#records) (e.g. `{ model | query = "foo" }`) * [`type alias` syntax reference](http://elm-lang.org/docs/syntax#type-aliases)
* [`List.map` documentation](http://package.elm-lang.org/packages/elm-lang/core/3.0.0/List#map)

View File

@@ -3,7 +3,7 @@ module Main exposing (..)
import Html exposing (..) import Html exposing (..)
import Html.App as Html import Html.App as Html
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput) import Html.Events exposing (onClick)
type alias Model = type alias Model =
@@ -19,12 +19,14 @@ type alias SearchResult =
} }
type Msg type alias Msg =
= SetQuery String { operation : String
| DeleteById Int , data : Int
}
initialModel : Model {-| TODO add a type annotation to this value
-}
initialModel = initialModel =
{ query = "tutorial" { query = "tutorial"
, results = , results =
@@ -52,7 +54,8 @@ initialModel =
} }
elmHubHeader : Html Msg {-| TODO add a type annotation to this function
-}
elmHubHeader = elmHubHeader =
header [] header []
[ h1 [] [ text "ElmHub" ] [ h1 [] [ text "ElmHub" ]
@@ -60,45 +63,39 @@ elmHubHeader =
] ]
view : Model -> Html Msg {-| TODO add a type annotation to this function
-}
view model = view model =
div [ class "content" ] div [ class "content" ]
[ header [] [ elmHubHeader
[ h1 [] [ text "ElmHub" ]
, span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
]
, input
[ class "search-query"
-- TODO onInput, set the query in the model
, defaultValue model.query
]
[]
, button [ class "search-button" ] [ text "Search" ]
, ul [ class "results" ] (List.map viewSearchResult model.results) , ul [ class "results" ] (List.map viewSearchResult model.results)
] ]
viewSearchResult : SearchResult -> Html Msg {-| TODO add a type annotation to this function
-}
viewSearchResult result = viewSearchResult result =
li [] li []
[ span [ class "star-count" ] [ text (toString result.stars) ] [ span [ class "star-count" ] [ text (toString result.stars) ]
, a [ href ("https://github.com/" ++ result.name), target "_blank" ] , a [ href ("https://github.com/" ++ result.name), target "_blank" ]
[ text result.name ] [ text result.name ]
, button , button
-- TODO add an onClick handler that sends a DeleteById action [ class "hide-result", onClick { operation = "DELETE_BY_ID", data = result.id } ]
[ class "hide-result" ]
[ text "X" ] [ text "X" ]
] ]
update : Msg -> Model -> Model {-| TODO add a type annotation to this function
-}
update msg model = update msg model =
-- TODO if we get a SetQuery action, use it to set the model's query field, if msg.operation == "DELETE_BY_ID" then
-- and if we get a DeleteById action, delete the appropriate result { model
model | results = List.filter (\result -> result.id /= msg.data) model.results
}
else
model
main : Program Never
main = main =
Html.beginnerProgram Html.beginnerProgram
{ view = view { view = view

View File

@@ -1,4 +1,4 @@
Part 4 Part 3
====== ======
The instructor will paste notes from the lesson, including code examples from The instructor will paste notes from the lesson, including code examples from
@@ -21,4 +21,5 @@ elm-live Main.elm --open --output=elm.js
## References ## References
* [Union Types syntax reference](http://elm-lang.org/docs/syntax#union-types) * [`onClick` documentation](http://package.elm-lang.org/packages/evancz/elm-html/4.0.2/Html-Events#onClick)
* [record update syntax reference](http://elm-lang.org/docs/syntax#records) (e.g. `{ model | query = "foo" }`)

View File

@@ -2,79 +2,8 @@ module Main exposing (..)
import Html exposing (..) import Html exposing (..)
import Html.App as Html import Html.App as Html
import Html.Attributes exposing (class, target, href, property, defaultValue) import Html.Attributes exposing (..)
import Html.Events exposing (..) import Html.Events exposing (onClick, onInput)
import Json.Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (..)
main : Program Never
main =
Html.beginnerProgram
{ view = view
, update = update
, model = initialModel
}
sampleJson : String
sampleJson =
"""
{
"total_count": 40,
"incomplete_results": false,
"items": [
{
"id": 3081286,
"name": "Tetris",
"full_name": "dtrupenn/Tetris",
"owner": {
"login": "dtrupenn",
"id": 872147,
"avatar_url": "https://secure.gravatar.com/avatar/e7956084e75f239de85d3a31bc172ace?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png",
"gravatar_id": "",
"url": "https://api.github.com/users/dtrupenn",
"received_events_url": "https://api.github.com/users/dtrupenn/received_events",
"type": "User"
},
"private": false,
"html_url": "https://github.com/dtrupenn/Tetris",
"description": "A C implementation of Tetris using Pennsim through LC4",
"fork": false,
"url": "https://api.github.com/repos/dtrupenn/Tetris",
"created_at": "2012-01-01T00:31:50Z",
"updated_at": "2013-01-05T17:58:47Z",
"pushed_at": "2012-01-01T00:37:02Z",
"homepage": "",
"size": 524,
"stargazers_count": 1,
"watchers_count": 1,
"language": "Assembly",
"forks_count": 0,
"open_issues_count": 0,
"master_branch": "master",
"default_branch": "master",
"score": 10.309712
}
]
}
"""
responseDecoder : Decoder (List SearchResult)
responseDecoder =
Json.Decode.at [ "items" ] (Json.Decode.list searchResultDecoder)
searchResultDecoder : Decoder SearchResult
searchResultDecoder =
-- See https://developer.github.com/v3/search/#example
-- and http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest
-- TODO replace these calls to `hardcoded` with calls to `require`
decode SearchResult
|> hardcoded 0
|> hardcoded ""
|> hardcoded 0
type alias Model = type alias Model =
@@ -90,22 +19,45 @@ type alias SearchResult =
} }
type Msg
= SetQuery String
| DeleteById Int
initialModel : Model initialModel : Model
initialModel = initialModel =
{ query = "tutorial" { query = "tutorial"
, results = decodeResults sampleJson , results =
[ { id = 1
, name = "TheSeamau5/elm-checkerboardgrid-tutorial"
, stars = 66
}
, { id = 2
, name = "grzegorzbalcerek/elm-by-example"
, stars = 41
}
, { id = 3
, name = "sporto/elm-tutorial-app"
, stars = 35
}
, { id = 4
, name = "jvoigtlaender/Elm-Tutorium"
, stars = 10
}
, { id = 5
, name = "sporto/elm-tutorial-assets"
, stars = 7
}
]
} }
decodeResults : String -> List SearchResult elmHubHeader : Html Msg
decodeResults json = elmHubHeader =
-- TODO use Json.Decode.decodeString to translate this into either: header []
-- [ h1 [] [ text "ElmHub" ]
-- * the search results, if decoding succeeded , span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
-- * an empty list if decoding failed ]
--
-- see http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Json-Decode#decodeString
[]
view : Model -> Html Msg view : Model -> Html Msg
@@ -115,10 +67,14 @@ view model =
[ h1 [] [ text "ElmHub" ] [ h1 [] [ text "ElmHub" ]
, span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ] , span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
] ]
, input [ class "search-query", onInput SetQuery, defaultValue model.query ] [] , input
[ class "search-query"
-- TODO onInput, set the query in the model
, defaultValue model.query
]
[]
, button [ class "search-button" ] [ text "Search" ] , button [ class "search-button" ] [ text "Search" ]
, ul [ class "results" ] , ul [ class "results" ] (List.map viewSearchResult model.results)
(List.map viewSearchResult model.results)
] ]
@@ -128,25 +84,24 @@ viewSearchResult result =
[ span [ class "star-count" ] [ text (toString result.stars) ] [ span [ class "star-count" ] [ text (toString result.stars) ]
, a [ href ("https://github.com/" ++ result.name), target "_blank" ] , a [ href ("https://github.com/" ++ result.name), target "_blank" ]
[ text result.name ] [ text result.name ]
, button [ class "hide-result", onClick (DeleteById result.id) ] , button
-- TODO add an onClick handler that sends a DeleteById action
[ class "hide-result" ]
[ text "X" ] [ text "X" ]
] ]
type Msg
= SetQuery String
| DeleteById Int
update : Msg -> Model -> Model update : Msg -> Model -> Model
update msg model = update msg model =
case msg of -- TODO if we get a SetQuery action, use it to set the model's query field,
SetQuery query -> -- and if we get a DeleteById action, delete the appropriate result
{ model | query = query } model
DeleteById idToHide ->
let main : Program Never
newResults = main =
List.filter (\{ id } -> id /= idToHide) model.results Html.beginnerProgram
in { view = view
{ model | results = newResults } , update = update
, model = initialModel
}

View File

@@ -1,4 +1,4 @@
Part 5 Part 4
====== ======
The instructor will paste notes from the lesson, including code examples from The instructor will paste notes from the lesson, including code examples from
@@ -18,3 +18,7 @@ elm-package install
```bash ```bash
elm-live Main.elm --open --output=elm.js elm-live Main.elm --open --output=elm.js
``` ```
## References
* [Union Types syntax reference](http://elm-lang.org/docs/syntax#union-types)

View File

@@ -4,15 +4,12 @@
"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.1.2 <= v < 2.0.0", "elm-lang/core": "4.0.5 <= v < 5.0.0",
"elm-lang/core": "4.0.1 <= v < 5.0.0", "elm-lang/html": "1.1.0 <= v < 2.0.0"
"elm-lang/html": "1.0.0 <= v < 2.0.0",
"evancz/elm-http": "3.0.1 <= v < 4.0.0"
}, },
"elm-version": "0.17.0 <= v < 0.18.0" "elm-version": "0.17.0 <= v < 0.18.0"
} }

View File

@@ -1,49 +1,64 @@
module Main exposing (..) module Main exposing (..)
import Auth
import Html exposing (..) import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (class, target, href, property, defaultValue) import Html.Attributes exposing (class, target, href, property, defaultValue)
import Html.Events exposing (..) import Html.Events exposing (..)
import Http
import Html.App as Html
import Task exposing (Task)
import Json.Decode exposing (Decoder) import Json.Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (..) import Json.Decode.Pipeline exposing (..)
main : Program Never main : Program Never
main = main =
Html.program Html.beginnerProgram
{ view = view { view = view
, update = update , update = update
, init = ( initialModel, searchFeed initialModel.query ) , model = initialModel
, subscriptions = \_ -> Sub.none
} }
searchFeed : String -> Cmd Msg sampleJson : String
searchFeed query = sampleJson =
let """
url = {
"https://api.github.com/search/repositories?access_token=" "total_count": 40,
++ Auth.token "incomplete_results": false,
++ "&q=" "items": [
++ query {
++ "+language:elm&sort=stars&order=desc" "id": 3081286,
"name": "Tetris",
-- Hint: responseDecoder may be useful here "full_name": "dtrupenn/Tetris",
task = "owner": {
"TODO replace this String with a Task using http://package.elm-lang.org/packages/evancz/elm-http/latest/Http#get" "login": "dtrupenn",
in "id": 872147,
-- TODO replace this Cmd.none with a call to Task.perform "avatar_url": "https://secure.gravatar.com/avatar/e7956084e75f239de85d3a31bc172ace?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png",
-- http://package.elm-lang.org/packages/elm-lang/core/4.0.1/Task#perform "gravatar_id": "",
-- "url": "https://api.github.com/users/dtrupenn",
-- Hint: pass these to Task.perform, but in a different order than this! "received_events_url": "https://api.github.com/users/dtrupenn/received_events",
-- "type": "User"
-- task },
-- HandleSearchResponse "private": false,
-- HandleSearchError "html_url": "https://github.com/dtrupenn/Tetris",
Cmd.none "description": "A C implementation of Tetris using Pennsim through LC4",
"fork": false,
"url": "https://api.github.com/repos/dtrupenn/Tetris",
"created_at": "2012-01-01T00:31:50Z",
"updated_at": "2013-01-05T17:58:47Z",
"pushed_at": "2012-01-01T00:37:02Z",
"homepage": "",
"size": 524,
"stargazers_count": 1,
"watchers_count": 1,
"language": "Assembly",
"forks_count": 0,
"open_issues_count": 0,
"master_branch": "master",
"default_branch": "master",
"score": 10.309712
}
]
}
"""
responseDecoder : Decoder (List SearchResult) responseDecoder : Decoder (List SearchResult)
@@ -53,16 +68,18 @@ responseDecoder =
searchResultDecoder : Decoder SearchResult searchResultDecoder : Decoder SearchResult
searchResultDecoder = searchResultDecoder =
-- See https://developer.github.com/v3/search/#example
-- and http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest
-- TODO replace these calls to `hardcoded` with calls to `require`
decode SearchResult decode SearchResult
|> required "id" Json.Decode.int |> hardcoded 0
|> required "full_name" Json.Decode.string |> hardcoded ""
|> required "stargazers_count" Json.Decode.int |> hardcoded 0
type alias Model = type alias Model =
{ query : String { query : String
, results : List SearchResult , results : List SearchResult
, errorMessage : Maybe String
} }
@@ -76,11 +93,21 @@ type alias SearchResult =
initialModel : Model initialModel : Model
initialModel = initialModel =
{ query = "tutorial" { query = "tutorial"
, results = [] , results = decodeResults sampleJson
, errorMessage = Nothing
} }
decodeResults : String -> List SearchResult
decodeResults json =
-- TODO use Json.Decode.decodeString to translate this into either:
--
-- * the search results, if decoding succeeded
-- * an empty list if decoding failed
--
-- see http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Json-Decode#decodeString
[]
view : Model -> Html Msg view : Model -> Html Msg
view model = view model =
div [ class "content" ] div [ class "content" ]
@@ -89,22 +116,12 @@ view model =
, span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ] , span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
] ]
, input [ class "search-query", onInput SetQuery, defaultValue model.query ] [] , input [ class "search-query", onInput SetQuery, defaultValue model.query ] []
, button [ class "search-button", onClick Search ] [ text "Search" ] , button [ class "search-button" ] [ text "Search" ]
, viewErrorMessage model.errorMessage , ul [ class "results" ]
, ul [ class "results" ] (List.map viewSearchResult model.results) (List.map viewSearchResult model.results)
] ]
viewErrorMessage : Maybe String -> Html a
viewErrorMessage errorMessage =
case errorMessage of
Just message ->
div [ class "error" ] [ text message ]
Nothing ->
text ""
viewSearchResult : SearchResult -> Html Msg viewSearchResult : SearchResult -> Html Msg
viewSearchResult result = viewSearchResult result =
li [] li []
@@ -117,42 +134,19 @@ viewSearchResult result =
type Msg type Msg
= Search = SetQuery String
| SetQuery String
| DeleteById Int | DeleteById Int
| HandleSearchResponse (List SearchResult)
| HandleSearchError Http.Error
update : Msg -> Model -> ( Model, Cmd Msg ) update : Msg -> Model -> Model
update msg model = update msg model =
case msg of case msg of
Search ->
( model, searchFeed model.query )
HandleSearchResponse results ->
( { model | results = results }, Cmd.none )
HandleSearchError error ->
-- TODO if decoding failed, store the message in model.errorMessage
--
-- Hint 1: look for "decode" in the documentation for this union type:
-- http://package.elm-lang.org/packages/evancz/elm-http/latest/Http#Error
--
-- Hint 2: to check if this is working, break responseDecoder
-- by changing "stargazers_count" to "description"
( model, Cmd.none )
SetQuery query -> SetQuery query ->
( { model | query = query }, Cmd.none ) { model | query = query }
DeleteById idToHide -> DeleteById idToHide ->
let let
newResults = newResults =
model.results List.filter (\{ id } -> id /= idToHide) model.results
|> List.filter (\{ id } -> id /= idToHide)
newModel =
{ model | results = newResults }
in in
( newModel, Cmd.none ) { model | results = newResults }

View File

@@ -1,4 +1,4 @@
Part 6 Part 5
====== ======
The instructor will paste notes from the lesson, including code examples from The instructor will paste notes from the lesson, including code examples from
@@ -18,11 +18,3 @@ elm-package install
```bash ```bash
elm-live Main.elm --open --output=elm.js elm-live Main.elm --open --output=elm.js
``` ```
## References
* [**let-expressions**](http://elm-lang.org/docs/syntax#let-expressions)
* [**case-expressions** and **if-expressions**](http://elm-lang.org/docs/syntax#conditionals)
* [HTTP Tasks tutorial](http://elm-lang.org/guide/reactivity#http-tasks)
* [HTTP Error documentation](http://package.elm-lang.org/packages/evancz/elm-http/3.0.0/Http#Error)
* [Modules syntax reference](http://elm-lang.org/docs/syntax#modules)

View File

@@ -1,11 +1,12 @@
port module Main exposing (..) module Main exposing (..)
import Html.App as Html import Auth
import Json.Decode exposing (..)
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (class, target, href, property, defaultValue) import Html.Attributes exposing (class, target, href, property, defaultValue)
import Html.Events exposing (..) import Html.Events exposing (..)
import Auth import Http
import Html.App as Html
import Task exposing (Task)
import Json.Decode exposing (Decoder) import Json.Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (..) import Json.Decode.Pipeline exposing (..)
@@ -15,19 +16,34 @@ main =
Html.program Html.program
{ view = view { view = view
, update = update , update = update
, init = ( initialModel, githubSearch (getQueryString initialModel.query) ) , init = ( initialModel, searchFeed initialModel.query )
, subscriptions = \_ -> githubResponse decodeResponse , subscriptions = \_ -> Sub.none
} }
getQueryString : String -> String searchFeed : String -> Cmd Msg
getQueryString query = searchFeed query =
-- See https://developer.github.com/v3/search/#example for how to customize! let
"access_token=" url =
++ Auth.token "https://api.github.com/search/repositories?access_token="
++ "&q=" ++ Auth.token
++ query ++ "&q="
++ "+language:elm&sort=stars&order=desc" ++ query
++ "+language:elm&sort=stars&order=desc"
-- Hint: responseDecoder may be useful here
task =
"TODO replace this String with a Task using http://package.elm-lang.org/packages/evancz/elm-http/latest/Http#get"
in
-- TODO replace this Cmd.none with a call to Task.perform
-- http://package.elm-lang.org/packages/elm-lang/core/4.0.1/Task#perform
--
-- Hint: pass these to Task.perform, but in a different order than this!
--
-- task
-- HandleSearchResponse
-- HandleSearchError
Cmd.none
responseDecoder : Decoder (List SearchResult) responseDecoder : Decoder (List SearchResult)
@@ -100,51 +116,43 @@ viewSearchResult result =
] ]
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Search ->
( model, githubSearch (getQueryString model.query) )
SetQuery query ->
( { model | query = query }, Cmd.none )
HandleSearchResponse results ->
( { model | results = results }, Cmd.none )
HandleSearchError error ->
( { model | errorMessage = error }, Cmd.none )
DeleteById idToDelete ->
let
newResults =
model.results
|> List.filter (\{ id } -> id /= idToDelete)
newModel =
{ model | results = newResults }
in
( newModel, Cmd.none )
type Msg type Msg
= Search = Search
| SetQuery String | SetQuery String
| DeleteById Int | DeleteById Int
| HandleSearchResponse (List SearchResult) | HandleSearchResponse (List SearchResult)
| HandleSearchError (Maybe String) | HandleSearchError Http.Error
decodeResponse : Value -> Msg update : Msg -> Model -> ( Model, Cmd Msg )
decodeResponse json = update msg model =
-- TODO use decodeValue to decode the response into a Msg. case msg of
-- Search ->
-- Hint: look at the definition of Msg and ( model, searchFeed model.query )
-- the definition of responseDecoder
HandleSearchError (Just "TODO decode the response!")
HandleSearchResponse results ->
( { model | results = results }, Cmd.none )
port githubSearch : String -> Cmd msg HandleSearchError error ->
-- TODO if decoding failed, store the message in model.errorMessage
--
-- Hint 1: look for "decode" in the documentation for this union type:
-- http://package.elm-lang.org/packages/evancz/elm-http/latest/Http#Error
--
-- Hint 2: to check if this is working, break responseDecoder
-- by changing "stargazers_count" to "description"
( model, Cmd.none )
SetQuery query ->
( { model | query = query }, Cmd.none )
port githubResponse : (Value -> msg) -> Sub msg DeleteById idToHide ->
let
newResults =
model.results
|> List.filter (\{ id } -> id /= idToHide)
newModel =
{ model | results = newResults }
in
( newModel, Cmd.none )

View File

@@ -1,4 +1,4 @@
Part 7 Part 6
====== ======
The instructor will paste notes from the lesson, including code examples from The instructor will paste notes from the lesson, including code examples from
@@ -18,3 +18,11 @@ elm-package install
```bash ```bash
elm-live Main.elm --open --output=elm.js elm-live Main.elm --open --output=elm.js
``` ```
## References
* [**let-expressions**](http://elm-lang.org/docs/syntax#let-expressions)
* [**case-expressions** and **if-expressions**](http://elm-lang.org/docs/syntax#conditionals)
* [HTTP Tasks tutorial](http://elm-lang.org/guide/reactivity#http-tasks)
* [HTTP Error documentation](http://package.elm-lang.org/packages/evancz/elm-http/3.0.0/Http#Error)
* [Modules syntax reference](http://elm-lang.org/docs/syntax#modules)

View File

@@ -4,33 +4,17 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>ElmHub</title> <title>ElmHub</title>
<script type="text/javascript" src="github.js"></script>
<script type="text/javascript" src="elm.js"></script> <script type="text/javascript" src="elm.js"></script>
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
<link rel="icon" type="image/png" href="elm-hub.png"> <link rel="icon" type="image/png" href="elm-hub.png">
</head> </head>
<body> <body>
<div id="elm-landing-pad"></div>
</body> </body>
<script type="text/javascript"> <script type="text/javascript">
// documentation: https://github.com/michael/github var app = Elm.Main.fullscreen();
var github = new Github();
var app = Elm.Main.embed(document.getElementById("elm-landing-pad"));
function searchGithub(query) {
console.log("Searching for", query);
github.getSearch(query).repositories({}, function (err, repositories) {
console.log("Got response", repositories);
// TODO: app.ports.portNameGoesHere.send(repositories);
});
}
// TODO app.ports.portNameGoesHere.subscribe(searchGithub);
</script> </script>
</html> </html>

View File

@@ -1,31 +1,150 @@
port module Main exposing (..) port module Main exposing (..)
import ElmHub exposing (..)
import Html.App as Html import Html.App as Html
import Json.Decode import Json.Decode exposing (..)
import Html exposing (..)
import Html.Attributes exposing (class, target, href, property, defaultValue)
import Html.Events exposing (..)
import Auth
import Json.Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (..)
main : Program Never main : Program Never
main = main =
Html.program Html.program
{ view = view { view = view
, update = update githubSearch , update = update
, init = ( initialModel, githubSearch (getQueryString initialModel.query) ) , init = ( initialModel, githubSearch (getQueryString initialModel.query) )
, subscriptions = \_ -> githubResponse decodeResponse , subscriptions = \_ -> githubResponse decodeResponse
} }
decodeResponse : Json.Decode.Value -> Msg getQueryString : String -> String
decodeResponse json = getQueryString query =
case Json.Decode.decodeValue responseDecoder json of -- See https://developer.github.com/v3/search/#example for how to customize!
Err err -> "access_token="
HandleSearchError (Just err) ++ Auth.token
++ "&q="
++ query
++ "+language:elm&sort=stars&order=desc"
Ok results ->
HandleSearchResponse results responseDecoder : Decoder (List SearchResult)
responseDecoder =
Json.Decode.at [ "items" ] (Json.Decode.list searchResultDecoder)
searchResultDecoder : Decoder SearchResult
searchResultDecoder =
decode SearchResult
|> required "id" Json.Decode.int
|> required "full_name" Json.Decode.string
|> required "stargazers_count" Json.Decode.int
type alias Model =
{ query : String
, results : List SearchResult
, errorMessage : Maybe String
}
type alias SearchResult =
{ id : Int
, name : String
, stars : Int
}
initialModel : Model
initialModel =
{ query = "tutorial"
, results = []
, errorMessage = Nothing
}
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", onClick Search ] [ text "Search" ]
, viewErrorMessage model.errorMessage
, ul [ class "results" ] (List.map viewSearchResult model.results)
]
viewErrorMessage : Maybe String -> Html a
viewErrorMessage errorMessage =
case errorMessage of
Just message ->
div [ class "error" ] [ text message ]
Nothing ->
text ""
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" ]
]
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Search ->
( model, githubSearch (getQueryString model.query) )
SetQuery query ->
( { model | query = query }, Cmd.none )
HandleSearchResponse results ->
( { model | results = results }, Cmd.none )
HandleSearchError error ->
( { model | errorMessage = error }, Cmd.none )
DeleteById idToDelete ->
let
newResults =
model.results
|> List.filter (\{ id } -> id /= idToDelete)
newModel =
{ model | results = newResults }
in
( newModel, Cmd.none )
type Msg
= Search
| SetQuery String
| DeleteById Int
| HandleSearchResponse (List SearchResult)
| HandleSearchError (Maybe String)
decodeResponse : Value -> Msg
decodeResponse json =
-- TODO use decodeValue to decode the response into a Msg.
--
-- Hint: look at the definition of Msg and
-- the definition of responseDecoder
HandleSearchError (Just "TODO decode the response!")
port githubSearch : String -> Cmd msg port githubSearch : String -> Cmd msg
port githubResponse : (Json.Decode.Value -> msg) -> Sub msg port githubResponse : (Value -> msg) -> Sub msg

View File

@@ -1,4 +1,4 @@
Part 8 Part 7
====== ======
The instructor will paste notes from the lesson, including code examples from The instructor will paste notes from the lesson, including code examples from
@@ -18,28 +18,3 @@ elm-package install
```bash ```bash
elm-live Main.elm --open --output=elm.js elm-live Main.elm --open --output=elm.js
``` ```
## Running Tests
Do either (or both!) of the following:
#### Running tests on the command line
```bash
elm-test
```
#### Running tests in a browser
```bash
cd tests
elm-reactor
```
Then visit [localhost:8000](http://localhost:8000) and choose `HtmlRunner.elm`.
## References
* [Using Elm packages](https://github.com/elm-lang/elm-package/blob/master/README.md#basic-usage)
* [elm-test documentation](http://package.elm-lang.org/packages/project-fuzzball/test/latest)
* [`(<|)` documentation](http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Basics#<|)

View File

@@ -26,11 +26,11 @@
github.getSearch(query).repositories({}, function (err, repositories) { github.getSearch(query).repositories({}, function (err, repositories) {
console.log("Got response", repositories); console.log("Got response", repositories);
app.ports.githubResponse.send(repositories); // TODO: app.ports.portNameGoesHere.send(repositories);
}); });
} }
app.ports.githubSearch.subscribe(searchGithub); // TODO app.ports.portNameGoesHere.subscribe(searchGithub);
</script> </script>
</html> </html>

31
part9/Main.elm Normal file
View File

@@ -0,0 +1,31 @@
port module Main exposing (..)
import ElmHub exposing (..)
import Html.App as Html
import Json.Decode
main : Program Never
main =
Html.program
{ view = view
, update = update githubSearch
, init = ( initialModel, githubSearch (getQueryString initialModel.query) )
, subscriptions = \_ -> githubResponse decodeResponse
}
decodeResponse : Json.Decode.Value -> Msg
decodeResponse json =
case Json.Decode.decodeValue responseDecoder json of
Err err ->
HandleSearchError (Just err)
Ok results ->
HandleSearchResponse results
port githubSearch : String -> Cmd msg
port githubResponse : (Json.Decode.Value -> msg) -> Sub msg

45
part9/README.md Normal file
View File

@@ -0,0 +1,45 @@
Part 8
======
The instructor will paste notes from the lesson, including code examples from
Q&A, in [this document](https://docs.google.com/document/d/1ApuSOk9DP0YsQrxhW7-WE8UOEAV4PPnLDDeqUOL2o5k/edit?usp=sharing).
## Installation
```bash
elm-package install
```
(Answer `y` when prompted.)
## Building
```bash
elm-live Main.elm --open --output=elm.js
```
## Running Tests
Do either (or both!) of the following:
#### Running tests on the command line
```bash
elm-test
```
#### Running tests in a browser
```bash
cd tests
elm-reactor
```
Then visit [localhost:8000](http://localhost:8000) and choose `HtmlRunner.elm`.
## References
* [Using Elm packages](https://github.com/elm-lang/elm-package/blob/master/README.md#basic-usage)
* [elm-test documentation](http://package.elm-lang.org/packages/project-fuzzball/test/latest)
* [`(<|)` documentation](http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Basics#<|)

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -4,12 +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": {
"elm-lang/core": "4.0.5 <= v < 5.0.0", "NoRedInk/elm-decode-pipeline": "1.1.2 <= v < 2.0.0",
"elm-lang/html": "1.1.0 <= v < 2.0.0" "elm-lang/core": "4.0.1 <= v < 5.0.0",
"elm-lang/html": "1.0.0 <= v < 2.0.0",
"evancz/elm-http": "3.0.1 <= v < 4.0.0"
}, },
"elm-version": "0.17.0 <= v < 0.18.0" "elm-version": "0.17.0 <= v < 0.18.0"
} }

36
part9/index.html Normal file
View File

@@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>ElmHub</title>
<script type="text/javascript" src="github.js"></script>
<script type="text/javascript" src="elm.js"></script>
<link rel="stylesheet" href="style.css">
<link rel="icon" type="image/png" href="elm-hub.png">
</head>
<body>
<div id="elm-landing-pad"></div>
</body>
<script type="text/javascript">
// documentation: https://github.com/michael/github
var github = new Github();
var app = Elm.Main.embed(document.getElementById("elm-landing-pad"));
function searchGithub(query) {
console.log("Searching for", query);
github.getSearch(query).repositories({}, function (err, repositories) {
console.log("Got response", repositories);
app.ports.githubResponse.send(repositories);
});
}
app.ports.githubSearch.subscribe(searchGithub);
</script>
</html>