Shift everything forward a partg
This commit is contained in:
@@ -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" ] []
|
||||
]
|
||||
@@ -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 }`)
|
||||
@@ -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" ] []
|
||||
]
|
||||
|
||||
@@ -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>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -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
|
||||
|
||||
@@ -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 }`)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" }`)
|
||||
|
||||
157
part5/Main.elm
157
part5/Main.elm
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
148
part6/Main.elm
148
part6/Main.elm
@@ -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 }
|
||||
|
||||
@@ -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)
|
||||
|
||||
102
part7/Main.elm
102
part7/Main.elm
@@ -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 )
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
141
part8/Main.elm
141
part8/Main.elm
@@ -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
|
||||
|
||||
@@ -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#<|)
|
||||
|
||||
@@ -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>
|
||||
|
||||
0
part8/.gitignore → part9/.gitignore
vendored
0
part8/.gitignore → part9/.gitignore
vendored
31
part9/Main.elm
Normal file
31
part9/Main.elm
Normal 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
45
part9/README.md
Normal 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#<|)
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -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
36
part9/index.html
Normal 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>
|
||||
Reference in New Issue
Block a user