From 86f96f41220971879743a69e5443ae54c89acc96 Mon Sep 17 00:00:00 2001 From: Tanya Bouman Date: Wed, 9 Aug 2023 09:23:07 -0400 Subject: [PATCH] update hackernews example to v3 --- examples/hackernews/app/Api.elm | 3 +- examples/hackernews/app/Effect.elm | 2 +- examples/hackernews/app/Route/Feed__.elm | 117 +++++++++--------- examples/hackernews/app/Route/Stories/Id_.elm | 40 +++--- examples/hackernews/app/Shared.elm | 19 +-- examples/hackernews/app/Site.elm | 3 +- examples/hackernews/elm.json | 16 ++- examples/hackernews/package-lock.json | 7 +- examples/hackernews/package.json | 3 +- 9 files changed, 104 insertions(+), 106 deletions(-) diff --git a/examples/hackernews/app/Api.elm b/examples/hackernews/app/Api.elm index f96c8fc9..4ca1f5aa 100644 --- a/examples/hackernews/app/Api.elm +++ b/examples/hackernews/app/Api.elm @@ -2,6 +2,7 @@ module Api exposing (routes) import ApiRoute exposing (ApiRoute) import BackendTask exposing (BackendTask) +import FatalError exposing (FatalError) import Html exposing (Html) import Pages.Manifest as Manifest import Route exposing (Route) @@ -9,7 +10,7 @@ import Site routes : - BackendTask (List Route) + BackendTask FatalError (List Route) -> (Maybe { indent : Int, newLines : Bool } -> Html Never -> String) -> List (ApiRoute.ApiRoute ApiRoute.Response) routes getStaticRoutes htmlToString = diff --git a/examples/hackernews/app/Effect.elm b/examples/hackernews/app/Effect.elm index cd19760b..fa5f006b 100644 --- a/examples/hackernews/app/Effect.elm +++ b/examples/hackernews/app/Effect.elm @@ -1,10 +1,10 @@ module Effect exposing (Effect(..), batch, fromCmd, map, none, perform) import Browser.Navigation -import Form.FormData exposing (FormData) import Http import Json.Decode as Decode import Pages.Fetcher +import Pages.FormData exposing (FormData) import Url exposing (Url) diff --git a/examples/hackernews/app/Route/Feed__.elm b/examples/hackernews/app/Route/Feed__.elm index 1d98adb4..3178beeb 100644 --- a/examples/hackernews/app/Route/Feed__.elm +++ b/examples/hackernews/app/Route/Feed__.elm @@ -1,27 +1,28 @@ module Route.Feed__ exposing (ActionData, Data, Model, Msg, route) import BackendTask exposing (BackendTask) -import BackendTask.Http import BackendTask.Custom +import BackendTask.Http import Effect exposing (Effect) import ErrorPage exposing (ErrorPage) +import FatalError exposing (FatalError) 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 PagesMsg exposing (PagesMsg) import Pages.PageUrl exposing (PageUrl) import Pages.Url -import Path exposing (Path) +import PagesMsg exposing (PagesMsg) import Route -import RouteBuilder exposing (StatefulRoute, StatelessRoute, App) +import RouteBuilder exposing (App, StatefulRoute, StatelessRoute) import Server.Request as Request import Server.Response as Response exposing (Response) import Shared import Story exposing (Item) import Url.Builder +import UrlPath exposing (UrlPath) import View exposing (View) @@ -43,7 +44,7 @@ route = RouteBuilder.serverRender { head = head , data = data - , action = \_ -> Request.skip "No action." + , action = \_ _ -> BackendTask.fail (FatalError.fromString "No action.") } |> RouteBuilder.buildWithLocalState { view = view @@ -54,33 +55,31 @@ route = init : - Maybe PageUrl + App Data ActionData RouteParams -> Shared.Model - -> App Data ActionData RouteParams -> ( Model, Effect Msg ) -init maybePageUrl sharedModel static = +init static sharedModel = ( {}, Effect.none ) update : - PageUrl + App Data ActionData RouteParams -> Shared.Model - -> App Data ActionData RouteParams -> Msg -> Model -> ( Model, Effect Msg ) -update pageUrl sharedModel static msg model = +update static sharedModel 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 = +subscriptions : RouteParams -> UrlPath -> Shared.Model -> Model -> Sub Msg +subscriptions routeParams path sharedModel model = Sub.none -pages : BackendTask (List RouteParams) +pages : BackendTask FatalError (List RouteParams) pages = BackendTask.succeed [] @@ -95,57 +94,54 @@ type alias ActionData = {} -data : RouteParams -> Request.Parser (BackendTask (Response Data ErrorPage)) -data routeParams = - Request.queryParam "page" - |> Request.map - (\maybePage -> - let - currentPage : Int - currentPage = - maybePage - |> Maybe.andThen String.toInt - |> Maybe.withDefault 1 +data : RouteParams -> Request.Request -> BackendTask FatalError (Response Data ErrorPage) +data routeParams request = + let + currentPage : Int + currentPage = + Request.queryParam "page" request + |> 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" + feed : String + feed = + --const type = Astro.params.stories || "top"; + case routeParams.feed |> Maybe.withDefault "top" of + "top" -> + "news" - "new" -> - "newest" + "new" -> + "newest" - "show" -> - "show" + "show" -> + "show" - "ask" -> - "ask" + "ask" -> + "ask" - "job" -> - "jobs" + "job" -> + "jobs" - _ -> - "not-found" + _ -> + "not-found" - getStoriesUrl : String - getStoriesUrl = - Url.Builder.crossOrigin "https://node-hnapi.herokuapp.com" - [ feed ] - [ Url.Builder.int "page" currentPage - ] + getStoriesUrl : String + getStoriesUrl = + Url.Builder.crossOrigin "https://node-hnapi.herokuapp.com" + [ feed ] + [ Url.Builder.int "page" currentPage + ] - getStories : BackendTask (List Item) - getStories = - BackendTask.Http.get getStoriesUrl - (Story.decoder |> Json.Decode.list) - in - BackendTask.map2 Data - getStories - (BackendTask.succeed currentPage) - |> BackendTask.map Response.render - ) + getStories : BackendTask FatalError (List Item) + getStories = + BackendTask.Http.getJson getStoriesUrl + (Story.decoder |> Json.Decode.list) + |> BackendTask.allowFatal + in + BackendTask.map2 Data + getStories + (BackendTask.succeed currentPage) + |> BackendTask.map Response.render head : @@ -156,7 +152,7 @@ head static = { canonicalUrlOverride = Nothing , siteName = "elm-pages Hacker News" , image = - { url = [ "images", "icon-png.png" ] |> Path.join |> Pages.Url.fromPath + { url = [ "images", "icon-png.png" ] |> UrlPath.join |> Pages.Url.fromPath , alt = "elm-pages logo" , dimensions = Nothing , mimeType = Nothing @@ -178,12 +174,11 @@ title routeParams = view : - Maybe PageUrl + App Data ActionData RouteParams -> Shared.Model -> Model - -> App Data ActionData RouteParams -> View (PagesMsg Msg) -view maybeUrl sharedModel model static = +view static sharedModel model = { title = title static.routeParams , body = [ paginationView static.data.stories static.routeParams static.data.currentPage diff --git a/examples/hackernews/app/Route/Stories/Id_.elm b/examples/hackernews/app/Route/Stories/Id_.elm index 30d960fc..4a2d24a4 100644 --- a/examples/hackernews/app/Route/Stories/Id_.elm +++ b/examples/hackernews/app/Route/Stories/Id_.elm @@ -4,6 +4,7 @@ import BackendTask exposing (BackendTask) import BackendTask.Http import Effect exposing (Effect) import ErrorPage exposing (ErrorPage) +import FatalError exposing (FatalError) import Head import Head.Seo as Seo import Html exposing (Html) @@ -11,15 +12,15 @@ import Html.Attributes as Attr import Html.Keyed import Json.Decode as Decode import Json.Encode as Encode -import PagesMsg exposing (PagesMsg) import Pages.PageUrl exposing (PageUrl) import Pages.Url -import Path exposing (Path) -import RouteBuilder exposing (StatefulRoute, StatelessRoute, App) +import PagesMsg exposing (PagesMsg) +import RouteBuilder exposing (App, StatefulRoute, StatelessRoute) import Server.Request as Request import Server.Response as Response exposing (Response) import Shared import Story exposing (Entry(..), Item(..)) +import UrlPath exposing (UrlPath) import View exposing (View) @@ -40,7 +41,7 @@ route = RouteBuilder.serverRender { head = head , data = data - , action = \_ -> Request.skip "No action." + , action = \_ _ -> BackendTask.fail (FatalError.fromString "No action.") } |> RouteBuilder.buildWithLocalState { view = view @@ -51,33 +52,31 @@ route = init : - Maybe PageUrl + App Data ActionData RouteParams -> Shared.Model - -> App Data ActionData RouteParams -> ( Model, Effect Msg ) -init maybePageUrl sharedModel static = +init static sharedModel = ( {}, Effect.none ) update : - PageUrl + App Data ActionData RouteParams -> Shared.Model - -> App Data ActionData RouteParams -> Msg -> Model -> ( Model, Effect Msg ) -update pageUrl sharedModel static msg model = +update static sharedModel 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 = +subscriptions : RouteParams -> UrlPath -> Shared.Model -> Model -> Sub Msg +subscriptions routeParams path sharedModel model = Sub.none -pages : BackendTask (List RouteParams) +pages : BackendTask FatalError (List RouteParams) pages = BackendTask.succeed [] @@ -91,10 +90,10 @@ type alias ActionData = {} -data : RouteParams -> Request.Parser (BackendTask (Response Data ErrorPage)) -data routeParams = - Request.succeed - (BackendTask.Http.get ("https://node-hnapi.herokuapp.com/item/" ++ routeParams.id) +data : RouteParams -> Request.Request -> BackendTask FatalError (Response Data ErrorPage) +data routeParams request = + BackendTask.allowFatal + (BackendTask.Http.getJson ("https://node-hnapi.herokuapp.com/item/" ++ routeParams.id) (Decode.map2 Tuple.pair Story.decoder (Decode.field "comments" (Decode.value |> Decode.map (Encode.encode 0))) @@ -115,7 +114,7 @@ head static = { canonicalUrlOverride = Nothing , siteName = "elm-pages Hacker News" , image = - { url = [ "images", "icon-png.png" ] |> Path.join |> Pages.Url.fromPath + { url = [ "images", "icon-png.png" ] |> UrlPath.join |> Pages.Url.fromPath , alt = "elm-pages logo" , dimensions = Nothing , mimeType = Nothing @@ -128,12 +127,11 @@ head static = view : - Maybe PageUrl + App Data ActionData RouteParams -> Shared.Model -> Model - -> App Data ActionData RouteParams -> View (PagesMsg Msg) -view maybeUrl sharedModel model static = +view static sharedModel model = { title = static.data.story |> Tuple.first |> (\(Item common _) -> common.title) , body = [ storyView static.data.story diff --git a/examples/hackernews/app/Shared.elm b/examples/hackernews/app/Shared.elm index 4e98e0d6..abd17990 100644 --- a/examples/hackernews/app/Shared.elm +++ b/examples/hackernews/app/Shared.elm @@ -2,13 +2,14 @@ module Shared exposing (Data, Model, Msg(..), SharedMsg(..), template) import BackendTask import Effect exposing (Effect) +import FatalError exposing (FatalError) import Html exposing (Html) import Html.Attributes as Attr import Pages.Flags import Pages.PageUrl exposing (PageUrl) -import Path exposing (Path) import Route exposing (Route) import SharedTemplate exposing (SharedTemplate) +import UrlPath exposing (UrlPath) import View exposing (View) @@ -25,7 +26,7 @@ template = type Msg = OnPageChange - { path : Path + { path : UrlPath , query : Maybe String , fragment : Maybe String } @@ -50,7 +51,7 @@ init : -> Maybe { path : - { path : Path + { path : UrlPath , query : Maybe String , fragment : Maybe String } @@ -58,7 +59,7 @@ init : , pageUrl : Maybe PageUrl } -> ( Model, Effect Msg ) -init flags maybePagePath = +init flags maybePageUrlPath = ( { showMobileMenu = False } , Effect.none ) @@ -74,12 +75,12 @@ update msg model = ( model, Effect.none ) -subscriptions : Path -> Model -> Sub Msg +subscriptions : UrlPath -> Model -> Sub Msg subscriptions _ _ = Sub.none -data : BackendTask.BackendTask Data +data : BackendTask.BackendTask FatalError Data data = BackendTask.succeed () @@ -87,15 +88,15 @@ data = view : Data -> - { path : Path + { path : UrlPath , route : Maybe Route } -> Model -> (Msg -> msg) -> View msg - -> { body : Html msg, title : String } + -> { body : List (Html msg), title : String } view sharedData page model toMsg pageView = - { body = Html.div [] (headerView :: pageView.body) + { body = [ Html.div [] (headerView :: pageView.body) ] , title = pageView.title } diff --git a/examples/hackernews/app/Site.elm b/examples/hackernews/app/Site.elm index d460358f..58338607 100644 --- a/examples/hackernews/app/Site.elm +++ b/examples/hackernews/app/Site.elm @@ -1,6 +1,7 @@ module Site exposing (canonicalUrl, config) import BackendTask exposing (BackendTask) +import FatalError exposing (FatalError) import Head import SiteConfig exposing (SiteConfig) @@ -17,7 +18,7 @@ canonicalUrl = "https://hacker-news-elm-pages.netlify.app" -head : BackendTask (List Head.Tag) +head : BackendTask FatalError (List Head.Tag) head = [ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1") , Head.metaName "mobile-web-app-capable" (Head.raw "yes") diff --git a/examples/hackernews/elm.json b/examples/hackernews/elm.json index 9cb2bf04..50f07a25 100644 --- a/examples/hackernews/elm.json +++ b/examples/hackernews/elm.json @@ -10,15 +10,16 @@ "elm-version": "0.19.1", "dependencies": { "direct": { - "MartinSStewart/elm-serialize": "1.3.0", + "MartinSStewart/elm-serialize": "1.3.1", "NoRedInk/elm-json-decode-pipeline": "1.0.1", "avh4/elm-color": "1.0.0", "danfishgold/base64-bytes": "1.1.0", "danyx23/elm-mimetype": "4.0.1", "dillonkearns/elm-bcp47-language-tag": "1.0.1", "dillonkearns/elm-date-or-date-time": "2.0.0", + "dillonkearns/elm-form": "3.0.0", "dillonkearns/elm-graphql": "5.0.11", - "dillonkearns/elm-markdown": "6.0.1", + "dillonkearns/elm-markdown": "7.0.1", "dillonkearns/elm-sitemap": "1.0.2", "elm/browser": "1.0.2", "elm/bytes": "1.0.8", @@ -35,25 +36,28 @@ "elm-community/list-extra": "8.7.0", "jluckyiv/elm-utc-date-strings": "1.0.0", "justinmimbs/date": "4.0.1", - "mdgriffith/elm-codegen": "2.1.0", - "miniBill/elm-codec": "1.2.0", + "mdgriffith/elm-codegen": "4.0.1", + "miniBill/elm-codec": "2.0.0", "noahzgordon/elm-color-extra": "1.0.2", - "pablohirafuji/elm-syntax-highlight": "3.4.1", + "pablohirafuji/elm-syntax-highlight": "3.5.0", "robinheghan/fnv1a": "1.0.0", "robinheghan/murmur3": "1.0.0", - "rtfeldman/elm-css": "16.1.1", + "rtfeldman/elm-css": "18.0.0", "rtfeldman/elm-iso8601-date-strings": "1.1.4", + "the-sett/elm-syntax-dsl": "6.0.2", "tripokey/elm-fuzzy": "5.2.1", "turboMaCk/non-empty-list-alias": "1.3.1", "vito/elm-ansi": "10.0.1", "zwilias/json-decode-exploration": "6.0.0" }, "indirect": { + "Chadtech/elm-bool-extra": "2.4.2", "bburdette/toop": "1.2.0", "billstclair/elm-xml-eeue56": "2.1.0", "elm/file": "1.0.5", "elm/random": "1.0.0", "elm-community/basics-extra": "4.1.0", + "elm-community/maybe-extra": "5.3.0", "fredcy/elm-parseint": "2.0.1", "j-maas/elm-ordered-containers": "1.0.0", "lukewestby/elm-string-interpolate": "1.0.4", diff --git a/examples/hackernews/package-lock.json b/examples/hackernews/package-lock.json index 0020a6d0..b345455a 100644 --- a/examples/hackernews/package-lock.json +++ b/examples/hackernews/package-lock.json @@ -22,8 +22,7 @@ } }, "../..": { - "name": "elm-pages", - "version": "3.0.0-beta.40", + "version": "3.0.6", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -60,7 +59,7 @@ "@types/micromatch": "^4.0.2", "@types/node": "^20.1.0", "@types/serve-static": "^1.15.1", - "cypress": "^12.11.0", + "cypress": "^12.13.0", "elm-codegen": "^0.3.0", "elm-optimize-level-2": "^0.3.5", "elm-review": "^2.10.2", @@ -4366,7 +4365,7 @@ "connect": "^3.7.0", "cookie-signature": "^1.2.1", "cross-spawn": "7.0.3", - "cypress": "^12.11.0", + "cypress": "^12.13.0", "devcert": "^1.2.2", "elm-codegen": "^0.3.0", "elm-doc-preview": "^5.0.5", diff --git a/examples/hackernews/package.json b/examples/hackernews/package.json index 8f7c3fd3..d42de135 100644 --- a/examples/hackernews/package.json +++ b/examples/hackernews/package.json @@ -4,7 +4,6 @@ "description": "Example site built with elm-pages.", "scripts": { "start": "elm-pages dev --debug", - "serve": "npm run build && http-server ./dist -a localhost -p 3000 -c-1", "build": "elm-pages build" }, "author": "Dillon Kearns", @@ -21,4 +20,4 @@ "postcss": "^8.4.5", "tailwindcss": "^2.2.19" } -} \ No newline at end of file +}