module Main exposing (..) import Browser import Browser.Dom import Browser.Events import Element exposing (Element) import Element.Background import Element.Font import Iddict import Items.VaultList as VaultList import Matrix import Recursion import Screen.Vault as VaultScreen import Screen.Welcome as WelcomeScreen import Task import Theme main : Program () Model Msg main = Browser.document { init = init , subscriptions = subscriptions , update = update , view = view } -- MODEL type MatrixAction = Sync type alias Model = { flavor : Theme.Flavor , height : Int , screen : Screen , width : Int } type Msg = OnMatrix MatrixAction Int Matrix.Vault | OnReturnHome Vaults | OnScreenVault Int VaultScreen.Msg | OnScreenWelcome WelcomeScreen.Msg | OnSelectVault Vaults Int | OnVaultUpdate Int Matrix.VaultUpdate | Pass | ScreenSize { height : Int, width : Int } | SetFlavor Theme.Flavor type Screen = ScreenWelcome WelcomeScreen.Model | ScreenVault Vaults Int VaultScreen.Model type alias Vaults = VaultList.Model init : () -> ( Model, Cmd Msg ) init () = ( { flavor = Theme.Latte , height = 480 , screen = ScreenWelcome WelcomeScreen.init , width = 720 } , Browser.Dom.getViewport |> Task.perform (\viewport -> ScreenSize { height = floor viewport.viewport.height , width = floor viewport.viewport.width } ) ) -- UPDATE update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of OnMatrix Sync i vault -> ( model, Matrix.sync (OnVaultUpdate i) vault ) OnReturnHome vaults -> ( { model | screen = ScreenWelcome (WelcomeScreen.fromVaults vaults) } , Cmd.none ) OnScreenVault i m -> case model.screen of ScreenVault welcomeMdl j mdl -> if i == j then case VaultScreen.update m mdl of newMdl -> ( { model | screen = ScreenVault welcomeMdl i newMdl } , Cmd.none ) else ( model, Cmd.none ) _ -> ( model, Cmd.none ) OnScreenWelcome m -> case model.screen of ScreenWelcome mdl -> case WelcomeScreen.update m mdl of newMdl -> ( { model | screen = ScreenWelcome newMdl } , Cmd.none ) _ -> ( model, Cmd.none ) OnSelectVault vaults i -> ( { model | screen = case model.screen of ScreenWelcome _ -> ScreenVault vaults i VaultScreen.init ScreenVault _ j old -> if i == j then ScreenVault vaults j old else ScreenVault vaults i VaultScreen.init } , Cmd.none ) OnVaultUpdate i vu -> ( { model | screen = case model.screen of ScreenWelcome mdl -> WelcomeScreen.updateVault i vu mdl |> ScreenWelcome ScreenVault vaults j mdl -> ScreenVault (VaultList.insertVaultUpdate i vu vaults) j mdl } , Cmd.none ) Pass -> ( model, Cmd.none ) ScreenSize { height, width } -> ( { model | height = height, width = width } , Cmd.none ) SetFlavor flavor -> ( { model | flavor = flavor }, Cmd.none ) -- SUBSCRIPTIONS subscriptions : Model -> Sub Msg subscriptions _ = Sub.batch [ Browser.Events.onResize (\w h -> ScreenSize { width = w, height = h }) ] -- VIEW view : Model -> Browser.Document Msg view model = { title = "Matrix Plier" , body = model |> viewScreen |> Element.layout [ Element.Background.color (Theme.baseUI model.flavor) , Element.Font.color (Theme.textUI model.flavor) ] |> List.singleton } viewScreen : Model -> Element Msg viewScreen model = let colorBackground = Theme.base model.flavor colorBackground2 = Theme.mantle model.flavor colorMain = Theme.mauve model.flavor colorSurface0 = Theme.surface0 model.flavor colorSurface1 = Theme.surface1 model.flavor colorText = Theme.text model.flavor in Recursion.runRecursion (\screen -> case screen of ScreenVault vaults i mdl -> case Iddict.get i vaults of Just block -> VaultScreen.view { colorBackground = colorBackground , colorBackground2 = colorBackground2 , colorMain = colorMain , colorText = colorText , height = model.height , logs = block.logs , model = mdl , onReturnToMenu = OnReturnHome vaults , onSync = OnMatrix Sync i block.vault , onVaultUpdate = OnVaultUpdate i , toMsg = OnScreenVault i , vault = block.vault , width = model.width } |> Recursion.base Nothing -> WelcomeScreen.fromVaults vaults |> ScreenWelcome |> Recursion.recurse ScreenWelcome mdl -> WelcomeScreen.view { colorBackground = colorBackground , colorBackground2 = colorBackground2 , colorMain = colorMain , colorMenu = colorSurface0 , colorText = colorText , colorTextField = colorSurface1 , flavor = model.flavor , height = model.height , model = mdl , onFlavorPick = SetFlavor , onSelectVault = OnSelectVault , toMsg = OnScreenWelcome , width = model.width } |> Recursion.base ) model.screen