aux-search/src/Main.elm

287 lines
6.3 KiB
Elm
Raw Normal View History

module Main exposing (main)
2020-03-28 04:09:01 +00:00
import Browser exposing (UrlRequest(..))
import Browser.Navigation as Nav exposing (Key)
import Html
exposing
( Html
, button
, div
, h1
, header
, input
, li
, text
, ul
)
import Html.Attributes
exposing
( class
, type_
, value
)
import Html.Events
exposing
( onClick
, onInput
)
2020-03-28 04:09:01 +00:00
import Http exposing (Error(..))
import Url exposing (Url)
import Url.Parser as UrlParser
exposing
( (<?>)
, Parser
)
2020-03-31 00:59:06 +00:00
import Url.Parser.Query as UrlParserQuery
2020-03-28 04:09:01 +00:00
-- ---------------------------
-- MODEL
-- ---------------------------
type alias Model =
{ key : Key
, page : Page
}
2020-03-31 00:59:06 +00:00
type alias SearchModel =
{ query : String
, results : List SearchResult
2020-03-31 00:59:06 +00:00
}
2020-03-28 04:09:01 +00:00
type Page
2020-03-31 00:59:06 +00:00
= Search SearchModel
type SearchResult
= Package SearchResultPackage
| Option SearchResultOption
type alias SearchResultPackage =
{ attribute_name : String
, name : String
, version : String
, description : String
, longDescription : String
, license : List SearchResultPackageLicense
, position : String
, homepage : String
}
type alias SearchResultOption =
{ option_name : String
, description : String
, type_ : String
, default : String
, example : String
, source : String
}
type alias SearchResultPackageLicense =
{ fullName : String
, url : String
}
type alias SearchResultPackageMaintainer =
{ name : String
, email : String
, github : String
}
emptySearch : Page
2020-03-31 00:59:06 +00:00
emptySearch =
Search { query = "", results = [] }
init : Int -> Url -> Key -> ( Model, Cmd Msg )
init _ url key =
2020-03-31 00:59:06 +00:00
( { key = key
, page = UrlParser.parse urlParser url |> Maybe.withDefault emptySearch
}
, Cmd.none
)
2020-03-28 04:09:01 +00:00
-- ---------------------------
-- URL Parsing and Routing
-- ---------------------------
handleUrlRequest : Key -> UrlRequest -> Cmd msg
handleUrlRequest key urlRequest =
case urlRequest of
Internal url ->
Nav.pushUrl key (Url.toString url)
External url ->
Nav.load url
urlParser : Parser (Page -> msg) msg
urlParser =
UrlParser.oneOf
2020-03-31 00:59:06 +00:00
[ UrlParser.map
(\q ->
Search
{ query = q |> Maybe.withDefault ""
, results = []
}
)
(UrlParser.s "search" <?> UrlParserQuery.string "query")
2020-03-28 04:09:01 +00:00
]
-- ---------------------------
-- UPDATE
-- ---------------------------
type Msg
= OnUrlRequest UrlRequest
| OnUrlChange Url
2020-03-31 00:59:06 +00:00
| SearchPageInput String
| SearchQuerySubmit
initPage : Page -> Cmd Msg
initPage page =
case page of
Search _ ->
2020-03-31 00:59:06 +00:00
Cmd.none
2020-03-28 04:09:01 +00:00
update : Msg -> Model -> ( Model, Cmd Msg )
update message model =
case message of
OnUrlRequest urlRequest ->
( model, handleUrlRequest model.key urlRequest )
OnUrlChange url ->
let
2020-03-31 00:59:06 +00:00
newModel =
{ model | page = UrlParser.parse urlParser url |> Maybe.withDefault model.page }
packages =
[ Package
{ attribute_name = "firefox"
, name = "firefox"
, version = "74.0"
, description = "A web browser built from Firefox source tree (with plugins: )"
, longDescription = ""
, license = [ { fullName = "Mozilla Public License 2.0", url = "http://spdx.org/licenses/MPL-2.0.html" } ]
, position = ""
, homepage = "http://www.mozilla.com/en-US/firefox/"
}
]
newPage =
2020-03-31 00:59:06 +00:00
case newModel.page of
Search searchModel ->
Search
{ searchModel
| results =
if searchModel.query == "" then
[]
else
packages
2020-03-31 00:59:06 +00:00
}
in
( { newModel | page = newPage }
, initPage newPage
2020-03-28 04:09:01 +00:00
)
2020-03-31 00:59:06 +00:00
SearchPageInput query ->
( { model
| page =
case model.page of
Search searchModel ->
Search { searchModel | query = query }
}
, Cmd.none
)
2020-03-28 04:09:01 +00:00
2020-03-31 00:59:06 +00:00
SearchQuerySubmit ->
case model.page of
Search searchModel ->
( model
, Nav.pushUrl model.key <| "/search?query=" ++ searchModel.query
)
2020-03-28 04:09:01 +00:00
-- ---------------------------
-- VIEW
-- ---------------------------
view : Model -> Html Msg
view model =
div [ class "container" ]
[ header []
2020-03-31 00:59:06 +00:00
[ h1 [] [ text "NixOS Search" ]
2020-03-28 04:09:01 +00:00
]
, case model.page of
2020-03-31 00:59:06 +00:00
Search searchModel ->
searchPage searchModel
2020-03-28 04:09:01 +00:00
]
2020-03-31 00:59:06 +00:00
searchPage : SearchModel -> Html Msg
searchPage model =
div []
[ div []
[ input
[ type_ "text"
, onInput SearchPageInput
, value model.query
]
[]
, button [ onClick SearchQuerySubmit ] [ text "Search" ]
2020-03-28 04:09:01 +00:00
]
2020-03-31 00:59:06 +00:00
, ul [] (List.map searchPageResult model.results)
2020-03-28 04:09:01 +00:00
]
searchPageResult : SearchResult -> Html Msg
searchPageResult result =
case result of
Package package ->
li [] [ text package.attribute_name ]
Option option ->
li [] [ text option.option_name ]
2020-03-28 04:09:01 +00:00
-- ---------------------------
-- MAIN
-- ---------------------------
main : Program Int Model Msg
main =
Browser.application
{ init = init
, update = update
, view =
\m ->
2020-03-31 00:59:06 +00:00
{ title = "NixOS Search"
2020-03-28 04:09:01 +00:00
, body = [ view m ]
}
, subscriptions = \_ -> Sub.none
, onUrlRequest = OnUrlRequest
, onUrlChange = OnUrlChange
}