140 lines
3.9 KiB
Elm
140 lines
3.9 KiB
Elm
port module Search exposing (..)
|
|
|
|
import Html exposing (..)
|
|
import Html.Attributes exposing (class, target, href, defaultValue, type', checked, placeholder, value)
|
|
import Html.Events exposing (..)
|
|
import Json.Decode exposing (Decoder)
|
|
import Auth
|
|
import String
|
|
|
|
|
|
port githubSearch : String -> Cmd msg
|
|
|
|
|
|
type alias Model =
|
|
{ query : String
|
|
, sort : String
|
|
, ascending : Bool
|
|
, searchInDescription : Bool
|
|
, userFilter : String
|
|
}
|
|
|
|
|
|
type Msg
|
|
= SetQuery String
|
|
| SetSort String
|
|
| SetAscending Bool
|
|
| SetSearchInDescription Bool
|
|
| SetUserFilter String
|
|
| Search
|
|
|
|
|
|
init : ( Model, Cmd Msg )
|
|
init =
|
|
( initialModel, githubSearch (getQueryString initialModel) )
|
|
|
|
|
|
initialModel : Model
|
|
initialModel =
|
|
{ query = "tutorial"
|
|
, sort = "stars"
|
|
, ascending = False
|
|
, searchInDescription = True
|
|
, userFilter = ""
|
|
}
|
|
|
|
|
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
update msg model =
|
|
case msg of
|
|
Search ->
|
|
-- TODO instead of Cmd.none, run this:
|
|
-- githubSearch (getQueryString model)
|
|
( model, Cmd.none )
|
|
|
|
SetQuery query ->
|
|
( { model | query = query }, Cmd.none )
|
|
|
|
SetSort sort ->
|
|
( { model | sort = sort }, Cmd.none )
|
|
|
|
SetAscending ascending ->
|
|
( { model | ascending = ascending }, Cmd.none )
|
|
|
|
SetSearchInDescription searchInDescription ->
|
|
( { model | searchInDescription = searchInDescription }, Cmd.none )
|
|
|
|
SetUserFilter userFilter ->
|
|
( { model | userFilter = userFilter }, Cmd.none )
|
|
|
|
|
|
view : Model -> Html Msg
|
|
view model =
|
|
div [ class "search" ]
|
|
[ div [ class "search-options" ]
|
|
[ div [ class "search-option" ]
|
|
[ label [ class "top-label" ] [ text "Sort by" ]
|
|
, select [ onChange SetSort, value model.sort ]
|
|
[ option [ value "stars" ] [ text "Stars" ]
|
|
, option [ value "forks" ] [ text "Forks" ]
|
|
, option [ value "updated" ] [ text "Updated" ]
|
|
]
|
|
]
|
|
, div [ class "search-option" ]
|
|
[ label [ class "top-label" ] [ text "Owned by" ]
|
|
, input
|
|
[ type' "text"
|
|
, placeholder "Enter a username"
|
|
, defaultValue model.userFilter
|
|
, onInput SetUserFilter
|
|
]
|
|
[]
|
|
]
|
|
, label [ class "search-option" ]
|
|
[ input [ type' "checkbox", checked model.ascending, onCheck SetAscending ] []
|
|
, text "Sort ascending"
|
|
]
|
|
, label [ class "search-option" ]
|
|
[ input [ type' "checkbox", checked model.searchInDescription, onCheck SetSearchInDescription ] []
|
|
, text "Search in description"
|
|
]
|
|
]
|
|
, div [ class "search-input" ]
|
|
[ input [ class "search-query", onInput SetQuery, defaultValue model.query ] []
|
|
, button [ class "search-button", onClick Search ] [ text "Search" ]
|
|
]
|
|
]
|
|
|
|
|
|
onChange : (String -> msg) -> Attribute msg
|
|
onChange toMsg =
|
|
on "change" (Json.Decode.map toMsg Html.Events.targetValue)
|
|
|
|
|
|
getQueryString : Model -> String
|
|
getQueryString model =
|
|
-- See https://developer.github.com/v3/search/#example for how to customize!
|
|
"access_token="
|
|
++ Auth.token
|
|
++ "&q="
|
|
++ model.query
|
|
++ (if model.searchInDescription then
|
|
"+in:name,description"
|
|
else
|
|
"+in:name"
|
|
)
|
|
++ "+language:elm"
|
|
++ (if String.isEmpty model.userFilter then
|
|
""
|
|
else
|
|
"+user:" ++ model.userFilter
|
|
)
|
|
++ "&sort="
|
|
++ model.sort
|
|
++ "&order="
|
|
++ (if model.ascending then
|
|
"asc"
|
|
else
|
|
"desc"
|
|
)
|