mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-12-28 14:23:04 +03:00
235 lines
6.4 KiB
Elm
235 lines
6.4 KiB
Elm
module Route.Feed__ exposing (ActionData, Data, Model, Msg, route)
|
|
|
|
import DataSource exposing (DataSource)
|
|
import DataSource.Http
|
|
import DataSource.Port
|
|
import Effect exposing (Effect)
|
|
import ErrorPage exposing (ErrorPage)
|
|
import Head
|
|
import Head.Seo as Seo
|
|
import Html exposing (Html)
|
|
import Html.Attributes as Attr
|
|
import Json.Decode exposing (Decoder)
|
|
import Json.Encode as Encode
|
|
import Pages.Msg
|
|
import Pages.PageUrl exposing (PageUrl)
|
|
import Pages.Url
|
|
import Path exposing (Path)
|
|
import Route
|
|
import RouteBuilder exposing (StatefulRoute, StatelessRoute, StaticPayload)
|
|
import Server.Request as Request
|
|
import Server.Response as Response exposing (Response)
|
|
import Shared
|
|
import Story exposing (Item)
|
|
import Url.Builder
|
|
import View exposing (View)
|
|
|
|
|
|
type alias Model =
|
|
{}
|
|
|
|
|
|
type Msg
|
|
= NoOp
|
|
|
|
|
|
type alias RouteParams =
|
|
{ feed : Maybe String
|
|
}
|
|
|
|
|
|
route : StatefulRoute RouteParams Data ActionData Model Msg
|
|
route =
|
|
RouteBuilder.serverRender
|
|
{ head = head
|
|
, data = data
|
|
, action = \_ -> Request.skip "No action."
|
|
}
|
|
|> RouteBuilder.buildWithLocalState
|
|
{ view = view
|
|
, update = update
|
|
, subscriptions = subscriptions
|
|
, init = init
|
|
}
|
|
|
|
|
|
init :
|
|
Maybe PageUrl
|
|
-> Shared.Model
|
|
-> StaticPayload Data ActionData RouteParams
|
|
-> ( Model, Effect Msg )
|
|
init maybePageUrl sharedModel static =
|
|
( {}, Effect.none )
|
|
|
|
|
|
update :
|
|
PageUrl
|
|
-> Shared.Model
|
|
-> StaticPayload Data ActionData RouteParams
|
|
-> Msg
|
|
-> Model
|
|
-> ( Model, Effect Msg )
|
|
update pageUrl sharedModel static msg model =
|
|
case msg of
|
|
NoOp ->
|
|
( model, Effect.none )
|
|
|
|
|
|
subscriptions : Maybe PageUrl -> RouteParams -> Path -> Shared.Model -> Model -> Sub Msg
|
|
subscriptions maybePageUrl routeParams path sharedModel model =
|
|
Sub.none
|
|
|
|
|
|
pages : DataSource (List RouteParams)
|
|
pages =
|
|
DataSource.succeed []
|
|
|
|
|
|
type alias Data =
|
|
{ stories : List Item
|
|
, currentPage : Int
|
|
}
|
|
|
|
|
|
type alias ActionData =
|
|
{}
|
|
|
|
|
|
data : RouteParams -> Request.Parser (DataSource (Response Data ErrorPage))
|
|
data routeParams =
|
|
Request.queryParam "page"
|
|
|> Request.map
|
|
(\maybePage ->
|
|
let
|
|
currentPage : Int
|
|
currentPage =
|
|
maybePage
|
|
|> Maybe.andThen String.toInt
|
|
|> Maybe.withDefault 1
|
|
|
|
feed : String
|
|
feed =
|
|
--const type = Astro.params.stories || "top";
|
|
case routeParams.feed |> Maybe.withDefault "top" of
|
|
"top" ->
|
|
"news"
|
|
|
|
"new" ->
|
|
"newest"
|
|
|
|
"show" ->
|
|
"show"
|
|
|
|
"ask" ->
|
|
"ask"
|
|
|
|
"job" ->
|
|
"jobs"
|
|
|
|
_ ->
|
|
"not-found"
|
|
|
|
getStoriesUrl : String
|
|
getStoriesUrl =
|
|
Url.Builder.crossOrigin "https://node-hnapi.herokuapp.com"
|
|
[ feed ]
|
|
[ Url.Builder.int "page" currentPage
|
|
]
|
|
|
|
getStories : DataSource (List Item)
|
|
getStories =
|
|
DataSource.Http.get getStoriesUrl
|
|
(Story.decoder |> Json.Decode.list)
|
|
in
|
|
DataSource.map2 Data
|
|
getStories
|
|
(DataSource.succeed currentPage)
|
|
|> DataSource.map Response.render
|
|
)
|
|
|
|
|
|
head :
|
|
StaticPayload Data ActionData RouteParams
|
|
-> List Head.Tag
|
|
head static =
|
|
Seo.summary
|
|
{ canonicalUrlOverride = Nothing
|
|
, siteName = "elm-pages Hacker News"
|
|
, image =
|
|
{ url = [ "images", "icon-png.png" ] |> Path.join |> Pages.Url.fromPath
|
|
, alt = "elm-pages logo"
|
|
, dimensions = Nothing
|
|
, mimeType = Nothing
|
|
}
|
|
, description = "A demo of elm-pages 3 server-rendered routes."
|
|
, locale = Nothing
|
|
, title = title static.routeParams
|
|
}
|
|
|> Seo.website
|
|
|
|
|
|
title : RouteParams -> String
|
|
title routeParams =
|
|
(routeParams.feed
|
|
|> Maybe.map (\feedName -> feedName ++ " | ")
|
|
|> Maybe.withDefault ""
|
|
)
|
|
++ "elm-pages Hacker News"
|
|
|
|
|
|
view :
|
|
Maybe PageUrl
|
|
-> Shared.Model
|
|
-> Model
|
|
-> StaticPayload Data ActionData RouteParams
|
|
-> View (Pages.Msg.Msg Msg)
|
|
view maybeUrl sharedModel model static =
|
|
{ title = title static.routeParams
|
|
, body =
|
|
[ paginationView static.data.stories static.routeParams static.data.currentPage
|
|
, Html.main_
|
|
[ Attr.class "news-list" ]
|
|
[ static.data.stories
|
|
|> List.map Story.view
|
|
|> Html.ul []
|
|
]
|
|
]
|
|
}
|
|
|
|
|
|
paginationView : List Item -> RouteParams -> Int -> Html msg
|
|
paginationView stories routeParams page =
|
|
Html.div [ Attr.class "news-view" ]
|
|
[ Html.div [ Attr.class "news-list-nav" ]
|
|
[ if page > 1 then
|
|
Html.a
|
|
[ Attr.class "page-link"
|
|
, Attr.href <| (Route.Feed__ routeParams |> Route.toString) ++ "?page=" ++ String.fromInt (page - 1)
|
|
, Attr.attribute "aria-label" "Previous Page"
|
|
]
|
|
[ Html.text "< prev" ]
|
|
|
|
else
|
|
Html.span
|
|
[ Attr.class "page-link disabled"
|
|
, Attr.attribute "aria-hidden" "true"
|
|
]
|
|
[ Html.text "< prev" ]
|
|
, Html.span [] [ Html.text <| "page " ++ String.fromInt page ]
|
|
, if List.length stories > 28 then
|
|
Html.a
|
|
[ Attr.class "page-link"
|
|
, Attr.href <| (Route.Feed__ routeParams |> Route.toString) ++ "?page=" ++ String.fromInt (page + 1)
|
|
, Attr.attribute "aria-label" "Next Page"
|
|
]
|
|
[ Html.text "more >" ]
|
|
|
|
else
|
|
Html.span
|
|
[ Attr.class "page-link"
|
|
, Attr.attribute "aria-hidden" "true"
|
|
]
|
|
[ Html.text "more >" ]
|
|
]
|
|
]
|