Add part4

This commit is contained in:
Richard Feldman
2018-08-09 06:45:07 -04:00
parent 8df12a0e3d
commit facfbccd62
6 changed files with 244 additions and 0 deletions

21
intro/part4/README.md Normal file
View File

@@ -0,0 +1,21 @@
# Part 3
This is just like last time, except first we'll install the `elm/browser` package so we can create an interactive app in the browser, instead of static HTML.
To install the package, `cd` into the `part3/` directory and run:
```shell
elm install elm/browser
```
Then build everything the same way as last time:
```shell
elm make src/Main.elm --output elm.js
```
Finally, open `index.html` in your browser.
## Exercise
Open `src/Main.elm` in your editor and resolve the TODOs there.

View File

@@ -0,0 +1,15 @@
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
"."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "5.1.1 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
}

24
intro/part4/elm.json Normal file
View File

@@ -0,0 +1,24 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.0",
"dependencies": {
"direct": {
"elm/browser": "1.0.0",
"elm/core": "1.0.0",
"elm/html": "1.0.0"
},
"indirect": {
"elm/json": "1.0.0",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.0"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

15
intro/part4/index.html Normal file
View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Elm Workshop</title>
<link rel="stylesheet" href="../server/public/main.css">
<script src="elm.js"></script>
</head>
<body>
<div id="app"></div>
<script>
Elm.Main.init({node: document.getElementById("app")});
</script>
</body>
</html>

View File

@@ -0,0 +1,21 @@
module Article exposing (feed, tags)
-- For now, this module only holds hardcoded data.
--
-- In future exercises, it will read data from the server!
tags =
[ "elm"
, "fun"
, "programming"
, "dragons"
]
feed =
[ { title = "Elm is fun!", description = "Elm", body = "I've really been enjoying it!", tags = [ "elm", "fun" ], slug = "elm-is-fun--zb6nba" }
, { title = "Who says undefined isn't a function anyway?", description = "Functions", body = "Quite frankly I think undefined can be anything it wants to be,if it believes in itself.", slug = "who-says-undefined-isnt-a-function-anyway-t39ope", tags = [ "programming" ] }
, { title = "This compiler is pretty neat", description = "Elm", body = "It tells me about problems in my code. How neat is that?", tags = [ "compilers", "elm" ], slug = "this-compiler-is-pretty-neat-9ycui8" }
, { title = "Are dragons real?", description = "dragons", body = "Do Komodo Dragons count? I think they should. It's right there in the name!", tags = [ "dragons" ], slug = "are-dragons-real-467lsh" }
]

148
intro/part4/src/Main.elm Normal file
View File

@@ -0,0 +1,148 @@
module Main exposing (main)
import Article
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
-- MODEL
type alias Model =
{ tags : List String
, selectedTag : String
{- 👉 TODO: change this `allArticles` annotation to the following:
allArticles : List Article
💡 HINT: You'll need to move the existing annotation to a `type alias`.
-}
, allArticles :
List
{ title : String
, description : String
, body : String
, tags : List String
, slug : String
}
}
{-| 👉 TODO: Replace this comment with a type annotation for `initialModel`
-}
initialModel =
{ tags = Article.tags
, selectedTag = "elm"
, allArticles = Article.feed
}
-- UPDATE
type alias Msg =
{ description : String
, data : String
}
{-| 👉 TODO: Replace this comment with a type annotation for `update`
-}
update msg model =
if msg.description == "ClickedTag" then
{ model | selectedTag = msg.data }
else
model
-- VIEW
{-| 👉 TODO: Replace this comment with a type annotation for `view`
-}
view model =
let
articles =
List.filter (\article -> List.member model.selectedTag article.tags)
model.allArticles
feed =
List.map viewArticle articles
in
div [ class "home-page" ]
[ viewBanner
, div [ class "container page" ]
[ div [ class "row" ]
[ div [ class "col-md-9" ] feed
, div [ class "col-md-3" ]
[ div [ class "sidebar" ]
[ p [] [ text "Popular Tags" ]
, viewTags model
]
]
]
]
]
{-| 👉 TODO: Replace this comment with a type annotation for `view`
-}
viewArticle article =
div [ class "article-preview" ]
[ h1 [] [ text article.title ]
, p [] [ text article.description ]
, span [] [ text "Read more..." ]
]
{-| 👉 TODO: Replace this comment with a type annotation for `view`
-}
viewBanner : Html Msg
viewBanner =
div [ class "banner" ]
[ div [ class "container" ]
[ h1 [ class "logo-font" ] [ text "conduit" ]
, p [] [ text "A place to share your knowledge." ]
]
]
{-| 👉 TODO: Replace this comment with a type annotation for `view`
-}
viewTag selectedTagName tagName =
let
otherClass =
if tagName == selectedTagName then
"tag-selected"
else
"tag-default"
in
button
[ class ("tag-pill " ++ otherClass)
, onClick { description = "ClickedTag", data = tagName }
]
[ text tagName ]
viewTags : Model -> Html Msg
viewTags model =
div [ class "tag-list" ] (List.map (viewTag model.selectedTag) model.tags)
-- MAIN
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, view = view
, update = update
}