2020-03-31 03:22:27 +00:00
|
|
|
module Main exposing (main)
|
2020-03-28 04:09:01 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
--exposing (UrlRequest(..))
|
|
|
|
|
|
|
|
import Browser
|
|
|
|
import Browser.Navigation
|
|
|
|
import ElasticSearch
|
2020-03-31 03:22:27 +00:00
|
|
|
import Html
|
|
|
|
exposing
|
|
|
|
( Html
|
2020-04-10 08:13:50 +00:00
|
|
|
, a
|
2020-03-31 03:22:27 +00:00
|
|
|
, div
|
2020-04-10 08:13:50 +00:00
|
|
|
, footer
|
2020-03-31 03:22:27 +00:00
|
|
|
, header
|
2020-04-10 08:13:50 +00:00
|
|
|
, img
|
2020-03-31 03:22:27 +00:00
|
|
|
, li
|
|
|
|
, text
|
|
|
|
, ul
|
|
|
|
)
|
|
|
|
import Html.Attributes
|
|
|
|
exposing
|
|
|
|
( class
|
2020-05-08 13:24:58 +00:00
|
|
|
, classList
|
2020-04-10 08:13:50 +00:00
|
|
|
, href
|
|
|
|
, src
|
2020-03-31 03:22:27 +00:00
|
|
|
)
|
2020-05-08 13:24:58 +00:00
|
|
|
import Page.Home
|
|
|
|
import Page.Options
|
|
|
|
import Page.Packages
|
|
|
|
import RemoteData
|
|
|
|
import Route
|
|
|
|
import Url
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- MODEL
|
|
|
|
|
|
|
|
|
2020-04-07 05:05:50 +00:00
|
|
|
type alias Flags =
|
|
|
|
{ elasticsearchUrl : String
|
|
|
|
, elasticsearchUsername : String
|
|
|
|
, elasticsearchPassword : String
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-28 04:09:01 +00:00
|
|
|
type alias Model =
|
2020-05-08 13:24:58 +00:00
|
|
|
{ navKey : Browser.Navigation.Key
|
|
|
|
, url : Url.Url
|
|
|
|
, elasticsearch : ElasticSearch.Options
|
2020-03-28 04:09:01 +00:00
|
|
|
, page : Page
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Page
|
2020-05-08 13:24:58 +00:00
|
|
|
= NotFound
|
|
|
|
| Home Page.Home.Model
|
|
|
|
| Packages Page.Packages.Model
|
|
|
|
| Options Page.Options.Model
|
|
|
|
|
|
|
|
|
|
|
|
init :
|
|
|
|
Flags
|
|
|
|
-> Url.Url
|
|
|
|
-> Browser.Navigation.Key
|
|
|
|
-> ( Model, Cmd Msg )
|
|
|
|
init flags url navKey =
|
2020-04-10 08:13:50 +00:00
|
|
|
let
|
|
|
|
model =
|
2020-05-08 13:24:58 +00:00
|
|
|
{ navKey = navKey
|
|
|
|
, url = url
|
|
|
|
, elasticsearch =
|
|
|
|
ElasticSearch.Options
|
|
|
|
flags.elasticsearchUrl
|
|
|
|
flags.elasticsearchUsername
|
|
|
|
flags.elasticsearchPassword
|
|
|
|
, page = NotFound
|
2020-04-10 08:13:50 +00:00
|
|
|
}
|
|
|
|
in
|
2020-05-08 13:24:58 +00:00
|
|
|
changeRouteTo model url
|
2020-04-10 08:13:50 +00:00
|
|
|
|
|
|
|
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
-- UPDATE
|
|
|
|
|
|
|
|
|
|
|
|
type Msg
|
2020-05-08 13:24:58 +00:00
|
|
|
= ChangedUrl Url.Url
|
|
|
|
| ClickedLink Browser.UrlRequest
|
|
|
|
| HomeMsg Page.Home.Msg
|
|
|
|
| PackagesMsg Page.Packages.Msg
|
|
|
|
| OptionsMsg Page.Options.Msg
|
|
|
|
|
|
|
|
|
|
|
|
updateWith :
|
|
|
|
(subModel -> Page)
|
|
|
|
-> (subMsg -> Msg)
|
|
|
|
-> Model
|
|
|
|
-> ( subModel, Cmd subMsg )
|
|
|
|
-> ( Model, Cmd Msg )
|
|
|
|
updateWith toPage toMsg model ( subModel, subCmd ) =
|
|
|
|
( { model | page = toPage subModel }
|
|
|
|
, Cmd.map toMsg subCmd
|
|
|
|
)
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
submitQuery :
|
|
|
|
Model
|
|
|
|
-> ( Model, Cmd Msg )
|
|
|
|
-> ( Model, Cmd Msg )
|
|
|
|
submitQuery old ( new, cmd ) =
|
|
|
|
let
|
|
|
|
triggerSearch oldModel newModel msg makeRequest =
|
|
|
|
if (oldModel.query == newModel.query) && RemoteData.isSuccess oldModel.result then
|
|
|
|
( new, cmd )
|
|
|
|
|
|
|
|
else
|
|
|
|
( new
|
|
|
|
, Cmd.batch
|
|
|
|
[ cmd
|
2020-05-08 14:56:14 +00:00
|
|
|
, makeRequest
|
2020-05-08 13:24:58 +00:00
|
|
|
new.elasticsearch
|
|
|
|
(Maybe.withDefault "" newModel.query)
|
2020-05-08 14:56:14 +00:00
|
|
|
|> Cmd.map msg
|
2020-05-08 13:24:58 +00:00
|
|
|
]
|
|
|
|
)
|
|
|
|
in
|
|
|
|
case ( old.page, new.page ) of
|
|
|
|
( Packages oldModel, Packages newModel ) ->
|
|
|
|
triggerSearch oldModel newModel PackagesMsg Page.Packages.makeRequest
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
( Options oldModel, Options newModel ) ->
|
|
|
|
triggerSearch oldModel newModel OptionsMsg Page.Options.makeRequest
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
( _, _ ) ->
|
|
|
|
( new, cmd )
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
changeRouteTo : Model -> Url.Url -> ( Model, Cmd Msg )
|
|
|
|
changeRouteTo model url =
|
|
|
|
let
|
|
|
|
newModel =
|
|
|
|
{ model | url = url }
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
maybeRoute =
|
|
|
|
Route.fromUrl url
|
|
|
|
in
|
|
|
|
case maybeRoute of
|
|
|
|
Nothing ->
|
|
|
|
( { newModel
|
|
|
|
| page = NotFound
|
|
|
|
}
|
|
|
|
, Cmd.none
|
|
|
|
)
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
Just Route.NotFound ->
|
|
|
|
( { newModel
|
|
|
|
| page = NotFound
|
|
|
|
}
|
|
|
|
, Cmd.none
|
|
|
|
)
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
Just Route.Home ->
|
|
|
|
-- Always redirect to /packages until we have something to show
|
|
|
|
-- on the home page
|
|
|
|
( newModel, Browser.Navigation.pushUrl newModel.navKey "/packages" )
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
Just (Route.Packages query showDetailsFor) ->
|
|
|
|
Page.Packages.init query showDetailsFor
|
|
|
|
|> updateWith Packages PackagesMsg newModel
|
|
|
|
|> submitQuery newModel
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
Just (Route.Options query showDetailsFor) ->
|
|
|
|
Page.Options.init query showDetailsFor
|
|
|
|
|> updateWith Options OptionsMsg newModel
|
|
|
|
|> submitQuery newModel
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
|
|
|
2020-03-28 04:09:01 +00:00
|
|
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
2020-05-08 13:24:58 +00:00
|
|
|
update msg model =
|
|
|
|
case ( msg, model.page ) of
|
|
|
|
( ClickedLink urlRequest, _ ) ->
|
|
|
|
case urlRequest of
|
|
|
|
Browser.Internal url ->
|
2020-03-31 00:59:06 +00:00
|
|
|
( model
|
2020-05-08 13:24:58 +00:00
|
|
|
, Browser.Navigation.pushUrl model.navKey <| Url.toString url
|
2020-03-31 00:59:06 +00:00
|
|
|
)
|
2020-03-28 04:09:01 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
Browser.External href ->
|
2020-04-10 08:13:50 +00:00
|
|
|
( model
|
2020-05-08 13:24:58 +00:00
|
|
|
, Browser.Navigation.load href
|
2020-04-10 08:13:50 +00:00
|
|
|
)
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
( ChangedUrl url, _ ) ->
|
|
|
|
changeRouteTo model url
|
2020-04-10 08:13:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
( HomeMsg subMsg, Home subModel ) ->
|
|
|
|
Page.Home.update subMsg subModel
|
|
|
|
|> updateWith Home HomeMsg model
|
|
|
|
|
|
|
|
( PackagesMsg subMsg, Packages subModel ) ->
|
|
|
|
Page.Packages.update model.navKey subMsg subModel
|
|
|
|
|> updateWith Packages PackagesMsg model
|
|
|
|
|
|
|
|
( OptionsMsg subMsg, Options subModel ) ->
|
|
|
|
Page.Options.update model.navKey subMsg subModel
|
|
|
|
|> updateWith Options OptionsMsg model
|
|
|
|
|
|
|
|
( _, _ ) ->
|
|
|
|
-- Disregard messages that arrived for the wrong page.
|
|
|
|
( model, Cmd.none )
|
2020-04-10 08:13:50 +00:00
|
|
|
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
-- VIEW
|
|
|
|
|
|
|
|
|
|
|
|
view : Model -> Html Msg
|
|
|
|
view model =
|
2020-04-10 08:13:50 +00:00
|
|
|
div []
|
2020-03-28 04:09:01 +00:00
|
|
|
[ header []
|
2020-04-10 08:13:50 +00:00
|
|
|
[ div [ class "navbar navbar-static-top" ]
|
|
|
|
[ div [ class "navbar-inner" ]
|
|
|
|
[ div [ class "container" ]
|
|
|
|
[ a [ class "brand", href "https://search.nixos.org" ]
|
|
|
|
[ img [ src "https://nixos.org/logo/nix-wiki.png", class "logo" ] []
|
|
|
|
]
|
2020-05-08 13:24:58 +00:00
|
|
|
, viewNavigation model.url
|
2020-04-10 08:13:50 +00:00
|
|
|
]
|
|
|
|
]
|
|
|
|
]
|
|
|
|
]
|
|
|
|
, div [ class "container main" ]
|
2020-05-08 13:24:58 +00:00
|
|
|
[ viewPage model
|
2020-04-10 08:13:50 +00:00
|
|
|
, footer [] []
|
2020-03-28 04:09:01 +00:00
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
viewNavigation : Url.Url -> Html Msg
|
|
|
|
viewNavigation url =
|
|
|
|
ul [ class "nav" ]
|
|
|
|
(List.map
|
|
|
|
(viewNavigationItem url)
|
|
|
|
[ ( "/packages", "Packages" )
|
|
|
|
, ( "/options", "Options" )
|
2020-03-28 04:09:01 +00:00
|
|
|
]
|
2020-05-08 13:24:58 +00:00
|
|
|
)
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
viewNavigationItem :
|
|
|
|
Url.Url
|
|
|
|
-> ( String, String )
|
|
|
|
-> Html Msg
|
|
|
|
viewNavigationItem url ( path, title ) =
|
|
|
|
li
|
|
|
|
[ classList [ ( "active", path == url.path ) ] ]
|
|
|
|
[ a [ href path ] [ text title ] ]
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-04-10 09:04:03 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
viewPage : Model -> Html Msg
|
|
|
|
viewPage model =
|
|
|
|
case model.page of
|
|
|
|
NotFound ->
|
|
|
|
div [] [ text "Not Found" ]
|
2020-03-28 04:09:01 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
Home _ ->
|
|
|
|
div [] [ text "Welcome" ]
|
2020-03-28 04:09:01 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
Packages packagesModel ->
|
|
|
|
Html.map (\m -> PackagesMsg m) <| Page.Packages.view packagesModel
|
2020-04-10 08:13:50 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
Options optionsModel ->
|
|
|
|
Html.map (\m -> OptionsMsg m) <| Page.Options.view optionsModel
|
2020-04-07 05:05:50 +00:00
|
|
|
|
2020-03-31 03:22:27 +00:00
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
|
|
|
-- SUBSCRIPTIONS
|
|
|
|
|
|
|
|
|
|
|
|
subscriptions : Model -> Sub Msg
|
|
|
|
subscriptions _ =
|
|
|
|
Sub.none
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- MAIN
|
|
|
|
|
|
|
|
|
2020-04-07 05:05:50 +00:00
|
|
|
main : Program Flags Model Msg
|
2020-03-28 04:09:01 +00:00
|
|
|
main =
|
|
|
|
Browser.application
|
|
|
|
{ init = init
|
2020-05-08 13:24:58 +00:00
|
|
|
, onUrlRequest = ClickedLink
|
|
|
|
, onUrlChange = ChangedUrl
|
|
|
|
, subscriptions = subscriptions
|
2020-03-28 04:09:01 +00:00
|
|
|
, 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 ]
|
|
|
|
}
|
|
|
|
}
|