aux-search/src/Main.elm
Andreas Rammhold e9bdeae3e2
Remove the defunct "burger menu" and always expand the navigation (#273)
I commonly run into a situation where the burger menu button is being
showed to me but it broke some time ago and doesn't expand the menu
anymore.

Since the snipped was probably mostly 1:1 translated from the old
nixos.org page (where we had more links than just the three we have now)
we can probably just remove it now. It is a net win as the feature was
broken and at least now you can use the website on mobile again.
2021-01-25 17:52:12 +01:00

417 lines
11 KiB
Elm
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module Main exposing (main)
import Browser
import Browser.Navigation
import Html
exposing
( Html
, a
, button
, div
, footer
, header
, img
, li
, span
, text
, ul
)
import Html.Attributes
exposing
( attribute
, class
, classList
, href
, id
, src
, type_
)
import Page.Home
import Page.Options
import Page.Packages
import Route
import Search
import Url
-- MODEL
type alias Flags =
{ elasticsearchMappingSchemaVersion : Int
, elasticsearchUrl : String
, elasticsearchUsername : String
, elasticsearchPassword : String
}
type alias Model =
{ navKey : Browser.Navigation.Key
, route : Route.Route
, elasticsearch : Search.Options
, page : Page
}
type Page
= 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 =
let
model =
{ navKey = navKey
, elasticsearch =
Search.Options
flags.elasticsearchMappingSchemaVersion
flags.elasticsearchUrl
flags.elasticsearchUsername
flags.elasticsearchPassword
, page = NotFound
, route = Route.Home
}
in
changeRouteTo model url
-- UPDATE
type Msg
= 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
)
attemptQuery : ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
attemptQuery (( model, _ ) as pair) =
let
-- We intentially throw away Cmd
-- because we don't want to perform any effects
-- in this cases where route itself doesn't change
noEffects =
Tuple.mapSecond (always Cmd.none)
submitQuery msg makeRequest searchModel =
Tuple.mapSecond
(\cmd ->
Cmd.batch
[ cmd
, Cmd.map msg <|
makeRequest
model.elasticsearch
searchModel.channel
(Maybe.withDefault "" searchModel.query)
searchModel.from
searchModel.size
searchModel.buckets
searchModel.sort
]
)
pair
in
case model.page of
Packages searchModel ->
if Search.shouldLoad searchModel then
submitQuery PackagesMsg Page.Packages.makeRequest searchModel
else
noEffects pair
Options searchModel ->
if Search.shouldLoad searchModel then
submitQuery OptionsMsg Page.Options.makeRequest searchModel
else
noEffects pair
_ ->
pair
pageMatch : Page -> Page -> Bool
pageMatch m1 m2 =
case ( m1, m2 ) of
( NotFound, NotFound ) ->
True
( Home _, Home _ ) ->
True
( Packages _, Packages _ ) ->
True
( Options _, Options _ ) ->
True
_ ->
False
changeRouteTo :
Model
-> Url.Url
-> ( Model, Cmd Msg )
changeRouteTo currentModel url =
case Route.fromUrl url of
Nothing ->
( { currentModel | page = NotFound }
, Cmd.none
)
Just route ->
let
model =
{ currentModel | route = route }
avoidReinit ( newModel, cmd ) =
if pageMatch currentModel.page newModel.page then
( model, Cmd.none )
else
( newModel, cmd )
in
case route of
Route.NotFound ->
( { model | page = NotFound }, Cmd.none )
Route.Home ->
-- Always redirect to /packages until we have something to show
-- on the home page
( model, Browser.Navigation.replaceUrl model.navKey "/packages" )
Route.Packages searchArgs ->
let
modelPage =
case model.page of
Packages x ->
Just x
_ ->
Nothing
in
Page.Packages.init searchArgs modelPage
|> updateWith Packages PackagesMsg model
|> avoidReinit
|> attemptQuery
Route.Options searchArgs ->
let
modelPage =
case model.page of
Options x ->
Just x
_ ->
Nothing
in
Page.Options.init searchArgs modelPage
|> updateWith Options OptionsMsg model
|> avoidReinit
|> attemptQuery
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case ( msg, model.page ) of
( ClickedLink urlRequest, _ ) ->
case urlRequest of
Browser.Internal url ->
( model
, Browser.Navigation.pushUrl model.navKey <| Url.toString url
)
Browser.External href ->
( model
, case href of
-- ignore links with no `href` attribute
"" ->
Cmd.none
_ ->
Browser.Navigation.load href
)
( ChangedUrl url, _ ) ->
changeRouteTo model url
( 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 )
-- VIEW
view :
Model
->
{ title : String
, body : List (Html Msg)
}
view model =
let
title =
case model.page of
Packages _ ->
"NixOS Search - Packages"
Options _ ->
"NixOS Search - Options"
_ ->
"NixOS Search"
in
{ title = title
, body =
[ div []
[ header []
[ div [ class "navbar navbar-static-top" ]
[ div [ class "navbar-inner" ]
[ div [ class "container" ]
[ a [ class "brand", href "https://nixos.org" ]
[ img [ src "https://nixos.org/logo/nix-wiki.png", class "logo" ] []
]
, div [ ]
[ ul [ class "nav pull-left" ]
(viewNavigation model.route)
]
]
]
]
]
, div [ class "container main" ]
[ div [ id "content" ] [ viewPage model ]
, footer
[ class "container text-center" ]
[ div []
[ span [] [ text "Please help us improve the search by " ]
, a
[ href "https://github.com/NixOS/nixos-search/issues"
]
[ text "reporting issues" ]
, span [] [ text "." ]
]
, div []
[ span [] [ text " " ]
, span [] [ text "Elasticsearch instance graciously provided by " ]
, a [ href "https://bonsai.io" ] [ text "Bonsai" ]
, span [] [ text ". Thank you! " ]
]
]
]
]
]
}
viewNavigation : Route.Route -> List (Html Msg)
viewNavigation route =
let
toRoute f =
case route of
-- Preserve arguments
Route.Packages searchArgs ->
f searchArgs
Route.Options searchArgs ->
f searchArgs
_ ->
f <| Route.SearchArgs Nothing Nothing Nothing Nothing Nothing Nothing Nothing
in
li [] [ a [ href "https://nixos.org" ] [ text "Back to nixos.org" ] ]
:: List.map
(viewNavigationItem route)
[ ( toRoute Route.Packages, "Packages" )
, ( toRoute Route.Options, "Options" )
]
viewNavigationItem :
Route.Route
-> ( Route.Route, String )
-> Html Msg
viewNavigationItem currentRoute ( route, title ) =
li
[ classList [ ( "active", currentRoute == route ) ] ]
[ a [ Route.href route ] [ text title ] ]
viewPage : Model -> Html Msg
viewPage model =
case model.page of
NotFound ->
div [] [ text "Not Found" ]
Home _ ->
div [] [ text "Welcome" ]
Packages packagesModel ->
Html.map (\m -> PackagesMsg m) <| Page.Packages.view packagesModel
Options optionsModel ->
Html.map (\m -> OptionsMsg m) <| Page.Options.view optionsModel
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none
-- MAIN
main : Program Flags Model Msg
main =
Browser.application
{ init = init
, onUrlRequest = ClickedLink
, onUrlChange = ChangedUrl
, subscriptions = subscriptions
, update = update
, view = view
}