Update a ton of things

This commit is contained in:
Richard Feldman
2016-06-24 17:40:54 -07:00
parent 908ca61c77
commit c8e9a117f5
56 changed files with 1023 additions and 1466 deletions

View File

@@ -1,4 +1,4 @@
module ElmHub (..) where
module ElmHub exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
@@ -7,133 +7,118 @@ import Html.Lazy exposing (..)
import Http
import Auth
import Task exposing (Task)
import Effects exposing (Effects)
import Json.Decode exposing (Decoder, (:=))
import Json.Decode exposing (Decoder)
import Json.Encode
import Signal exposing (Address)
import Dict exposing (Dict)
import SearchResult exposing (ResultId)
searchFeed : String -> Task x Action
searchFeed : String -> Task x Msg
searchFeed query =
let
-- See https://developer.github.com/v3/search/#example for how to customize!
url =
"https://api.github.com/search/repositories?access_token="
++ Auth.token
++ "&q="
++ query
++ "+language:elm&sort=stars&order=desc"
let
-- See https://developer.github.com/v3/search/#example for how to customize!
url =
"https://api.github.com/search/repositories?access_token="
++ Auth.token
++ "&q="
++ query
++ "+language:elm&sort=stars&order=desc"
task =
Http.get responseDecoder url
|> Task.map SetResults
in
Task.onError task (\_ -> Task.succeed (SetResults []))
task =
Http.get responseDecoder url
|> Task.map SetResults
in
Task.onError task (\_ -> Task.succeed (SetResults []))
responseDecoder : Decoder (List SearchResult.Model)
responseDecoder =
"items" := Json.Decode.list SearchResult.decoder
"items" := Json.Decode.list SearchResult.decoder
type alias Model =
{ query : String
, results : Dict SearchResult.ResultId SearchResult.Model
}
{ query : String
, results : Dict SearchResult.ResultId SearchResult.Model
}
initialModel : Model
initialModel =
{ query = "tutorial"
, results = Dict.empty
}
{ query = "tutorial"
, results = Dict.empty
}
view : Address Action -> Model -> Html
view address model =
div
[ class "content" ]
[ header
[]
[ h1 [] [ text "ElmHub" ]
, span [ class "tagline" ] [ text "Like GitHub, but for Elm things." ]
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" ]
, ul [ class "results" ] (viewSearchResults model.results)
]
, input [ class "search-query", onInput address SetQuery, defaultValue model.query ] []
, button [ class "search-button", onClick address Search ] [ text "Search" ]
, ul
[ class "results" ]
(viewSearchResults address model.results)
]
viewSearchResults : Address Action -> Dict ResultId SearchResult.Model -> List Html
viewSearchResults address results =
results
|> Dict.values
|> List.sortBy (.stars >> negate)
|> List.map (viewSearchResult address)
viewSearchResults : Dict ResultId SearchResult.Model -> List Html
viewSearchResults results =
results
|> Dict.values
|> List.sortBy (.stars >> negate)
|> List.map (viewSearchResult address)
viewSearchResult : Address Action -> SearchResult.Model -> Html
viewSearchResult address result =
SearchResult.view
(Signal.forwardTo address (UpdateSearchResult result.id))
result
viewSearchResult result =
SearchResult.view (Signal.forwardTo address (UpdateSearchResult result.id))
result
onInput address wrap =
on "input" targetValue (\val -> Signal.message address (wrap val))
type Msg
= Search
| SetQuery String
| SetResults (List SearchResult.Model)
| UpdateSearchResult ResultId SearchResult.Action
defaultValue str =
property "defaultValue" (Json.Encode.string str)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Search ->
( model, searchFeed model.query )
SetQuery query ->
( { model | query = query }, Cmd.none )
type Action
= Search
| SetQuery String
| SetResults (List SearchResult.Model)
| UpdateSearchResult ResultId SearchResult.Action
update : Action -> Model -> ( Model, Effects Action )
update action model =
case action of
Search ->
( model, Effects.task (searchFeed model.query) )
SetQuery query ->
( { 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 )
UpdateSearchResult id childAction ->
let
updated =
model.results
|> Dict.get id
|> Maybe.map (SearchResult.update childAction)
in
case updated of
Nothing ->
( model, Effects.none )
Just ( newChildModel, childEffects ) ->
SetResults results ->
let
effects =
Effects.map (UpdateSearchResult id) childEffects
newResults =
Dict.insert id newChildModel model.results
resultsById : Dict SearchResult.ResultId SearchResult.Model
resultsById =
results
|> List.map (\result -> ( result.id, result ))
|> Dict.fromList
in
( { model | results = newResults }, effects )
( { model | results = resultsById }, Cmd.none )
UpdateSearchResult id childAction ->
let
updated =
model.results
|> Dict.get id
|> Maybe.map (SearchResult.update childAction)
in
case updated of
Nothing ->
( model, Cmd.none )
Just ( newChildModel, childEffects ) ->
let
effects =
Effects.map (UpdateSearchResult id) childEffects
newResults =
Dict.insert id newChildModel model.results
in
( { model | results = newResults }, effects )

View File

@@ -1,27 +1,13 @@
module Main (..) where
module Main exposing (..)
import StartApp
import ElmHub exposing (..)
import Effects exposing (Effects)
import Task exposing (Task)
import Html exposing (Html)
main : Signal Html
main : Program Never
main =
app.html
app : StartApp.App Model
app =
StartApp.start
{ view = view
, update = update
, init = ( initialModel, Effects.task (searchFeed initialModel.query) )
, inputs = []
}
port tasks : Signal (Task Effects.Never ())
port tasks =
app.tasks
Html.App.program
{ view = view
, update = update
, init = ( initialModel, searchFeed initialModel.query )
, inputs = []
}

View File

@@ -4,16 +4,16 @@ Part 13
## Installation
```bash
elm package install
elm-package install
```
(Answer `y` at the prompt. In rare cases a known issue can cause the download
to fail; in that case, just run `elm package install` again.)
to fail; in that case, just run `elm-package install` again.)
## Building
```bash
elm live Main.elm --open -- --output=elm.js
elm-live Main.elm --open -- --output=elm.js
```
## Compiling CSS

View File

@@ -1,65 +1,59 @@
module SearchResult (..) where
module SearchResult exposing (..)
import Html exposing (..)
import Html.Attributes exposing (class, target, href, property)
import Html.Attributes exposing (class, target, href, property, defaultValue)
import Html.Events exposing (..)
import Signal exposing (Address)
import Effects exposing (Effects)
import Json.Decode exposing (Decoder, (:=))
import Json.Decode exposing (Decoder)
import Json.Decode.Pipeline exposing (..)
type alias Model =
{ id : Int
, name : String
, stars : Int
, expanded : Bool
}
{ id : Int
, name : String
, stars : Int
, expanded : Bool
}
type alias ResultId =
Int
Int
type Action
= Expand
| Collapse
type Msg
= Expand
| Collapse
decoder : Decoder Model
decoder =
decode Model
|> required "id" Json.Decode.int
|> required "full_name" Json.Decode.string
|> required "stargazers_count" Json.Decode.int
|> hardcoded True
decode Model
|> required "id" Json.Decode.int
|> required "full_name" Json.Decode.string
|> required "stargazers_count" Json.Decode.int
|> hardcoded True
update : Action -> Model -> ( Model, Effects Action )
update action model =
case action of
Expand ->
( { model | expanded = True }, Effects.none )
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Expand ->
( { model | expanded = True }, Cmd.none )
Collapse ->
( { model | expanded = False }, Effects.none )
Collapse ->
( { model | expanded = False }, Cmd.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
[ class "hide-result", onClick address Collapse ]
[ text "X" ]
]
else
[ button
[ class "expand-result", onClick address Expand ]
[ text "Show" ]
]
view : Model -> Html Msg
view 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 [ class "hide-result", onClick Collapse ]
[ text "X" ]
]
else
[ button [ class "expand-result", onClick Expand ]
[ text "Show" ]
]

View File

@@ -10,11 +10,10 @@
"exposed-modules": [],
"dependencies": {
"NoRedInk/elm-decode-pipeline": "1.0.0 <= v < 2.0.0",
"elm-lang/core": "3.0.0 <= v < 4.0.0",
"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"
"elm-lang/core": "4.0.1 <= v < 5.0.0",
"elm-lang/html": "1.0.0 <= v < 2.0.0",
"rtfeldman/elm-css": "1.0.0 <= v < 2.0.0",
"evancz/elm-http": "3.0.1 <= v < 4.0.0"
},
"elm-version": "0.16.0 <= v < 0.17.0"
"elm-version": "0.17.0 <= v < 0.18.0"
}

View File

@@ -10,12 +10,10 @@
"exposed-modules": [],
"dependencies": {
"NoRedInk/elm-decode-pipeline": "1.0.0 <= v < 2.0.0",
"elm-lang/core": "3.0.0 <= v < 4.0.0",
"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",
"elm-lang/core": "4.0.1 <= v < 5.0.0",
"elm-lang/html": "1.0.0 <= v < 2.0.0",
"rtfeldman/elm-css": "1.0.0 <= v < 2.0.0",
"evancz/start-app": "2.0.0 <= v < 3.0.0"
"evancz/elm-http": "3.0.1 <= v < 4.0.0"
},
"elm-version": "0.16.0 <= v < 0.17.0"
"elm-version": "0.17.0 <= v < 0.18.0"
}

View File

@@ -9,13 +9,11 @@
],
"exposed-modules": [],
"dependencies": {
"deadfoxygrandpa/elm-test": "3.1.1 <= v < 4.0.0",
"elm-lang/core": "3.0.0 <= v < 4.0.0",
"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",
"laszlopandy/elm-console": "1.0.3 <= v < 2.0.0"
"NoRedInk/elm-decode-pipeline": "1.0.0 <= v < 2.0.0",
"elm-lang/core": "4.0.1 <= v < 5.0.0",
"elm-lang/html": "1.0.0 <= v < 2.0.0",
"rtfeldman/elm-css": "1.0.0 <= v < 2.0.0",
"evancz/elm-http": "3.0.1 <= v < 4.0.0"
},
"elm-version": "0.16.0 <= v < 0.17.0"
"elm-version": "0.17.0 <= v < 0.18.0"
}