martiplier/src/Main.elm

267 lines
7.1 KiB
Elm

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