recipes.coopcloud.tech/src/Main.elm

149 lines
3.1 KiB
Elm

module Main exposing (main)
import Browser
import Browser.Navigation as Nav
import Shared exposing (Flags)
import Spa.Document as Document exposing (Document)
import Spa.Generated.Pages as Pages
import Spa.Generated.Route as Route exposing (Route)
import Url exposing (Url)
main : Program Flags Model Msg
main =
Browser.application
{ init = init
, update = update
, subscriptions = subscriptions
, view = view >> Document.toBrowserDocument
, onUrlRequest = LinkClicked
, onUrlChange = UrlChanged
}
-- INIT
type alias Model =
{ shared : Shared.Model
, page : Pages.Model
}
init : Flags -> Url -> Nav.Key -> ( Model, Cmd Msg )
init flags url key =
let
( shared, sharedCmd ) =
Shared.init flags url key
( page, pageCmd ) =
Pages.init (fromUrl url) shared
savedShare =
Pages.save page shared
in
( Model savedShare page
, Cmd.batch
[ Cmd.map Shared sharedCmd
, Cmd.map Pages pageCmd
]
)
-- UPDATE
type Msg
= LinkClicked Browser.UrlRequest
| UrlChanged Url
| Shared Shared.Msg
| Pages Pages.Msg
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
LinkClicked (Browser.Internal url) ->
( model
, Nav.pushUrl model.shared.key (Url.toString url)
)
LinkClicked (Browser.External href) ->
( model
, Nav.load href
)
UrlChanged url ->
let
original =
model.shared
shared =
{ original | url = url }
( page, pageCmd ) =
Pages.init (fromUrl url) shared
in
( { model | page = page, shared = Pages.save page shared }
, Cmd.map Pages pageCmd
)
Shared sharedMsg ->
let
( shared, sharedCmd ) =
Shared.update sharedMsg model.shared
( page, pageCmd ) =
Pages.load model.page shared
in
( { model | page = page, shared = shared }
, Cmd.batch
[ Cmd.map Shared sharedCmd
, Cmd.map Pages pageCmd
]
)
Pages pageMsg ->
let
( page, pageCmd ) =
Pages.update pageMsg model.page
shared =
Pages.save page model.shared
in
( { model | page = page, shared = shared }
, Cmd.map Pages pageCmd
)
view : Model -> Document Msg
view model =
Shared.view
{ page =
Pages.view model.page
|> Document.map Pages
, toMsg = Shared
}
model.shared
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ Shared.subscriptions model.shared
|> Sub.map Shared
, Pages.subscriptions model.page
|> Sub.map Pages
]
-- URL
fromUrl : Url -> Route
fromUrl =
Route.fromUrl >> Maybe.withDefault Route.NotFound