99 lines
2.1 KiB
Elm
99 lines
2.1 KiB
Elm
module Route exposing (Route(..), fromUrl, href, replaceUrl)
|
|
|
|
import Browser.Navigation as Nav
|
|
import Html exposing (Attribute)
|
|
import Html.Attributes as Attr
|
|
import Todo.UUID as UUID
|
|
import Url exposing (Url)
|
|
import Url.Parser as Parser exposing ((</>), Parser, oneOf, s, string)
|
|
import Username exposing (Username)
|
|
|
|
|
|
|
|
-- ROUTING
|
|
|
|
|
|
type Route
|
|
= Home
|
|
| Login
|
|
| Logout
|
|
| Signup
|
|
| Account
|
|
| Todo UUID.UUID
|
|
| NewTodo
|
|
| EditTodo UUID.UUID
|
|
|
|
|
|
parser : Parser (Route -> a) a
|
|
parser =
|
|
oneOf
|
|
[ Parser.map Home Parser.top
|
|
, Parser.map Login (s "login")
|
|
, Parser.map Logout (s "logout")
|
|
, Parser.map Account (s "account")
|
|
, Parser.map Signup (s "signup")
|
|
, Parser.map Todo (s "article" </> UUID.urlParser)
|
|
, Parser.map NewTodo (s "editor")
|
|
, Parser.map EditTodo (s "editor" </> UUID.urlParser)
|
|
]
|
|
|
|
|
|
|
|
-- 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 =
|
|
"#/" ++ String.join "/" (routeToPieces page)
|
|
|
|
|
|
routeToPieces : Route -> List String
|
|
routeToPieces page =
|
|
case page of
|
|
Home ->
|
|
[]
|
|
|
|
Login ->
|
|
[ "login" ]
|
|
|
|
Logout ->
|
|
[ "logout" ]
|
|
|
|
Signup ->
|
|
[ "Signup" ]
|
|
|
|
Account ->
|
|
[ "account" ]
|
|
|
|
Todo uuid ->
|
|
[ "article", UUID.toString uuid ]
|
|
|
|
NewTodo ->
|
|
[ "editor" ]
|
|
|
|
EditTodo uuid ->
|
|
[ "editor", UUID.toString uuid ]
|