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 (..)
model =
{ result =
{ id = 1
, name = "TheSeamau5/elm-checkerboardgrid-tutorial"
, stars = 66
}
}
elmHubHeader =
header []
[ h1 [] [ text "ElmHub" ]
, span [ class "tagline" ] [ text "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.
]
[ -- 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 =
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 (..)
import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
initialModel =
{ query = "tutorial"
, results =
[ { id = 1
model =
{ result =
{ 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
}
]
}
@@ -43,31 +23,16 @@ elmHubHeader =
view model =
div [ class "content" ]
[ 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 =
Html.beginnerProgram
{ view = view
, update = update
, model = initialModel
}
view model

View File

@@ -1,4 +1,4 @@
Part 2
Part 1
======
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
* [Type Annotation syntax reference](http://elm-lang.org/docs/syntax#type-annotations)
* [`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)
* [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

@@ -6,27 +6,6 @@ import Html.Attributes exposing (..)
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 =
{ query = "tutorial"
, results =
@@ -54,8 +33,6 @@ initialModel =
}
{-| TODO add a type annotation to this function
-}
elmHubHeader =
header []
[ h1 [] [ text "ElmHub" ]
@@ -63,8 +40,6 @@ elmHubHeader =
]
{-| TODO add a type annotation to this function
-}
view model =
div [ class "content" ]
[ elmHubHeader
@@ -72,27 +47,21 @@ view model =
]
{-| TODO add a type annotation to this function
-}
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 { operation = "DELETE_BY_ID", data = result.id } ]
-- TODO add an onClick handler that sends a DELETE_BY_ID msg
[ class "hide-result" ]
[ text "X" ]
]
{-| TODO add a type annotation to this function
-}
update msg model =
if msg.operation == "DELETE_BY_ID" then
{ model
| results = List.filter (\result -> result.id /= msg.data) model.results
}
else
-- TODO if msg.operation == "DELETE_BY_ID",
-- then return a new model without the given ID present anymore.
model

View File

@@ -1,4 +1,4 @@
Part 3
Part 2
======
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
* [`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" }`)
* [Type Annotation syntax reference](http://elm-lang.org/docs/syntax#type-annotations)
* [`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.App as Html
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput)
import Html.Events exposing (onClick)
type alias Model =
@@ -19,12 +19,14 @@ type alias SearchResult =
}
type Msg
= SetQuery String
| DeleteById Int
type alias Msg =
{ operation : String
, data : Int
}
initialModel : Model
{-| TODO add a type annotation to this value
-}
initialModel =
{ query = "tutorial"
, results =
@@ -52,7 +54,8 @@ initialModel =
}
elmHubHeader : Html Msg
{-| TODO add a type annotation to this function
-}
elmHubHeader =
header []
[ h1 [] [ text "ElmHub" ]
@@ -60,45 +63,39 @@ elmHubHeader =
]
view : Model -> Html Msg
{-| TODO add a type annotation to this function
-}
view model =
div [ class "content" ]
[ header []
[ 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" ]
[ elmHubHeader
, ul [ class "results" ] (List.map viewSearchResult model.results)
]
viewSearchResult : SearchResult -> Html Msg
{-| TODO add a type annotation to this function
-}
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" ]
[ class "hide-result", onClick { operation = "DELETE_BY_ID", data = result.id } ]
[ text "X" ]
]
update : Msg -> Model -> Model
{-| TODO add a type annotation to this function
-}
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
if msg.operation == "DELETE_BY_ID" then
{ model
| results = List.filter (\result -> result.id /= msg.data) model.results
}
else
model
main : Program Never
main =
Html.beginnerProgram
{ view = view

View File

@@ -1,4 +1,4 @@
Part 4
Part 3
======
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
* [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.App as Html
import Html.Attributes exposing (class, target, href, property, defaultValue)
import Html.Events exposing (..)
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
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput)
type alias Model =
@@ -90,22 +19,45 @@ type alias SearchResult =
}
type Msg
= SetQuery String
| DeleteById Int
initialModel : Model
initialModel =
{ 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
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
[]
elmHubHeader : Html Msg
elmHubHeader =
header []
[ h1 [] [ text "ElmHub" ]
, span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
]
view : Model -> Html Msg
@@ -115,10 +67,14 @@ view model =
[ h1 [] [ text "ElmHub" ]
, 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" ]
, ul [ class "results" ]
(List.map viewSearchResult model.results)
, ul [ class "results" ] (List.map viewSearchResult model.results)
]
@@ -128,25 +84,24 @@ viewSearchResult result =
[ 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) ]
, button
-- TODO add an onClick handler that sends a DeleteById action
[ class "hide-result" ]
[ text "X" ]
]
type Msg
= SetQuery String
| DeleteById Int
update : Msg -> Model -> Model
update msg model =
case msg of
SetQuery query ->
{ model | query = query }
-- 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
DeleteById idToHide ->
let
newResults =
List.filter (\{ id } -> id /= idToHide) model.results
in
{ model | results = newResults }
main : Program Never
main =
Html.beginnerProgram
{ view = view
, 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
@@ -18,3 +18,7 @@ elm-package install
```bash
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",
"license": "BSD-3-Clause",
"source-directories": [
".",
".."
".", ".."
],
"exposed-modules": [],
"dependencies": {
"NoRedInk/elm-decode-pipeline": "1.1.2 <= 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-lang/core": "4.0.5 <= v < 5.0.0",
"elm-lang/html": "1.1.0 <= v < 2.0.0"
},
"elm-version": "0.17.0 <= v < 0.18.0"
}

View File

@@ -1,49 +1,64 @@
module Main exposing (..)
import Auth
import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (class, target, href, property, defaultValue)
import Html.Events exposing (..)
import Http
import Html.App as Html
import Task exposing (Task)
import Json.Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (..)
main : Program Never
main =
Html.program
Html.beginnerProgram
{ view = view
, update = update
, init = ( initialModel, searchFeed initialModel.query )
, subscriptions = \_ -> Sub.none
, model = initialModel
}
searchFeed : String -> Cmd Msg
searchFeed query =
let
url =
"https://api.github.com/search/repositories?access_token="
++ Auth.token
++ "&q="
++ 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
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)
@@ -53,16 +68,18 @@ responseDecoder =
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
|> required "id" Json.Decode.int
|> required "full_name" Json.Decode.string
|> required "stargazers_count" Json.Decode.int
|> hardcoded 0
|> hardcoded ""
|> hardcoded 0
type alias Model =
{ query : String
, results : List SearchResult
, errorMessage : Maybe String
}
@@ -76,11 +93,21 @@ type alias SearchResult =
initialModel : Model
initialModel =
{ query = "tutorial"
, results = []
, errorMessage = Nothing
, results = decodeResults sampleJson
}
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 =
div [ class "content" ]
@@ -89,22 +116,12 @@ view model =
, 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)
, button [ class "search-button" ] [ text "Search" ]
, 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 []
@@ -117,42 +134,19 @@ viewSearchResult result =
type Msg
= Search
| SetQuery String
= SetQuery String
| DeleteById Int
| HandleSearchResponse (List SearchResult)
| HandleSearchError Http.Error
update : Msg -> Model -> ( Model, Cmd Msg )
update : Msg -> Model -> Model
update msg model =
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 ->
( { model | query = query }, Cmd.none )
{ model | query = query }
DeleteById idToHide ->
let
newResults =
model.results
|> List.filter (\{ id } -> id /= idToHide)
newModel =
{ model | results = newResults }
List.filter (\{ id } -> id /= idToHide) model.results
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
@@ -18,11 +18,3 @@ elm-package install
```bash
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 Json.Decode exposing (..)
import Auth
import Html exposing (..)
import Html.Attributes exposing (class, target, href, property, defaultValue)
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.Pipeline exposing (..)
@@ -15,20 +16,35 @@ main =
Html.program
{ view = view
, update = update
, init = ( initialModel, githubSearch (getQueryString initialModel.query) )
, subscriptions = \_ -> githubResponse decodeResponse
, init = ( initialModel, searchFeed initialModel.query )
, subscriptions = \_ -> Sub.none
}
getQueryString : String -> String
getQueryString query =
-- See https://developer.github.com/v3/search/#example for how to customize!
"access_token="
searchFeed : String -> Cmd Msg
searchFeed query =
let
url =
"https://api.github.com/search/repositories?access_token="
++ Auth.token
++ "&q="
++ 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 =
@@ -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
= Search
| SetQuery String
| DeleteById Int
| HandleSearchResponse (List SearchResult)
| HandleSearchError (Maybe String)
| HandleSearchError Http.Error
decodeResponse : Value -> Msg
decodeResponse json =
-- TODO use decodeValue to decode the response into a Msg.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
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: look at the definition of Msg and
-- the definition of responseDecoder
HandleSearchError (Just "TODO decode the response!")
-- 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 githubSearch : String -> Cmd msg
DeleteById idToHide ->
let
newResults =
model.results
|> List.filter (\{ id } -> id /= idToHide)
port githubResponse : (Value -> msg) -> Sub msg
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
@@ -18,3 +18,11 @@ elm-package install
```bash
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>
<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);
// TODO: app.ports.portNameGoesHere.send(repositories);
});
}
// TODO app.ports.portNameGoesHere.subscribe(searchGithub);
var app = Elm.Main.fullscreen();
</script>
</html>

View File

@@ -1,31 +1,150 @@
port module Main exposing (..)
import ElmHub exposing (..)
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 =
Html.program
{ view = view
, update = update githubSearch
, update = update
, 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)
getQueryString : String -> String
getQueryString query =
-- See https://developer.github.com/v3/search/#example for how to customize!
"access_token="
++ 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 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
@@ -18,28 +18,3 @@ elm-package install
```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

@@ -26,11 +26,11 @@
github.getSearch(query).repositories({}, function (err, 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>
</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",
"license": "BSD-3-Clause",
"source-directories": [
".", ".."
".",
".."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "4.0.5 <= v < 5.0.0",
"elm-lang/html": "1.1.0 <= v < 2.0.0"
"NoRedInk/elm-decode-pipeline": "1.1.2 <= 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"
}

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>