Bump part3 and part4

This commit is contained in:
Richard Feldman
2018-08-13 06:15:44 -04:00
parent 5d27ab52a7
commit 3002567065
58 changed files with 260 additions and 260 deletions

View File

@@ -10,4 +10,7 @@ Then open [http://localhost:3000](http://localhost:3000) in your browser.
## Exercise
Open `src/Article/Feed.elm` in your editor and resolve the TODO there.
Resolve the TODOs in these files:
* `src/Page/Home.elm`
* `src/Page/Settings.elm`
* `src/Page/Article.elm`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 985 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M235 6959 c22 -22 365 -365 761 -762 l721 -722 1652 0 c908 -1 1651
2 1651 5 0 3 -341 346 -758 763 l-757 757 -1655 0 -1654 0 39 -41z"/>
<path d="M3900 6995 c0 -3 698 -704 1550 -1557 l1550 -1551 0 1557 0 1556
-1550 0 c-852 0 -1550 -2 -1550 -5z"/>
<path d="M0 3495 l0 -3310 1655 1655 c909 910 1653 1655 1652 1657 -5 5 -3235
3237 -3269 3270 l-38 37 0 -3309z"/>
<path d="M2008 5199 c-5 -3 329 -345 743 -758 l752 -752 753 753 c414 414 751
755 748 757 -6 7 -2985 7 -2996 0z"/>
<path d="M4522 4327 c-452 -453 -822 -827 -822 -831 0 -4 369 -376 821 -828
l821 -821 829 829 829 829 -822 822 c-453 453 -825 823 -828 823 -3 0 -375
-370 -828 -823z"/>
<path d="M1853 1655 c-904 -905 -1643 -1647 -1643 -1650 0 -3 1484 -5 3297 -5
l3298 0 -1650 1650 c-907 908 -1652 1650 -1655 1650 -3 0 -744 -741 -1647
-1645z"/>
<path d="M6265 2384 c-396 -398 -722 -726 -724 -728 -2 -3 326 -335 728 -737
l731 -732 0 1461 c0 804 -3 1462 -7 1461 -5 -1 -332 -327 -728 -725z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -1,19 +0,0 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

View File

@@ -1,15 +0,0 @@
{
"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"
}

View File

@@ -110,50 +110,11 @@ viewArticles timeZone (Model { articles, sources, session }) =
FeedSources.selected sources
pagination =
viewPaginatedList articles (limit feedSource)
PaginatedList.view ClickedFeedPage articles (limit feedSource)
in
List.append articlesHtml [ pagination ]
{-| 👉 TODO Move this logic into PaginatedList.view and make it reusable,
so we can use it on other pages too!
💡 HINT: Make `PaginatedList.view` return `Html msg` instead of `Html Msg`. (The function will need to accept an extra argument for this to work.)
-}
viewPaginatedList : PaginatedList a -> Int -> Html Msg
viewPaginatedList paginatedList resultsPerPage =
let
totalPages =
ceiling (toFloat (PaginatedList.total paginatedList) / toFloat resultsPerPage)
activePage =
PaginatedList.page paginatedList
viewPageLink currentPage =
pageLink currentPage (currentPage == activePage)
in
if totalPages > 1 then
List.range 1 totalPages
|> List.map viewPageLink
|> ul [ class "pagination" ]
else
Html.text ""
pageLink : Int -> Bool -> Html Msg
pageLink targetPage isActive =
li [ classList [ ( "page-item", True ), ( "active", isActive ) ] ]
[ a
[ class "page-link"
, onClick (ClickedFeedPage targetPage)
-- The RealWorld CSS requires an href to work properly.
, href ""
]
[ text (String.fromInt targetPage) ]
]
viewPreview : Maybe Cred -> Time.Zone -> Article Preview -> Html Msg
viewPreview maybeCred timeZone article =
let

View File

@@ -84,19 +84,8 @@ view model =
[ viewBanner
, div [ class "container page" ]
[ div [ class "row" ]
[ div [ class "col-md-9" ] <|
case model.feed of
Loaded feed ->
viewFeed model.timeZone feed
Loading ->
[]
LoadingSlowly ->
[ Loading.icon ]
Failed ->
[ Loading.error "feed" ]
[ div [ class "col-md-9" ]
(viewFeed model)
, div [ class "col-md-3" ] <|
case model.tags of
Loaded tags ->
@@ -130,11 +119,25 @@ viewBanner =
]
viewFeed : Time.Zone -> Feed.Model -> List (Html Msg)
viewFeed timeZone feed =
div [ class "feed-toggle" ]
[ Feed.viewFeedSources feed |> Html.map GotFeedMsg ]
:: (Feed.viewArticles timeZone feed |> List.map (Html.map GotFeedMsg))
{-| 👉 TODO refactor this to accept narrower types than the entire Model.
💡 HINT: It may end up with multiple arguments!
-}
viewFeed : Model -> List (Html Msg)
viewFeed model =
case model.feed of
Loaded feed ->
div [ class "feed-toggle" ]
[ Feed.viewFeedSources feed |> Html.map GotFeedMsg ]
:: (Feed.viewArticles model.timeZone feed |> List.map (Html.map GotFeedMsg))
Loading ->
[]
LoadingSlowly ->
[ Loading.icon ]
Failed ->
[ Loading.error "feed" ]
viewTags : List Tag -> Html Msg

View File

@@ -98,6 +98,10 @@ type ValidForm
view : Model -> { title : String, content : Html Msg }
view model =
let
form =
viewForm model
in
{ title = "Settings"
, content =
case Session.cred model.session of
@@ -109,7 +113,7 @@ view model =
[ h1 [ class "text-xs-center" ] [ text "Your Settings" ]
, ul [ class "error-messages" ]
(List.map viewProblem model.problems)
, viewForm cred model.form
, form
]
]
]
@@ -120,62 +124,74 @@ view model =
}
viewForm : Cred -> Form -> Html Msg
viewForm cred form =
Html.form [ onSubmit (SubmittedForm cred) ]
[ fieldset []
[ fieldset [ class "form-group" ]
[ input
[ class "form-control"
, placeholder "URL of profile picture"
, value form.avatar
, onInput EnteredAvatar
{-| 👉 TODO refactor this to accept narrower types than the entire Model.
💡 HINT: It may end up with multiple arguments!
-}
viewForm : Model -> Html Msg
viewForm model =
let
form =
model.form
in
case Session.cred model.session of
Nothing ->
text ""
Just cred ->
Html.form [ onSubmit (SubmittedForm cred) ]
[ fieldset []
[ fieldset [ class "form-group" ]
[ input
[ class "form-control"
, placeholder "URL of profile picture"
, value form.avatar
, onInput EnteredAvatar
]
[]
]
, fieldset [ class "form-group" ]
[ input
[ class "form-control form-control-lg"
, placeholder "Username"
, value form.username
, onInput EnteredUsername
]
[]
]
, fieldset [ class "form-group" ]
[ textarea
[ class "form-control form-control-lg"
, placeholder "Short bio about you"
, attribute "rows" "8"
, value form.bio
, onInput EnteredBio
]
[]
]
, fieldset [ class "form-group" ]
[ input
[ class "form-control form-control-lg"
, placeholder "Email"
, value form.email
, onInput EnteredEmail
]
[]
]
, fieldset [ class "form-group" ]
[ input
[ class "form-control form-control-lg"
, type_ "password"
, placeholder "Password"
, value form.password
, onInput EnteredPassword
]
[]
]
, button
[ class "btn btn-lg btn-primary pull-xs-right" ]
[ text "Update Settings" ]
]
[]
]
, fieldset [ class "form-group" ]
[ input
[ class "form-control form-control-lg"
, placeholder "Username"
, value form.username
, onInput EnteredUsername
]
[]
]
, fieldset [ class "form-group" ]
[ textarea
[ class "form-control form-control-lg"
, placeholder "Short bio about you"
, attribute "rows" "8"
, value form.bio
, onInput EnteredBio
]
[]
]
, fieldset [ class "form-group" ]
[ input
[ class "form-control form-control-lg"
, placeholder "Email"
, value form.email
, onInput EnteredEmail
]
[]
]
, fieldset [ class "form-group" ]
[ input
[ class "form-control form-control-lg"
, type_ "password"
, placeholder "Password"
, value form.password
, onInput EnteredPassword
]
[]
]
, button
[ class "btn btn-lg btn-primary pull-xs-right" ]
[ text "Update Settings" ]
]
]
viewProblem : Problem -> Html msg

View File

@@ -1,4 +1,4 @@
module PaginatedList exposing (PaginatedList, fromList, map, mapPage, page, total, values)
module PaginatedList exposing (PaginatedList, fromList, map, mapPage, page, total, values, view)
import Html exposing (Html, a, li, text, ul)
import Html.Attributes exposing (class, classList, href)
@@ -61,3 +61,38 @@ mapPage transform (PaginatedList info) =
-- VIEW
view : (Int -> msg) -> PaginatedList a -> Int -> Html msg
view toMsg list resultsPerPage =
let
totalPages =
ceiling (toFloat (total list) / toFloat resultsPerPage)
activePage =
page list
viewPageLink currentPage =
pageLink toMsg currentPage (currentPage == activePage)
in
if totalPages > 1 then
List.range 1 totalPages
|> List.map viewPageLink
|> ul [ class "pagination" ]
else
Html.text ""
pageLink : (Int -> msg) -> Int -> Bool -> Html msg
pageLink toMsg targetPage isActive =
li [ classList [ ( "page-item", True ), ( "active", isActive ) ] ]
[ a
[ class "page-link"
, onClick (toMsg targetPage)
-- The RealWorld CSS requires an href to work properly.
, href ""
]
[ text (String.fromInt targetPage) ]
]