Add part5

This commit is contained in:
Richard Feldman
2018-08-05 08:41:30 -04:00
parent 2e0d00f947
commit 1ea49f8bda
53 changed files with 5519 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
module Route exposing (Route(..), fromUrl, href, replaceUrl)
import Article.Slug as Slug exposing (Slug)
import Browser.Navigation as Nav
import Html exposing (Attribute)
import Html.Attributes as Attr
import Profile exposing (Profile)
import Url exposing (Url)
import Url.Parser as Parser exposing ((</>), Parser, oneOf, s, string)
import Username exposing (Username)
-- ROUTING
type Route
= Home
| Root
| Login
| Logout
| Register
| Settings
| Article Slug
| Profile Username
| NewArticle
| EditArticle Slug
parser : Parser (Route -> a) a
parser =
oneOf
[ Parser.map Home Parser.top
, Parser.map Login (s "login")
, Parser.map Logout (s "logout")
, Parser.map Profile (s "profile" </> Username.urlParser)
-- 👉 TODO /settings → Settings
-- 👉 TODO /register → Register
-- 👉 TODO /article/[slug] → Article [slug]
-- 👉 TODO /editor/[slug] → EditArticle [slug]
-- 👉 TODO /editor → NewArticle
--
-- 💡 HINT: Article and EditArticle work similarly to how Profile works.
]
-- PUBLIC HELPERS
href : Route -> Attribute msg
href targetRoute =
Attr.href (routeToString targetRoute)
replaceUrl : Nav.Key -> Route -> Cmd msg
replaceUrl key route =
Nav.replaceUrl key (routeToString route)
fromUrl : Url -> Maybe Route
fromUrl url =
-- The RealWorld spec treats the fragment like a path.
-- This makes it *literally* the path, so we can proceed
-- with parsing as if it had been a normal path all along.
{ url | path = Maybe.withDefault "" url.fragment, fragment = Nothing }
|> Parser.parse parser
-- INTERNAL
routeToString : Route -> String
routeToString page =
let
pieces =
case page of
Home ->
[]
Root ->
[]
Login ->
[ "login" ]
Logout ->
[ "logout" ]
Register ->
[ "register" ]
Settings ->
[ "settings" ]
Article slug ->
[ "article", Slug.toString slug ]
Profile username ->
[ "profile", Username.toString username ]
NewArticle ->
[ "editor" ]
EditArticle slug ->
[ "editor", Slug.toString slug ]
in
"#/" ++ String.join "/" pieces