module Main exposing (main) import Browser import Browser.Navigation as Nav exposing (Key) import Effect import Gen.Model import Gen.Pages as Pages import Gen.Route as Route import Request import Shared import Url exposing (Url) import View main : Program Shared.Flags Model Msg main = Browser.application { init = init , update = update , view = view , subscriptions = subscriptions , onUrlChange = ChangedUrl , onUrlRequest = ClickedLink } -- INIT type alias Model = { url : Url , key : Key , shared : Shared.Model , page : Pages.Model } init : Shared.Flags -> Url -> Key -> ( Model, Cmd Msg ) init flags url key = let ( shared, sharedCmd ) = Shared.init (Request.create () url key) flags ( page, effect ) = Pages.init (Route.fromUrl url) shared url key in ( Model url key shared page , Cmd.batch [ Cmd.map Shared sharedCmd , Effect.toCmd ( Shared, Page ) effect ] ) -- UPDATE type Msg = ChangedUrl Url | ClickedLink Browser.UrlRequest | Shared Shared.Msg | Page Pages.Msg update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of ClickedLink (Browser.Internal url) -> ( model , Nav.pushUrl model.key (Url.toString url) ) ClickedLink (Browser.External url) -> ( model , Nav.load url ) ChangedUrl url -> if url.path /= model.url.path then let ( page, effect ) = Pages.init (Route.fromUrl url) model.shared url model.key in ( { model | url = url, page = page } , Effect.toCmd ( Shared, Page ) effect ) else ( { model | url = url }, Cmd.none ) Shared sharedMsg -> let ( shared, sharedCmd ) = Shared.update (Request.create () model.url model.key) sharedMsg model.shared ( page, effect ) = Pages.init (Route.fromUrl model.url) shared model.url model.key in if page == Gen.Model.Redirecting_ then ( { model | shared = shared, page = page } , Cmd.batch [ Cmd.map Shared sharedCmd , Effect.toCmd ( Shared, Page ) effect ] ) else ( { model | shared = shared } , Cmd.map Shared sharedCmd ) Page pageMsg -> let ( page, effect ) = Pages.update pageMsg model.page model.shared model.url model.key in ( { model | page = page } , Effect.toCmd ( Shared, Page ) effect ) -- VIEW view : Model -> Browser.Document Msg view model = Pages.view model.page model.shared model.url model.key |> View.map Page |> View.toBrowserDocument -- SUBSCRIPTIONS subscriptions : Model -> Sub Msg subscriptions model = Sub.batch [ Pages.subscriptions model.page model.shared model.url model.key |> Sub.map Page , Shared.subscriptions (Request.create () model.url model.key) model.shared |> Sub.map Shared ]