From 89182d21566987ef2b62e5ef5e54c7ae35ba6c60 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 27 Mar 2016 09:37:35 -0700 Subject: [PATCH] Reorganize 11 and 12 --- stages/11/Component/SearchResult.elm | 52 --------------- stages/11/{Component => }/ElmHub.elm | 86 +++++++++--------------- stages/11/ElmHub/Css.elm | 14 ++++ stages/11/Main.elm | 2 +- stages/11/README.md | 8 +-- stages/11/SearchResult.elm | 44 +++++++++++++ stages/{12/css => 11}/Stylesheets.elm | 4 +- stages/11/elm-package.json | 3 +- stages/11/style.css | 94 ++------------------------- stages/12/Component/ElmHub.elm | 15 ++--- stages/12/Component/SearchResult.elm | 14 ++-- stages/12/ElmHub.elm | 8 --- stages/12/README.md | 8 ++- stages/12/Stylesheets.elm | 10 --- stages/12/elm-package.json | 3 +- stages/12/style.css | 91 ++++++++++++++++++++++++++ 16 files changed, 207 insertions(+), 249 deletions(-) delete mode 100644 stages/11/Component/SearchResult.elm rename stages/11/{Component => }/ElmHub.elm (51%) create mode 100644 stages/11/ElmHub/Css.elm create mode 100644 stages/11/SearchResult.elm rename stages/{12/css => 11}/Stylesheets.elm (65%) delete mode 100644 stages/12/ElmHub.elm delete mode 100644 stages/12/Stylesheets.elm diff --git a/stages/11/Component/SearchResult.elm b/stages/11/Component/SearchResult.elm deleted file mode 100644 index 4dedbd3..0000000 --- a/stages/11/Component/SearchResult.elm +++ /dev/null @@ -1,52 +0,0 @@ -module Component.SearchResult (..) where - -import Html exposing (..) -import Html.Attributes exposing (..) -import Html.Events exposing (..) -import Signal exposing (Address) -import Effects exposing (Effects) - - -type alias Model = - { id : Int - , name : String - , stars : Int - , expanded : Bool - } - - -type alias ResultId = - Int - - -type Action - = Expand - | Collapse - - -update : Action -> Model -> ( Model, Effects Action ) -update action model = - -- TODO make expand and collapse work - ( model, Effects.none ) - - -view : Address Action -> Model -> Html -view address model = - li - [] - <| if model.expanded then - [ span [ class "star-count" ] [ text (toString model.stars) ] - , a - [ href ("https://github.com/" ++ model.name), target "_blank" ] - [ text model.name ] - , button - -- TODO when the user clicks, send a Collapse action - [ class "hide-result" ] - [ text "X" ] - ] - else - [ button - -- TODO when the user clicks, send an Expand action - [ class "expand-result" ] - [ text "Show" ] - ] diff --git a/stages/11/Component/ElmHub.elm b/stages/11/ElmHub.elm similarity index 51% rename from stages/11/Component/ElmHub.elm rename to stages/11/ElmHub.elm index e825e6d..24667ee 100644 --- a/stages/11/Component/ElmHub.elm +++ b/stages/11/ElmHub.elm @@ -1,4 +1,4 @@ -module Component.ElmHub (..) where +module ElmHub (..) where import Html exposing (..) import Html.Attributes exposing (..) @@ -10,7 +10,8 @@ import Effects exposing (Effects) import Json.Decode exposing (Decoder, (:=)) import Json.Encode import Signal exposing (Address) -import Component.SearchResult exposing (ResultId) +import Dict exposing (Dict) +import SearchResult searchFeed : String -> Task x Action @@ -20,7 +21,7 @@ searchFeed query = url = "https://api.github.com/search/repositories?q=" ++ query - ++ "+language:elm&sort=stars&order=desc" + ++ "+language:elm" task = Http.get responseDecoder url @@ -29,31 +30,21 @@ searchFeed query = Task.onError task (\_ -> Task.succeed (SetResults [])) -responseDecoder : Decoder (List Component.SearchResult.Model) +responseDecoder : Decoder (List SearchResult.Model) responseDecoder = - "items" := Json.Decode.list searchResultDecoder - - -searchResultDecoder : Decoder Component.SearchResult.Model -searchResultDecoder = - Json.Decode.object4 - Component.SearchResult.Model - ("id" := Json.Decode.int) - ("full_name" := Json.Decode.string) - ("stargazers_count" := Json.Decode.int) - (Json.Decode.succeed True) + "items" := Json.Decode.list SearchResult.decoder type alias Model = { query : String - , results : List Component.SearchResult.Model + , results : Dict SearchResult.ResultId SearchResult.Model } initialModel : Model initialModel = { query = "tutorial" - , results = [] + , results = Dict.empty } @@ -74,22 +65,24 @@ view address model = ] -viewSearchResults : Address Action -> List Component.SearchResult.Model -> List Html +viewSearchResults : Address Action -> Dict SearchResult.ResultId SearchResult.Model -> List Html viewSearchResults address results = results + |> Dict.values + |> List.sortBy (.stars >> negate) |> filterResults - |> List.map (lazy2 viewSearchResult address) + |> List.map (lazy3 SearchResult.view address DeleteById) -filterResults : List Component.SearchResult.Model -> List Component.SearchResult.Model +filterResults : List SearchResult.Model -> List SearchResult.Model filterResults results = case results of [] -> [] - first :: rest -> - if first.stars > 0 then - first :: (filterResults rest) + result :: rest -> + if result.stars > 0 then + result :: (filterResults rest) else filterResults rest @@ -102,18 +95,11 @@ defaultValue str = property "defaultValue" (Json.Encode.string str) -viewSearchResult : Address Action -> Component.SearchResult.Model -> Html -viewSearchResult address result = - Component.SearchResult.view - (Signal.forwardTo address (UpdateSearchResult result.id)) - (Debug.log "rendering result..." result) - - type Action = Search | SetQuery String - | SetResults (List Component.SearchResult.Model) - | UpdateSearchResult ResultId Component.SearchResult.Action + | DeleteById SearchResult.ResultId + | SetResults (List SearchResult.Model) update : Action -> Model -> ( Model, Effects Action ) @@ -126,32 +112,18 @@ update action model = ( { model | query = query }, Effects.none ) SetResults results -> + let + resultsById : Dict SearchResult.ResultId SearchResult.Model + resultsById = + results + |> List.map (\result -> ( result.id, result )) + |> Dict.fromList + in + ( { model | results = resultsById }, Effects.none ) + + DeleteById id -> let newModel = - { model | results = results } + { model | results = Dict.remove id model.results } in ( newModel, Effects.none ) - - UpdateSearchResult id childAction -> - let - updateResult childModel = - if childModel.id == id then - let - ( newChildModel, childEffects ) = - Component.SearchResult.update childAction childModel - in - ( newChildModel - , Effects.map (UpdateSearchResult id) childEffects - ) - else - ( childModel, Effects.none ) - - ( newResults, effects ) = - model.results - |> List.map updateResult - |> List.unzip - - newModel = - { model | results = newResults } - in - ( newModel, Effects.batch effects ) diff --git a/stages/11/ElmHub/Css.elm b/stages/11/ElmHub/Css.elm new file mode 100644 index 0000000..58b5769 --- /dev/null +++ b/stages/11/ElmHub/Css.elm @@ -0,0 +1,14 @@ +module ElmHub.Css (..) where + +import Css exposing (..) + + +css = + stylesheet + [ ((.) "content") + [ width (px 960) + , margin2 zero auto + , padding (px 30) + , fontFamilies [ "Helvetica", "Arial", "serif" ] + ] + ] diff --git a/stages/11/Main.elm b/stages/11/Main.elm index 5b8e88e..fa4bada 100644 --- a/stages/11/Main.elm +++ b/stages/11/Main.elm @@ -1,7 +1,7 @@ module Main (..) where import StartApp -import Component.ElmHub exposing (..) +import ElmHub exposing (..) import Effects exposing (Effects) import Task exposing (Task) import Html exposing (Html) diff --git a/stages/11/README.md b/stages/11/README.md index 76fe73f..432848f 100644 --- a/stages/11/README.md +++ b/stages/11/README.md @@ -1,4 +1,4 @@ -Stage 11 +Stage 12 ======== ## Installation @@ -16,10 +16,8 @@ to fail; in that case, just run `elm package install` again.) elm live Main.elm --open -- --output=elm.js ``` -## Running Tests +## Compiling CSS ```bash -cd test -elm package install -elm test TestRunner.elm +elm css Stylesheets.elm ``` diff --git a/stages/11/SearchResult.elm b/stages/11/SearchResult.elm new file mode 100644 index 0000000..daf012a --- /dev/null +++ b/stages/11/SearchResult.elm @@ -0,0 +1,44 @@ +module SearchResult (..) where + +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (..) +import Json.Decode exposing (Decoder, (:=)) +import Signal exposing (Address) +import Dict exposing (Dict) + + +type alias ResultId = + Int + + +type alias Model = + { id : ResultId + , name : String + , stars : Int + } + + +decoder : Decoder Model +decoder = + Json.Decode.object3 + Model + ("id" := Json.Decode.int) + ("full_name" := Json.Decode.string) + ("stargazers_count" := Json.Decode.int) + + +view : Address a -> (Int -> a) -> Model -> Html +view address delete 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 address (delete result.id) ] + [ text "X" ] + ] diff --git a/stages/12/css/Stylesheets.elm b/stages/11/Stylesheets.elm similarity index 65% rename from stages/12/css/Stylesheets.elm rename to stages/11/Stylesheets.elm index 460790c..5bd28a0 100644 --- a/stages/12/css/Stylesheets.elm +++ b/stages/11/Stylesheets.elm @@ -1,10 +1,10 @@ module Stylesheets (..) where import Css.File exposing (..) -import ElmHub +import ElmHub.Css port files : CssFileStructure port files = toFileStructure - [ ( "style.css", compile ElmHub.css ) ] + [ ( "style.css", compile ElmHub.Css.css ) ] diff --git a/stages/11/elm-package.json b/stages/11/elm-package.json index 5728b71..ea197b6 100644 --- a/stages/11/elm-package.json +++ b/stages/11/elm-package.json @@ -12,7 +12,8 @@ "evancz/elm-effects": "2.0.0 <= v < 3.0.0", "evancz/elm-html": "4.0.0 <= v < 5.0.0", "evancz/elm-http": "3.0.0 <= v < 4.0.0", - "evancz/start-app": "2.0.0 <= v < 3.0.0" + "evancz/start-app": "2.0.0 <= v < 3.0.0", + "rtfeldman/elm-css": "1.0.0 <= v < 2.0.0" }, "elm-version": "0.16.0 <= v < 0.17.0" } diff --git a/stages/11/style.css b/stages/11/style.css index 64c74d7..9d13aae 100644 --- a/stages/11/style.css +++ b/stages/11/style.css @@ -1,92 +1,6 @@ - .content { - width: 960px; - margin: 0 auto; - padding: 30px; - font-family: Helvetica, Arial, serif; -} - -header { - position: relative; - padding: 6px 12px; - height: 36px; - background-color: rgb(96, 181, 204); -} - -h1 { - color: white; - font-weight: normal; - margin: 0; -} - -.tagline { - color: #eee; - position: absolute; - right: 16px; - top: 12px; - font-size: 24px; - font-style: italic; -} - -.results { - list-style-image: url('http://img-cache.cdn.gaiaonline.com/76bd5c99d8f2236e9d3672510e933fdf/http://i278.photobucket.com/albums/kk81/d3m3nt3dpr3p/Tiny-Star-Icon.png'); - list-style-position: inside; - padding: 0; -} - -.results li { - font-size: 18px; - margin-bottom: 16px; -} - -.star-count { - font-weight: bold; - margin-right: 16px; -} - -a { - color: rgb(96, 181, 204); - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -.search-query { - padding: 8px; - font-size: 24px; - margin-bottom: 18px; - margin-top: 36px; -} - -.search-button { - padding: 8px 16px; - font-size: 24px; - color: white; - border: 1px solid #ccc; - background-color: rgb(96, 181, 204); - margin-left: 12px -} - -.search-button:hover { - color: rgb(96, 181, 204); - background-color: white; -} - -.hide-result { - background-color: transparent; - border: 0; - font-weight: bold; - font-size: 18px; - margin-left: 18px; - cursor: pointer; -} - -.hide-result:hover { - color: rgb(96, 181, 204); -} - -button:focus, input:focus { - outline: none; + width: 960px; + margin: 0 auto; + padding: 30px; + font-family: Helvetica, Arial, serif; } diff --git a/stages/12/Component/ElmHub.elm b/stages/12/Component/ElmHub.elm index fb9237f..e825e6d 100644 --- a/stages/12/Component/ElmHub.elm +++ b/stages/12/Component/ElmHub.elm @@ -82,21 +82,16 @@ viewSearchResults address results = filterResults : List Component.SearchResult.Model -> List Component.SearchResult.Model -filterResults = - filterResultsHelp [] - - -filterResultsHelp : List Component.SearchResult.Model -> List Component.SearchResult.Model -> List Component.SearchResult.Model -filterResultsHelp output results = +filterResults results = case results of [] -> - output + [] first :: rest -> if first.stars > 0 then - filterResultsHelp (first :: output) rest + first :: (filterResults rest) else - filterResultsHelp output rest + filterResults rest onInput address wrap = @@ -111,7 +106,7 @@ viewSearchResult : Address Action -> Component.SearchResult.Model -> Html viewSearchResult address result = Component.SearchResult.view (Signal.forwardTo address (UpdateSearchResult result.id)) - result + (Debug.log "rendering result..." result) type Action diff --git a/stages/12/Component/SearchResult.elm b/stages/12/Component/SearchResult.elm index 67d7d37..4dedbd3 100644 --- a/stages/12/Component/SearchResult.elm +++ b/stages/12/Component/SearchResult.elm @@ -26,12 +26,8 @@ type Action update : Action -> Model -> ( Model, Effects Action ) update action model = - case action of - Expand -> - ( { model | expanded = True }, Effects.none ) - - Collapse -> - ( { model | expanded = False }, Effects.none ) + -- TODO make expand and collapse work + ( model, Effects.none ) view : Address Action -> Model -> Html @@ -44,11 +40,13 @@ view address model = [ href ("https://github.com/" ++ model.name), target "_blank" ] [ text model.name ] , button - [ class "hide-result", onClick address Collapse ] + -- TODO when the user clicks, send a Collapse action + [ class "hide-result" ] [ text "X" ] ] else [ button - [ class "expand-result", onClick address Expand ] + -- TODO when the user clicks, send an Expand action + [ class "expand-result" ] [ text "Show" ] ] diff --git a/stages/12/ElmHub.elm b/stages/12/ElmHub.elm deleted file mode 100644 index e3ed2f3..0000000 --- a/stages/12/ElmHub.elm +++ /dev/null @@ -1,8 +0,0 @@ -module ElmHub (..) where - -import Css exposing (..) - - -css = - stylesheet - [ (.) "foo" [] ] diff --git a/stages/12/README.md b/stages/12/README.md index e98b73b..76fe73f 100644 --- a/stages/12/README.md +++ b/stages/12/README.md @@ -1,4 +1,4 @@ -Stage 12 +Stage 11 ======== ## Installation @@ -16,8 +16,10 @@ to fail; in that case, just run `elm package install` again.) elm live Main.elm --open -- --output=elm.js ``` -## Compiling CSS +## Running Tests ```bash -elm css css/Stylesheets.elm +cd test +elm package install +elm test TestRunner.elm ``` diff --git a/stages/12/Stylesheets.elm b/stages/12/Stylesheets.elm deleted file mode 100644 index 460790c..0000000 --- a/stages/12/Stylesheets.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Stylesheets (..) where - -import Css.File exposing (..) -import ElmHub - - -port files : CssFileStructure -port files = - toFileStructure - [ ( "style.css", compile ElmHub.css ) ] diff --git a/stages/12/elm-package.json b/stages/12/elm-package.json index ea197b6..5728b71 100644 --- a/stages/12/elm-package.json +++ b/stages/12/elm-package.json @@ -12,8 +12,7 @@ "evancz/elm-effects": "2.0.0 <= v < 3.0.0", "evancz/elm-html": "4.0.0 <= v < 5.0.0", "evancz/elm-http": "3.0.0 <= v < 4.0.0", - "evancz/start-app": "2.0.0 <= v < 3.0.0", - "rtfeldman/elm-css": "1.0.0 <= v < 2.0.0" + "evancz/start-app": "2.0.0 <= v < 3.0.0" }, "elm-version": "0.16.0 <= v < 0.17.0" } diff --git a/stages/12/style.css b/stages/12/style.css index 8b13789..64c74d7 100644 --- a/stages/12/style.css +++ b/stages/12/style.css @@ -1 +1,92 @@ +.content { + width: 960px; + margin: 0 auto; + padding: 30px; + font-family: Helvetica, Arial, serif; +} + +header { + position: relative; + padding: 6px 12px; + height: 36px; + background-color: rgb(96, 181, 204); +} + +h1 { + color: white; + font-weight: normal; + margin: 0; +} + +.tagline { + color: #eee; + position: absolute; + right: 16px; + top: 12px; + font-size: 24px; + font-style: italic; +} + +.results { + list-style-image: url('http://img-cache.cdn.gaiaonline.com/76bd5c99d8f2236e9d3672510e933fdf/http://i278.photobucket.com/albums/kk81/d3m3nt3dpr3p/Tiny-Star-Icon.png'); + list-style-position: inside; + padding: 0; +} + +.results li { + font-size: 18px; + margin-bottom: 16px; +} + +.star-count { + font-weight: bold; + margin-right: 16px; +} + +a { + color: rgb(96, 181, 204); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +.search-query { + padding: 8px; + font-size: 24px; + margin-bottom: 18px; + margin-top: 36px; +} + +.search-button { + padding: 8px 16px; + font-size: 24px; + color: white; + border: 1px solid #ccc; + background-color: rgb(96, 181, 204); + margin-left: 12px +} + +.search-button:hover { + color: rgb(96, 181, 204); + background-color: white; +} + +.hide-result { + background-color: transparent; + border: 0; + font-weight: bold; + font-size: 18px; + margin-left: 18px; + cursor: pointer; +} + +.hide-result:hover { + color: rgb(96, 181, 204); +} + +button:focus, input:focus { + outline: none; +}