Add initial spike
parent
4e76fe6e09
commit
3b370138aa
|
@ -0,0 +1,43 @@
|
|||
module Items.FlavorPicker exposing (..)
|
||||
{-| This module allows the user to pick whatever flavor they want to use.
|
||||
-}
|
||||
|
||||
import Color exposing (Color)
|
||||
import Element exposing (Element)
|
||||
import Html.Attributes
|
||||
import Material.Icons
|
||||
import Theme exposing (Flavor(..))
|
||||
import Layout
|
||||
import Element.Events
|
||||
|
||||
-- MODEL
|
||||
|
||||
-- UPDATE
|
||||
|
||||
-- VIEW
|
||||
|
||||
view :
|
||||
{ height : Int
|
||||
, flavor : Flavor
|
||||
, onClick : Flavor -> msg
|
||||
, themeIcon : Flavor -> Color
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
view data =
|
||||
let
|
||||
lightMode = data.flavor == Latte
|
||||
icon = if lightMode then Material.Icons.dark_mode else Material.Icons.light_mode
|
||||
newFlavor = if lightMode then Frappe else Latte
|
||||
in
|
||||
Element.el
|
||||
[ Element.Events.onClick (data.onClick newFlavor)
|
||||
, Element.htmlAttribute (Html.Attributes.style "cursor" "pointer")
|
||||
]
|
||||
( Layout.iconAsElement
|
||||
{ color = data.themeIcon data.flavor
|
||||
, height = data.height
|
||||
, icon = icon
|
||||
, width = data.width
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
module Items.Introduction exposing (..)
|
||||
|
||||
|
||||
import Color exposing (Color)
|
||||
import Element exposing (Element)
|
||||
import Element.Background
|
||||
import Widget.Material.Typography
|
||||
import Theme
|
||||
|
||||
-- MODEL
|
||||
|
||||
type alias Model = ()
|
||||
|
||||
type alias Msg = ()
|
||||
|
||||
-- UPDATE
|
||||
|
||||
-- SUBSCRIPTIONS
|
||||
|
||||
-- VIEW
|
||||
|
||||
view :
|
||||
{ colorBackground : Color
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
view data =
|
||||
[ header "Martiplier"
|
||||
, text "Martiplier (short for Matrix Plier) is a unique client. It doesn't let you browse rooms and have chat conversations."
|
||||
, text "Instead, it offers you a more debug-like display of a user account. This helps when trying to do bulk operations, or to discover information about a client."
|
||||
]
|
||||
|> Element.column
|
||||
[ Element.Background.color (Theme.toElmUiColor data.colorBackground)
|
||||
, Element.padding 30
|
||||
, Element.spacing 20
|
||||
, Element.width (Element.px data.width)
|
||||
]
|
||||
|
||||
header : String -> Element msg
|
||||
header =
|
||||
Element.text >> Element.el Widget.Material.Typography.h1
|
||||
>> List.singleton >> Element.paragraph []
|
||||
|
||||
text : String -> Element msg
|
||||
text =
|
||||
Element.text >> List.singleton >> Element.paragraph []
|
|
@ -0,0 +1,198 @@
|
|||
module Items.LoginScreen exposing (..)
|
||||
{-| The Login screen allows the user to log in, as well as view a short display
|
||||
of what to expect from the Matrix client.
|
||||
-}
|
||||
|
||||
import Color exposing (Color)
|
||||
import Element exposing (Element)
|
||||
import Element.Background
|
||||
import Element.Border
|
||||
import Matrix
|
||||
import Matrix.Settings
|
||||
import Theme
|
||||
import Layout
|
||||
import Items.FlavorPicker as FlavorPicker
|
||||
import Material.Icons
|
||||
|
||||
-- MODEL
|
||||
|
||||
type alias Model =
|
||||
{ accessToken : String
|
||||
, loginMethod : LoginMethod
|
||||
, password : String
|
||||
, username : String
|
||||
}
|
||||
|
||||
type Msg
|
||||
= SetAccessToken String
|
||||
| SetPassword String
|
||||
| SetUsername String
|
||||
| SwitchMethod LoginMethod
|
||||
|
||||
type LoginMethod
|
||||
= AccessToken
|
||||
| Password
|
||||
|
||||
init : Model
|
||||
init =
|
||||
{ accessToken = ""
|
||||
, loginMethod = AccessToken
|
||||
, password = ""
|
||||
, username = ""
|
||||
}
|
||||
|
||||
-- UPDATE
|
||||
|
||||
update : Msg -> Model -> Model
|
||||
update msg model =
|
||||
case msg of
|
||||
SetAccessToken name ->
|
||||
{ model | accessToken = name }
|
||||
|
||||
SetPassword name ->
|
||||
{ model | password = name }
|
||||
|
||||
SetUsername name ->
|
||||
{ model | username = name }
|
||||
|
||||
SwitchMethod method ->
|
||||
{ model | loginMethod = method }
|
||||
|
||||
-- VIEW
|
||||
|
||||
view :
|
||||
{ colorBackground : Color
|
||||
, colorMain : Color
|
||||
, colorMenu : Color
|
||||
, colorText : Color
|
||||
, colorTextField : Color
|
||||
, height : Int
|
||||
, flavor : Theme.Flavor
|
||||
, model : Model
|
||||
, onFlavorPick : Theme.Flavor -> msg
|
||||
, onSubmit : Matrix.Vault -> msg
|
||||
, toMsg : Msg -> msg
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
view data =
|
||||
[ viewLoginMethodPicker
|
||||
{ color = data.colorMain
|
||||
, loginMethod = data.model.loginMethod
|
||||
, toMsg = SwitchMethod >> data.toMsg
|
||||
}
|
||||
, Layout.textInput
|
||||
{ color = data.colorTextField
|
||||
, label = "username"
|
||||
, onChange = SetUsername >> data.toMsg
|
||||
, placeholder = Just "@alice:example.org"
|
||||
, text = data.model.username
|
||||
}
|
||||
, case data.model.loginMethod of
|
||||
AccessToken ->
|
||||
Layout.passwordInput
|
||||
{ color = data.colorTextField
|
||||
, label = "access-token"
|
||||
, onChange = SetAccessToken >> data.toMsg
|
||||
, placeholder = Just "syt_p12smN_aR0KbfXxDr3RVESXNr3I_k5Ay88"
|
||||
, show = False
|
||||
, text = data.model.accessToken
|
||||
}
|
||||
|
||||
Password ->
|
||||
Layout.passwordInput
|
||||
{ color = data.colorTextField
|
||||
, label = "password"
|
||||
, onChange = SetPassword >> data.toMsg
|
||||
, placeholder = Just "Password"
|
||||
, show = False
|
||||
, text = data.model.password
|
||||
}
|
||||
, Layout.containedButton
|
||||
{ buttonColor = data.colorMain
|
||||
, clickColor = data.colorText
|
||||
, icon = always Element.none
|
||||
, onPress =
|
||||
data.model
|
||||
|> toVault
|
||||
|> Maybe.map data.onSubmit
|
||||
, text = "LOG IN"
|
||||
}
|
||||
|> Element.el
|
||||
[ Element.centerX ]
|
||||
]
|
||||
|> Element.column
|
||||
[ Element.Background.color (Theme.toElmUiColor data.colorMenu)
|
||||
, Element.Border.rounded 25
|
||||
, Element.centerX
|
||||
, Element.centerY
|
||||
, Element.height (Element.px 300)
|
||||
, Element.padding 30
|
||||
, Element.spaceEvenly
|
||||
, Element.width (Element.px 400)
|
||||
]
|
||||
|> Element.el
|
||||
[ Element.Background.color (Theme.toElmUiColor data.colorBackground)
|
||||
, Element.inFront
|
||||
( FlavorPicker.view
|
||||
{ height = 30
|
||||
, flavor = data.flavor
|
||||
, onClick = data.onFlavorPick
|
||||
, themeIcon = always data.colorText
|
||||
, width = 30
|
||||
}
|
||||
|> Element.el [ Element.alignRight ]
|
||||
|> Element.el [ Element.padding 10, Element.width Element.fill ]
|
||||
)
|
||||
, Element.height (Element.px data.height)
|
||||
, Element.width (Element.px data.width)
|
||||
]
|
||||
|
||||
toVault : Model -> Maybe Matrix.Vault
|
||||
toVault model =
|
||||
case model.loginMethod of
|
||||
AccessToken ->
|
||||
if model.accessToken == "" then
|
||||
Nothing
|
||||
|
||||
else
|
||||
model.username
|
||||
|> Matrix.fromUserId
|
||||
|> Maybe.map (Matrix.Settings.setAccessToken model.accessToken)
|
||||
|
||||
Password ->
|
||||
if model.password == "" then
|
||||
Nothing
|
||||
|
||||
else
|
||||
model.username
|
||||
|> Matrix.fromUserId
|
||||
|> Maybe.map (Matrix.Settings.setPassword model.password)
|
||||
|
||||
viewLoginMethodPicker : { color : Color, loginMethod : LoginMethod, toMsg : LoginMethod -> msg } -> Element msg
|
||||
viewLoginMethodPicker data =
|
||||
Layout.tab
|
||||
{ color = data.color
|
||||
, content = always Element.none
|
||||
, items =
|
||||
[ { icon = Layout.iconAsIcon Material.Icons.key
|
||||
, text = "Access token"
|
||||
}
|
||||
, { icon = Layout.iconAsIcon Material.Icons.password
|
||||
, text = "Password"
|
||||
}
|
||||
]
|
||||
, onSelect =
|
||||
(\i ->
|
||||
if i == 0 then
|
||||
data.toMsg AccessToken
|
||||
else
|
||||
data.toMsg Password
|
||||
)
|
||||
, selected =
|
||||
case data.loginMethod of
|
||||
AccessToken ->
|
||||
0
|
||||
|
||||
Password ->
|
||||
1
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
module Items.VaultPicker exposing (..)
|
||||
|
||||
import Color exposing (Color)
|
||||
import Element exposing (Element)
|
||||
import Iddict exposing (Iddict)
|
||||
import Material.Icons
|
||||
import Matrix
|
||||
import Layout
|
||||
|
||||
-- MODEL
|
||||
|
||||
type alias Model =
|
||||
{ hover : Maybe Int, vaults : Iddict NamedVault }
|
||||
|
||||
type alias NamedVault = { name : String, vault : Matrix.Vault }
|
||||
|
||||
type Msg
|
||||
= AddVault String Matrix.Vault
|
||||
| OnHover Int
|
||||
| OnHoverOut Int
|
||||
| OnRemoveVault Int
|
||||
|
||||
init : List NamedVault -> Model
|
||||
init items =
|
||||
{ hover = Nothing
|
||||
, vaults =
|
||||
items
|
||||
|> List.indexedMap Tuple.pair
|
||||
|> Iddict.fromList
|
||||
}
|
||||
|
||||
-- UPDATE
|
||||
|
||||
addVault : NamedVault -> Model -> Model
|
||||
addVault data =
|
||||
AddVault data.name data.vault |> update
|
||||
|
||||
update : Msg -> Model -> Model
|
||||
update msg model =
|
||||
case msg of
|
||||
AddVault name vault ->
|
||||
{ model
|
||||
| vaults =
|
||||
model.vaults
|
||||
|> Iddict.insert { name = name, vault = vault }
|
||||
|> Tuple.second
|
||||
}
|
||||
|
||||
OnHover i ->
|
||||
{ model | hover = Just i }
|
||||
|
||||
OnHoverOut i ->
|
||||
case model.hover of
|
||||
Just h ->
|
||||
if i == h then
|
||||
{ model | hover = Nothing }
|
||||
else
|
||||
model
|
||||
|
||||
Nothing ->
|
||||
model
|
||||
|
||||
OnRemoveVault i ->
|
||||
{ model | vaults = Iddict.remove i model.vaults }
|
||||
|
||||
-- VIEW
|
||||
|
||||
getVault : Int -> Model -> Maybe Matrix.Vault
|
||||
getVault i model =
|
||||
Iddict.get i model.vaults |> Maybe.map .vault
|
||||
|
||||
view :
|
||||
{ colorItem : Color
|
||||
, colorList : Color
|
||||
, model : Model
|
||||
, onAddVault : msg
|
||||
, onSelectVault : Int -> msg
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
view data =
|
||||
Layout.sideList
|
||||
{ color = data.colorList
|
||||
, items =
|
||||
data.model.vaults
|
||||
|> Iddict.toList
|
||||
|> List.map
|
||||
(\(vid, { name, vault }) ->
|
||||
Layout.itemWithSubtext
|
||||
{ color = data.colorItem
|
||||
, leftIcon = always Element.none
|
||||
, onPress = Just (data.onSelectVault vid)
|
||||
, rightIcon = Layout.iconAsIcon Material.Icons.launch
|
||||
, text = name
|
||||
, title = "Vault #" ++ String.fromInt vid
|
||||
}
|
||||
)
|
||||
|> (\items ->
|
||||
[ Layout.itemWithSubtext
|
||||
{ color = data.colorItem
|
||||
, leftIcon = Layout.iconAsIcon Material.Icons.add_circle
|
||||
, onPress = Just data.onAddVault
|
||||
, rightIcon = always Element.none
|
||||
, text = "Click here"
|
||||
, title = "Add new"
|
||||
}
|
||||
]
|
||||
|> List.append items
|
||||
)
|
||||
|
||||
}
|
||||
|> Element.el
|
||||
[ Element.width (Element.px data.width) ]
|
|
@ -0,0 +1,170 @@
|
|||
module Items.VaultScreen exposing (..)
|
||||
|
||||
import Color exposing (Color)
|
||||
import Element exposing (Element)
|
||||
import Layout
|
||||
import Matrix
|
||||
import Matrix.Room
|
||||
import Queue exposing (Queue)
|
||||
|
||||
-- MODEL
|
||||
|
||||
type alias Model =
|
||||
{ recentLogs : Queue { channel : String, content : String }
|
||||
, screen : Screen
|
||||
}
|
||||
|
||||
type Msg
|
||||
= OnSwitchScreen Screen
|
||||
| OnVaultUpdate Matrix.VaultUpdate
|
||||
|
||||
type Screen
|
||||
= LandingScreen
|
||||
| Room String
|
||||
|
||||
init : Model
|
||||
init =
|
||||
{ recentLogs = Queue.empty
|
||||
, screen = LandingScreen
|
||||
}
|
||||
|
||||
maxItemsInRecentLogsQueue : Int
|
||||
maxItemsInRecentLogsQueue = 100
|
||||
|
||||
-- UPDATE
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
OnSwitchScreen screen ->
|
||||
( { model | screen = screen }, Cmd.none )
|
||||
|
||||
OnVaultUpdate vu ->
|
||||
( { model
|
||||
| recentLogs =
|
||||
model.recentLogs
|
||||
|> addItemsToQueue (Matrix.logs vu)
|
||||
|> stripQueueToSize maxItemsInRecentLogsQueue
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
addItemsToQueue : List a -> Queue a -> Queue a
|
||||
addItemsToQueue items queue =
|
||||
List.foldl Queue.enqueue queue items
|
||||
|
||||
stripQueueToSize : Int -> Queue a -> Queue a
|
||||
stripQueueToSize i queue =
|
||||
if Queue.length queue > i then
|
||||
stripQueueToSize i (Queue.dequeue queue)
|
||||
else
|
||||
queue
|
||||
|
||||
-- VIEW
|
||||
|
||||
view :
|
||||
{ colorSelectedRoom : Color
|
||||
, colorText : Color
|
||||
, height : Int
|
||||
, model : Model
|
||||
, onVaultUpdate : Matrix.VaultUpdate -> msg
|
||||
, vault : Matrix.Vault
|
||||
, toMsg : Msg -> msg
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
view data =
|
||||
viewScreen
|
||||
{ colorSelectedRoom = data.colorSelectedRoom
|
||||
, colorText = data.colorText
|
||||
, height = data.height
|
||||
, model = data.model
|
||||
, onVaultUpdate = data.onVaultUpdate
|
||||
, vault = data.vault
|
||||
, screen = data.model.screen
|
||||
, toMsg = data.toMsg
|
||||
, width = data.width
|
||||
}
|
||||
|
||||
viewScreen :
|
||||
{ colorSelectedRoom : Color
|
||||
, colorText : Color
|
||||
, height : Int
|
||||
, model : Model
|
||||
, onVaultUpdate : Matrix.VaultUpdate -> msg
|
||||
, vault : Matrix.Vault
|
||||
, screen : Screen
|
||||
, toMsg : Msg -> msg
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
viewScreen data =
|
||||
case data.screen of
|
||||
LandingScreen ->
|
||||
Element.wrappedRow
|
||||
[ Element.height (Element.px data.height)
|
||||
, Element.width (Element.px data.width)
|
||||
]
|
||||
[ viewRoomList
|
||||
{ colorSelected = data.colorSelectedRoom
|
||||
, colorText = data.colorText
|
||||
, rooms = Matrix.rooms data.vault
|
||||
, toMsg = data.toMsg
|
||||
}
|
||||
]
|
||||
|
||||
Room roomId ->
|
||||
case Matrix.fromRoomId roomId data.vault of
|
||||
Just room ->
|
||||
viewRoom
|
||||
{ height = data.height
|
||||
, model = room
|
||||
, toMsg = data.toMsg
|
||||
, width = data.width
|
||||
}
|
||||
|
||||
Nothing ->
|
||||
viewScreen { data | screen = LandingScreen }
|
||||
|
||||
|
||||
viewRoom :
|
||||
{ height : Int
|
||||
, model : Matrix.Room.Room
|
||||
, toMsg : Msg -> msg
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
viewRoom data =
|
||||
[ Matrix.Room.name data.model
|
||||
|> Maybe.withDefault "Nameless room"
|
||||
|> Element.text
|
||||
]
|
||||
|> Element.column []
|
||||
|
||||
viewRoomList :
|
||||
{ colorSelected : Color
|
||||
, colorText : Color
|
||||
, rooms : List Matrix.Room.Room
|
||||
, toMsg : Msg -> msg
|
||||
} -> Element msg
|
||||
viewRoomList data =
|
||||
Layout.sideList
|
||||
{ color = data.colorSelected
|
||||
, items =
|
||||
data.rooms
|
||||
|> List.map
|
||||
(\room ->
|
||||
Layout.itemWithSubtext
|
||||
{ color = data.colorText
|
||||
, leftIcon = always Element.none -- TODO: Add room image
|
||||
, onPress =
|
||||
Matrix.Room.roomId room
|
||||
|> Room
|
||||
|> OnSwitchScreen
|
||||
|> data.toMsg
|
||||
|> Just
|
||||
, rightIcon = always Element.none -- TODO: Choose icon?
|
||||
, text = Matrix.Room.roomId room
|
||||
, title =
|
||||
Matrix.Room.name room
|
||||
|> Maybe.withDefault "Nameless room"
|
||||
}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
module Items.WelcomeScreen exposing (..)
|
||||
|
||||
import Color exposing (Color)
|
||||
import Element exposing (Element)
|
||||
import Element.Background
|
||||
import Items.FlavorPicker as FlavorPicker
|
||||
import Items.Introduction as Intro
|
||||
import Items.LoginScreen as Login
|
||||
import Items.VaultPicker as VaultPicker
|
||||
import Matrix
|
||||
import Theme
|
||||
|
||||
-- MODEL
|
||||
|
||||
type alias Model =
|
||||
{ loginView : Maybe Login.Model
|
||||
, vaultView : VaultPicker.Model
|
||||
}
|
||||
|
||||
type Msg
|
||||
= OnAddVault
|
||||
| OnLoginView Login.Msg
|
||||
| OnSubmitVault { name : String, vault : Matrix.Vault }
|
||||
| OnVaultView VaultPicker.Msg
|
||||
|
||||
init : List { name : String, vault : Matrix.Vault } -> Model
|
||||
init vaults =
|
||||
{ loginView = Nothing
|
||||
, vaultView = VaultPicker.init vaults
|
||||
}
|
||||
|
||||
-- UPDATE
|
||||
|
||||
update : Msg -> Model -> Model
|
||||
update msg model =
|
||||
case msg of
|
||||
OnAddVault ->
|
||||
case model.loginView of
|
||||
Just _ ->
|
||||
model
|
||||
|
||||
Nothing ->
|
||||
{ model | loginView = Just Login.init }
|
||||
|
||||
OnLoginView m ->
|
||||
{ model
|
||||
| loginView = Maybe.map (Login.update m) model.loginView
|
||||
}
|
||||
|
||||
OnSubmitVault vault ->
|
||||
{ model
|
||||
| loginView = Nothing
|
||||
, vaultView = VaultPicker.addVault vault model.vaultView
|
||||
}
|
||||
|
||||
OnVaultView m ->
|
||||
{ model
|
||||
| vaultView = VaultPicker.update m model.vaultView
|
||||
}
|
||||
|
||||
-- VIEW
|
||||
|
||||
getVault : Int -> Model -> Maybe Matrix.Vault
|
||||
getVault i model =
|
||||
VaultPicker.getVault i model.vaultView
|
||||
|
||||
view :
|
||||
{ colorBackground : Color
|
||||
, colorBackground2 : Color
|
||||
, colorMain : Color
|
||||
, colorMenu : Color
|
||||
, colorText : Color
|
||||
, colorTextField : Color
|
||||
, height : Int
|
||||
, flavor : Theme.Flavor
|
||||
, model : Model
|
||||
, onFlavorPick : Theme.Flavor -> msg
|
||||
, onSelectVault : Int -> msg
|
||||
, toMsg : Msg -> msg
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
view data =
|
||||
let
|
||||
goesVertical = 2 * data.width <= 3 * data.height
|
||||
direction = if goesVertical then Element.column else Element.row
|
||||
width = if goesVertical then data.width else data.width // 2
|
||||
height = if goesVertical then data.height // 2 else data.height
|
||||
in
|
||||
case data.model.loginView of
|
||||
Just m ->
|
||||
direction
|
||||
[ Element.height (Element.px data.height)
|
||||
, Element.width (Element.px data.width)
|
||||
]
|
||||
[ viewIntroduction
|
||||
{ colorBackground = data.colorBackground
|
||||
, colorItem = data.colorText
|
||||
, colorList = data.colorMenu
|
||||
, height = height
|
||||
, model = data.model.vaultView
|
||||
, onSelectVault = data.onSelectVault
|
||||
, toMsg = data.toMsg
|
||||
, width = width
|
||||
}
|
||||
, Login.view
|
||||
{ colorBackground = data.colorBackground2
|
||||
, colorMain = data.colorMain
|
||||
, colorMenu = data.colorMenu
|
||||
, colorText = data.colorText
|
||||
, colorTextField = data.colorTextField
|
||||
, height = height
|
||||
, flavor = data.flavor
|
||||
, model = m
|
||||
, onFlavorPick = data.onFlavorPick
|
||||
, onSubmit = \vault -> OnSubmitVault { name = "New Vault", vault = vault } |> data.toMsg
|
||||
, toMsg = OnLoginView >> data.toMsg
|
||||
, width = width
|
||||
}
|
||||
]
|
||||
|
||||
Nothing ->
|
||||
viewIntroduction
|
||||
{ colorBackground = data.colorBackground
|
||||
, colorItem = data.colorText
|
||||
, colorList = data.colorMenu
|
||||
, height = data.height
|
||||
, model = data.model.vaultView
|
||||
, onSelectVault = data.onSelectVault
|
||||
, toMsg = data.toMsg
|
||||
, width = data.width
|
||||
}
|
||||
|> Element.el
|
||||
[ Element.Background.color (Theme.toElmUiColor data.colorBackground)
|
||||
, Element.inFront
|
||||
( FlavorPicker.view
|
||||
{ height = 30
|
||||
, flavor = data.flavor
|
||||
, onClick = data.onFlavorPick
|
||||
, themeIcon = always data.colorText
|
||||
, width = 30
|
||||
}
|
||||
|> Element.el [ Element.alignRight ]
|
||||
|> Element.el [ Element.padding 10, Element.width Element.fill ]
|
||||
)
|
||||
]
|
||||
|
||||
viewIntroduction :
|
||||
{ colorBackground : Color
|
||||
, colorItem : Color
|
||||
, colorList : Color
|
||||
, height : Int
|
||||
, model : VaultPicker.Model
|
||||
, onSelectVault : Int -> msg
|
||||
, toMsg : Msg -> msg
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
viewIntroduction data =
|
||||
[ Intro.view
|
||||
{ colorBackground = data.colorBackground
|
||||
, width = data.width
|
||||
}
|
||||
, VaultPicker.view
|
||||
{ colorItem = data.colorItem
|
||||
, colorList = data.colorList
|
||||
, onAddVault = data.toMsg OnAddVault
|
||||
, onSelectVault = data.onSelectVault
|
||||
, model = data.model
|
||||
, width = Basics.min 360 (4 * data.width // 5)
|
||||
}
|
||||
|> Element.el
|
||||
[ Element.centerX
|
||||
]
|
||||
]
|
||||
|> Element.column
|
||||
[ Element.height (Element.px data.height)
|
||||
, Element.scrollbarY
|
||||
, Element.width (Element.px data.width)
|
||||
]
|
|
@ -0,0 +1,277 @@
|
|||
module Layout exposing
|
||||
( tab
|
||||
, iconAsElement, iconAsIcon
|
||||
, containedButton, outlinedButton, textButton, sideList
|
||||
, textInput, passwordInput
|
||||
, loadingIndicator, itemWithSubtext
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
|
||||
# Layout
|
||||
|
||||
The layout module exposes some boilerplate functions that have produce a
|
||||
beautiful Material design Elm webpage.
|
||||
|
||||
|
||||
## Elements
|
||||
|
||||
@docs tab
|
||||
|
||||
## Icons
|
||||
|
||||
@docs iconAsElement, iconAsIcon
|
||||
|
||||
## Buttons
|
||||
|
||||
@docs containedButton, outlinedButton, textButton
|
||||
|
||||
|
||||
## Text fields
|
||||
|
||||
@docs textInput, passwordInput
|
||||
|
||||
## Items in a list
|
||||
|
||||
@docs itemWithSubtext
|
||||
|
||||
## Lists
|
||||
|
||||
@docs sideList
|
||||
|
||||
## Other elements
|
||||
|
||||
@docs loadingIndicator
|
||||
|
||||
-}
|
||||
|
||||
import Color exposing (Color)
|
||||
import Element exposing (Element)
|
||||
import Element.Input
|
||||
import Widget
|
||||
import Widget.Customize as Customize
|
||||
import Widget.Icon exposing (Icon)
|
||||
import Widget.Material as Material
|
||||
import Material.Icons.Types
|
||||
|
||||
|
||||
{-| A contained button representing the most important action of a group.
|
||||
-}
|
||||
containedButton :
|
||||
{ buttonColor : Color
|
||||
, clickColor : Color
|
||||
, icon : Icon msg
|
||||
, onPress : Maybe msg
|
||||
, text : String
|
||||
}
|
||||
-> Element msg
|
||||
containedButton data =
|
||||
Widget.button
|
||||
({ primary = data.buttonColor, onPrimary = data.clickColor }
|
||||
|> singlePalette
|
||||
|> Material.containedButton
|
||||
|> Customize.elementButton [ Element.width Element.fill ]
|
||||
)
|
||||
{ text = data.text, icon = data.icon, onPress = data.onPress }
|
||||
|
||||
iconAsElement :
|
||||
{ color : Color
|
||||
, height : Int
|
||||
, icon : Material.Icons.Types.Icon msg
|
||||
, width : Int
|
||||
} -> Element msg
|
||||
iconAsElement data =
|
||||
data.icon
|
||||
|> iconAsIcon
|
||||
|> (|>) { size = Basics.min data.height data.width, color = data.color }
|
||||
|> Element.el [ Element.centerX, Element.centerY ]
|
||||
|> Element.el
|
||||
[ Element.height (Element.px data.height)
|
||||
, Element.width (Element.px data.width)
|
||||
]
|
||||
|
||||
iconAsIcon : Material.Icons.Types.Icon msg -> Widget.Icon.Icon msg
|
||||
iconAsIcon =
|
||||
Widget.Icon.elmMaterialIcons Material.Icons.Types.Color
|
||||
|
||||
{-| Multiline item
|
||||
-}
|
||||
itemWithSubtext :
|
||||
{ color : Color
|
||||
, leftIcon : Widget.Icon.Icon msg
|
||||
, onPress : Maybe msg
|
||||
, rightIcon : Widget.Icon.Icon msg
|
||||
, text : String
|
||||
, title : String
|
||||
}
|
||||
-> Widget.Item msg
|
||||
itemWithSubtext data =
|
||||
Widget.multiLineItem
|
||||
( { primary = data.color, onPrimary = data.color }
|
||||
|> singlePalette
|
||||
|> Material.multiLineItem
|
||||
)
|
||||
{ content = data.rightIcon
|
||||
, icon = data.leftIcon
|
||||
, onPress = data.onPress
|
||||
, title = data.title
|
||||
, text = data.text
|
||||
}
|
||||
|
||||
{-| Circular loading bar indicator
|
||||
-}
|
||||
loadingIndicator :
|
||||
{ color : Color
|
||||
}
|
||||
-> Element msg
|
||||
loadingIndicator data =
|
||||
Widget.circularProgressIndicator
|
||||
( { primary = data.color, onPrimary = data.color }
|
||||
|> singlePalette
|
||||
|> Material.progressIndicator
|
||||
)
|
||||
Nothing
|
||||
|
||||
{-| An outlined button representing an important action within a group.
|
||||
-}
|
||||
outlinedButton :
|
||||
{ color : Color
|
||||
, icon : Icon msg
|
||||
, onPress : Maybe msg
|
||||
, text : String
|
||||
}
|
||||
-> Element msg
|
||||
outlinedButton data =
|
||||
Widget.button
|
||||
({ primary = data.color, onPrimary = data.color }
|
||||
|> singlePalette
|
||||
|> Material.outlinedButton
|
||||
)
|
||||
{ text = data.text, icon = data.icon, onPress = data.onPress }
|
||||
|
||||
{-| Show a password field
|
||||
-}
|
||||
passwordInput :
|
||||
{ color : Color
|
||||
, label : String
|
||||
, onChange : String -> msg
|
||||
, placeholder : Maybe String
|
||||
, show : Bool
|
||||
, text : String
|
||||
}
|
||||
-> Element msg
|
||||
passwordInput data =
|
||||
Widget.currentPasswordInputV2
|
||||
({ primary = data.color, onPrimary = data.color }
|
||||
|> singlePalette
|
||||
|> Material.passwordInput
|
||||
|> Customize.elementRow [ Element.width Element.fill ]
|
||||
)
|
||||
{ label = data.label
|
||||
, onChange = data.onChange
|
||||
, placeholder =
|
||||
data.placeholder
|
||||
|> Maybe.map Element.text
|
||||
|> Maybe.map (Element.Input.placeholder [])
|
||||
, show = data.show
|
||||
, text = data.text
|
||||
}
|
||||
|
||||
|
||||
{-| Create a simple palette.
|
||||
-}
|
||||
singlePalette : { primary : Color, onPrimary : Color } -> Material.Palette
|
||||
singlePalette { primary, onPrimary } =
|
||||
{ primary = primary
|
||||
, secondary = primary
|
||||
, background = primary
|
||||
, surface = primary
|
||||
, error = primary
|
||||
, on =
|
||||
{ primary = onPrimary
|
||||
, secondary = onPrimary
|
||||
, background = onPrimary
|
||||
, surface = onPrimary
|
||||
, error = onPrimary
|
||||
}
|
||||
}
|
||||
|
||||
sideList : { color : Color, items : List (Widget.Item msg) }-> Element msg
|
||||
sideList data =
|
||||
Widget.itemList
|
||||
( { primary = data.color, onPrimary = data.color }
|
||||
|> singlePalette
|
||||
|> Material.sideSheet
|
||||
)
|
||||
data.items
|
||||
|
||||
{-| A tab selector that always has an item selected.
|
||||
-}
|
||||
tab :
|
||||
{ color : Color
|
||||
, content : Int -> Element msg
|
||||
, items : List { text : String, icon : Icon msg }
|
||||
, onSelect : Int -> msg
|
||||
, selected : Int
|
||||
}
|
||||
-> Element msg
|
||||
tab data =
|
||||
Widget.tab
|
||||
({ primary = data.color, onPrimary = data.color }
|
||||
|> singlePalette
|
||||
|> Material.tab
|
||||
)
|
||||
{ tabs =
|
||||
{ onSelect = data.onSelect >> Just
|
||||
, options = data.items
|
||||
, selected = Just data.selected
|
||||
}
|
||||
, content = \_ -> data.content data.selected
|
||||
}
|
||||
|
||||
|
||||
{-| A text button representing an important action within a group.
|
||||
-}
|
||||
textButton :
|
||||
{ icon : Icon msg
|
||||
, onPress : Maybe msg
|
||||
, text : String
|
||||
, color : Color
|
||||
}
|
||||
-> Element msg
|
||||
textButton data =
|
||||
Widget.button
|
||||
({ primary = data.color, onPrimary = data.color }
|
||||
|> singlePalette
|
||||
|> Material.textButton
|
||||
)
|
||||
{ text = data.text, icon = data.icon, onPress = data.onPress }
|
||||
|
||||
|
||||
{-| Text input element.
|
||||
-}
|
||||
textInput :
|
||||
{ color : Color
|
||||
, label : String
|
||||
, onChange : String -> msg
|
||||
, placeholder : Maybe String
|
||||
, text : String
|
||||
}
|
||||
-> Element msg
|
||||
textInput data =
|
||||
Widget.textInput
|
||||
({ primary = data.color, onPrimary = data.color }
|
||||
|> singlePalette
|
||||
|> Material.textInput
|
||||
|> Customize.elementRow [ Element.width Element.fill ]
|
||||
)
|
||||
{ chips = []
|
||||
, text = data.text
|
||||
, placeholder =
|
||||
data.placeholder
|
||||
|> Maybe.map Element.text
|
||||
|> Maybe.map (Element.Input.placeholder [])
|
||||
, label = data.label
|
||||
, onChange = data.onChange
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
module Main exposing (..)
|
||||
|
||||
import Browser
|
||||
import Browser.Dom
|
||||
import Browser.Events
|
||||
import Element exposing (Element)
|
||||
import Element.Background
|
||||
import Task
|
||||
import Theme
|
||||
import Items.LoginScreen as LoginScreen
|
||||
import Items.VaultScreen as VaultScreen
|
||||
import Items.WelcomeScreen as WelcomeScreen
|
||||
import Element.Font
|
||||
import Items.VaultScreen as VaultScreen
|
||||
|
||||
|
||||
main : Program () Model Msg
|
||||
main =
|
||||
Browser.document
|
||||
{ init = init
|
||||
, subscriptions = subscriptions
|
||||
, update = update
|
||||
, view = view
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ flavor : Theme.Flavor
|
||||
, height : Int
|
||||
, screen : Screen
|
||||
, width : Int
|
||||
}
|
||||
|
||||
type Screen
|
||||
= ScreenLogin LoginScreen.Model
|
||||
| ScreenWelcome WelcomeScreen.Model
|
||||
| ScreenVault WelcomeScreen.Model Int VaultScreen.Model
|
||||
|
||||
type Msg
|
||||
= OnScreenLogin LoginScreen.Msg
|
||||
| OnScreenVault Int VaultScreen.Msg
|
||||
| OnScreenWelcome WelcomeScreen.Msg
|
||||
| OnSelectVault Int
|
||||
| Pass
|
||||
| ScreenSize { height : Int, width : Int }
|
||||
| SetFlavor Theme.Flavor
|
||||
|
||||
|
||||
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
|
||||
OnScreenLogin m ->
|
||||
case model.screen of
|
||||
ScreenLogin mdl ->
|
||||
case LoginScreen.update m mdl of
|
||||
newMdl ->
|
||||
( { model | screen = ScreenLogin newMdl }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
_ ->
|
||||
( model, Cmd.none )
|
||||
|
||||
OnScreenVault i m ->
|
||||
case model.screen of
|
||||
ScreenVault welcomeMdl j mdl ->
|
||||
if i == j then
|
||||
case VaultScreen.update m mdl of
|
||||
( newMdl, cmd ) ->
|
||||
( { model | screen = ScreenVault welcomeMdl i newMdl }
|
||||
, Cmd.map (OnScreenVault i) cmd
|
||||
)
|
||||
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 i ->
|
||||
case model.screen of
|
||||
ScreenVault welcomeMdl j _ ->
|
||||
if i == j then
|
||||
( model, Cmd.none )
|
||||
else
|
||||
( { model | screen = ScreenVault welcomeMdl i VaultScreen.init }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
ScreenWelcome mdl ->
|
||||
( { model | screen = ScreenVault mdl i VaultScreen.init }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
_ ->
|
||||
( model, 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 =
|
||||
case model.screen of
|
||||
ScreenLogin mdl ->
|
||||
LoginScreen.view
|
||||
{ colorBackground = Theme.base model.flavor
|
||||
, colorMain = Theme.mauve model.flavor
|
||||
, colorMenu = Theme.mantle model.flavor
|
||||
, colorText = Theme.text model.flavor
|
||||
, colorTextField = Theme.surface0 model.flavor
|
||||
, flavor = model.flavor
|
||||
, height = model.height
|
||||
, model = mdl
|
||||
, onFlavorPick = SetFlavor
|
||||
, onSubmit = always Pass
|
||||
, toMsg = OnScreenLogin
|
||||
, width = model.width
|
||||
}
|
||||
|
||||
ScreenVault welcomeMdl i mdl ->
|
||||
case WelcomeScreen.getVault i welcomeMdl of
|
||||
Just vault ->
|
||||
VaultScreen.view
|
||||
{ colorSelectedRoom = Theme.mantle model.flavor
|
||||
, colorText = Theme.text model.flavor
|
||||
, height = model.height
|
||||
, model = mdl
|
||||
, onVaultUpdate = always Pass
|
||||
, toMsg = OnScreenVault i
|
||||
, vault = vault
|
||||
, width = model.width
|
||||
}
|
||||
|
||||
Nothing ->
|
||||
viewScreen { model | screen = ScreenWelcome welcomeMdl }
|
||||
|
||||
ScreenWelcome mdl ->
|
||||
WelcomeScreen.view
|
||||
{ colorBackground = Theme.base model.flavor
|
||||
, colorBackground2 = Theme.mantle model.flavor
|
||||
, colorMain = Theme.mauve model.flavor
|
||||
, colorMenu = Theme.surface0 model.flavor
|
||||
, colorText = Theme.text model.flavor
|
||||
, colorTextField = Theme.surface1 model.flavor
|
||||
, flavor = model.flavor
|
||||
, height = model.height
|
||||
, model = mdl
|
||||
, onFlavorPick = SetFlavor
|
||||
, onSelectVault = OnSelectVault
|
||||
, toMsg = OnScreenWelcome
|
||||
, width = model.width
|
||||
}
|
||||
|
|
@ -0,0 +1,583 @@
|
|||
module Theme exposing (..)
|
||||
|
||||
{-|
|
||||
|
||||
|
||||
# Theme
|
||||
|
||||
The Theme helps pick colors from different color schemes.
|
||||
|
||||
-}
|
||||
|
||||
import Catppuccin.Frappe as CF
|
||||
import Catppuccin.Latte as CL
|
||||
import Catppuccin.Macchiato as CA
|
||||
import Catppuccin.Mocha as CO
|
||||
import Color
|
||||
import Element
|
||||
import Element.Background
|
||||
|
||||
|
||||
{-| Catppuccin flavor used for display.
|
||||
-}
|
||||
type Flavor
|
||||
= Frappe
|
||||
| Latte
|
||||
| Macchiato
|
||||
| Mocha
|
||||
|
||||
|
||||
background : (Flavor -> Color.Color) -> Flavor -> Element.Attribute msg
|
||||
background toColor =
|
||||
toColor >> toElmUiColor >> Element.Background.color
|
||||
|
||||
|
||||
toElmUiColor : Color.Color -> Element.Color
|
||||
toElmUiColor =
|
||||
Color.toRgba >> Element.fromRgb
|
||||
|
||||
|
||||
rosewater : Flavor -> Color.Color
|
||||
rosewater flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.rosewater
|
||||
|
||||
Latte ->
|
||||
CL.rosewater
|
||||
|
||||
Macchiato ->
|
||||
CA.rosewater
|
||||
|
||||
Mocha ->
|
||||
CO.rosewater
|
||||
|
||||
|
||||
rosewaterUI : Flavor -> Element.Color
|
||||
rosewaterUI =
|
||||
rosewater >> toElmUiColor
|
||||
|
||||
|
||||
flamingo : Flavor -> Color.Color
|
||||
flamingo flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.flamingo
|
||||
|
||||
Latte ->
|
||||
CL.flamingo
|
||||
|
||||
Macchiato ->
|
||||
CA.flamingo
|
||||
|
||||
Mocha ->
|
||||
CO.flamingo
|
||||
|
||||
|
||||
flamingoUI : Flavor -> Element.Color
|
||||
flamingoUI =
|
||||
flamingo >> toElmUiColor
|
||||
|
||||
|
||||
pink : Flavor -> Color.Color
|
||||
pink flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.pink
|
||||
|
||||
Latte ->
|
||||
CL.pink
|
||||
|
||||
Macchiato ->
|
||||
CA.pink
|
||||
|
||||
Mocha ->
|
||||
CO.pink
|
||||
|
||||
|
||||
pinkUI : Flavor -> Element.Color
|
||||
pinkUI =
|
||||
pink >> toElmUiColor
|
||||
|
||||
|
||||
mauve : Flavor -> Color.Color
|
||||
mauve flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.mauve
|
||||
|
||||
Latte ->
|
||||
CL.mauve
|
||||
|
||||
Macchiato ->
|
||||
CA.mauve
|
||||
|
||||
Mocha ->
|
||||
CO.mauve
|
||||
|
||||
|
||||
mauveUI : Flavor -> Element.Color
|
||||
mauveUI =
|
||||
mauve >> toElmUiColor
|
||||
|
||||
|
||||
red : Flavor -> Color.Color
|
||||
red flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.red
|
||||
|
||||
Latte ->
|
||||
CL.red
|
||||
|
||||
Macchiato ->
|
||||
CA.red
|
||||
|
||||
Mocha ->
|
||||
CO.red
|
||||
|
||||
|
||||
redUI : Flavor -> Element.Color
|
||||
redUI =
|
||||
red >> toElmUiColor
|
||||
|
||||
|
||||
maroon : Flavor -> Color.Color
|
||||
maroon flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.maroon
|
||||
|
||||
Latte ->
|
||||
CL.maroon
|
||||
|
||||
Macchiato ->
|
||||
CA.maroon
|
||||
|
||||
Mocha ->
|
||||
CO.maroon
|
||||
|
||||
|
||||
maroonUI : Flavor -> Element.Color
|
||||
maroonUI =
|
||||
maroon >> toElmUiColor
|
||||
|
||||
|
||||
peach : Flavor -> Color.Color
|
||||
peach flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.peach
|
||||
|
||||
Latte ->
|
||||
CL.peach
|
||||
|
||||
Macchiato ->
|
||||
CA.peach
|
||||
|
||||
Mocha ->
|
||||
CO.peach
|
||||
|
||||
|
||||
peachUI : Flavor -> Element.Color
|
||||
peachUI =
|
||||
peach >> toElmUiColor
|
||||
|
||||
|
||||
yellow : Flavor -> Color.Color
|
||||
yellow flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.yellow
|
||||
|
||||
Latte ->
|
||||
CL.yellow
|
||||
|
||||
Macchiato ->
|
||||
CA.yellow
|
||||
|
||||
Mocha ->
|
||||
CO.yellow
|
||||
|
||||
|
||||
yellowUI : Flavor -> Element.Color
|
||||
yellowUI =
|
||||
yellow >> toElmUiColor
|
||||
|
||||
|
||||
green : Flavor -> Color.Color
|
||||
green flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.green
|
||||
|
||||
Latte ->
|
||||
CL.green
|
||||
|
||||
Macchiato ->
|
||||
CA.green
|
||||
|
||||
Mocha ->
|
||||
CO.green
|
||||
|
||||
|
||||
greenUI : Flavor -> Element.Color
|
||||
greenUI =
|
||||
green >> toElmUiColor
|
||||
|
||||
|
||||
teal : Flavor -> Color.Color
|
||||
teal flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.teal
|
||||
|
||||
Latte ->
|
||||
CL.teal
|
||||
|
||||
Macchiato ->
|
||||
CA.teal
|
||||
|
||||
Mocha ->
|
||||
CO.teal
|
||||
|
||||
|
||||
tealUI : Flavor -> Element.Color
|
||||
tealUI =
|
||||
teal >> toElmUiColor
|
||||
|
||||
|
||||
sky : Flavor -> Color.Color
|
||||
sky flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.sky
|
||||
|
||||
Latte ->
|
||||
CL.sky
|
||||
|
||||
Macchiato ->
|
||||
CA.sky
|
||||
|
||||
Mocha ->
|
||||
CO.sky
|
||||
|
||||
|
||||
skyUI : Flavor -> Element.Color
|
||||
skyUI =
|
||||
sky >> toElmUiColor
|
||||
|
||||
|
||||
sapphire : Flavor -> Color.Color
|
||||
sapphire flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.sapphire
|
||||
|
||||
Latte ->
|
||||
CL.sapphire
|
||||
|
||||
Macchiato ->
|
||||
CA.sapphire
|
||||
|
||||
Mocha ->
|
||||
CO.sapphire
|
||||
|
||||
|
||||
sapphireUI : Flavor -> Element.Color
|
||||
sapphireUI =
|
||||
sapphire >> toElmUiColor
|
||||
|
||||
|
||||
blue : Flavor -> Color.Color
|
||||
blue flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.blue
|
||||
|
||||
Latte ->
|
||||
CL.blue
|
||||
|
||||
Macchiato ->
|
||||
CA.blue
|
||||
|
||||
Mocha ->
|
||||
CO.blue
|
||||
|
||||
|
||||
blueUI : Flavor -> Element.Color
|
||||
blueUI =
|
||||
blue >> toElmUiColor
|
||||
|
||||
|
||||
lavender : Flavor -> Color.Color
|
||||
lavender flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.lavender
|
||||
|
||||
Latte ->
|
||||
CL.lavender
|
||||
|
||||
Macchiato ->
|
||||
CA.lavender
|
||||
|
||||
Mocha ->
|
||||
CO.lavender
|
||||
|
||||
|
||||
lavenderUI : Flavor -> Element.Color
|
||||
lavenderUI =
|
||||
lavender >> toElmUiColor
|
||||
|
||||
|
||||
text : Flavor -> Color.Color
|
||||
text flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.text
|
||||
|
||||
Latte ->
|
||||
CL.text
|
||||
|
||||
Macchiato ->
|
||||
CA.text
|
||||
|
||||
Mocha ->
|
||||
CO.text
|
||||
|
||||
|
||||
textUI : Flavor -> Element.Color
|
||||
textUI =
|
||||
text >> toElmUiColor
|
||||
|
||||
|
||||
subtext1 : Flavor -> Color.Color
|
||||
subtext1 flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.subtext1
|
||||
|
||||
Latte ->
|
||||
CL.subtext1
|
||||
|
||||
Macchiato ->
|
||||
CA.subtext1
|
||||
|
||||
Mocha ->
|
||||
CO.subtext1
|
||||
|
||||
|
||||
subtext1UI : Flavor -> Element.Color
|
||||
subtext1UI =
|
||||
subtext1 >> toElmUiColor
|
||||
|
||||
|
||||
subtext0 : Flavor -> Color.Color
|
||||
subtext0 flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.subtext0
|
||||
|
||||
Latte ->
|
||||
CL.subtext0
|
||||
|
||||
Macchiato ->
|
||||
CA.subtext0
|
||||
|
||||
Mocha ->
|
||||
CO.subtext0
|
||||
|
||||
|
||||
subtext0UI : Flavor -> Element.Color
|
||||
subtext0UI =
|
||||
subtext0 >> toElmUiColor
|
||||
|
||||
|
||||
overlay2 : Flavor -> Color.Color
|
||||
overlay2 flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.overlay2
|
||||
|
||||
Latte ->
|
||||
CL.overlay2
|
||||
|
||||
Macchiato ->
|
||||
CA.overlay2
|
||||
|
||||
Mocha ->
|
||||
CO.overlay2
|
||||
|
||||
|
||||
overlay2UI : Flavor -> Element.Color
|
||||
overlay2UI =
|
||||
overlay2 >> toElmUiColor
|
||||
|
||||
|
||||
overlay1 : Flavor -> Color.Color
|
||||
overlay1 flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.overlay1
|
||||
|
||||
Latte ->
|
||||
CL.overlay1
|
||||
|
||||
Macchiato ->
|
||||
CA.overlay1
|
||||
|
||||
Mocha ->
|
||||
CO.overlay1
|
||||
|
||||
|
||||
overlay1UI : Flavor -> Element.Color
|
||||
overlay1UI =
|
||||
overlay1 >> toElmUiColor
|
||||
|
||||
|
||||
overlay0 : Flavor -> Color.Color
|
||||
overlay0 flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.overlay0
|
||||
|
||||
Latte ->
|
||||
CL.overlay0
|
||||
|
||||
Macchiato ->
|
||||
CA.overlay0
|
||||
|
||||
Mocha ->
|
||||
CO.overlay0
|
||||
|
||||
|
||||
overlay0UI : Flavor -> Element.Color
|
||||
overlay0UI =
|
||||
overlay0 >> toElmUiColor
|
||||
|
||||
|
||||
surface2 : Flavor -> Color.Color
|
||||
surface2 flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.surface2
|
||||
|
||||
Latte ->
|
||||
CL.surface2
|
||||
|
||||
Macchiato ->
|
||||
CA.surface2
|
||||
|
||||
Mocha ->
|
||||
CO.surface2
|
||||
|
||||
|
||||
surface2UI : Flavor -> Element.Color
|
||||
surface2UI =
|
||||
surface2 >> toElmUiColor
|
||||
|
||||
|
||||
surface1 : Flavor -> Color.Color
|
||||
surface1 flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.surface1
|
||||
|
||||
Latte ->
|
||||
CL.surface1
|
||||
|
||||
Macchiato ->
|
||||
CA.surface1
|
||||
|
||||
Mocha ->
|
||||
CO.surface1
|
||||
|
||||
|
||||
surface1UI : Flavor -> Element.Color
|
||||
surface1UI =
|
||||
surface1 >> toElmUiColor
|
||||
|
||||
|
||||
surface0 : Flavor -> Color.Color
|
||||
surface0 flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.surface0
|
||||
|
||||
Latte ->
|
||||
CL.surface0
|
||||
|
||||
Macchiato ->
|
||||
CA.surface0
|
||||
|
||||
Mocha ->
|
||||
CO.surface0
|
||||
|
||||
|
||||
surface0UI : Flavor -> Element.Color
|
||||
surface0UI =
|
||||
surface0 >> toElmUiColor
|
||||
|
||||
|
||||
base : Flavor -> Color.Color
|
||||
base flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.base
|
||||
|
||||
Latte ->
|
||||
CL.base
|
||||
|
||||
Macchiato ->
|
||||
CA.base
|
||||
|
||||
Mocha ->
|
||||
CO.base
|
||||
|
||||
|
||||
baseUI : Flavor -> Element.Color
|
||||
baseUI =
|
||||
base >> toElmUiColor
|
||||
|
||||
|
||||
mantle : Flavor -> Color.Color
|
||||
mantle flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.mantle
|
||||
|
||||
Latte ->
|
||||
CL.mantle
|
||||
|
||||
Macchiato ->
|
||||
CA.mantle
|
||||
|
||||
Mocha ->
|
||||
CO.mantle
|
||||
|
||||
|
||||
mantleUI : Flavor -> Element.Color
|
||||
mantleUI =
|
||||
mantle >> toElmUiColor
|
||||
|
||||
|
||||
crust : Flavor -> Color.Color
|
||||
crust flavor =
|
||||
case flavor of
|
||||
Frappe ->
|
||||
CF.crust
|
||||
|
||||
Latte ->
|
||||
CL.crust
|
||||
|
||||
Macchiato ->
|
||||
CA.crust
|
||||
|
||||
Mocha ->
|
||||
CO.crust
|
||||
|
||||
|
||||
crustUI : Flavor -> Element.Color
|
||||
crustUI =
|
||||
crust >> toElmUiColor
|
Loading…
Reference in New Issue