Move to using shared material library.
Build / Build docker images. (push) Has been cancelled

This commit is contained in:
Gareth Latty
2022-05-31 17:30:13 +01:00
parent a6035da2e6
commit d3e816eddb
58 changed files with 879 additions and 1681 deletions
+5
View File
@@ -16,6 +16,11 @@ updates:
schedule:
interval: "weekly"
- package-ecosystem: "gitsubmodule"
directory: "/client/elm-material"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/server"
schedule:
+2
View File
@@ -19,6 +19,8 @@ jobs:
steps:
- name: Checkout repository.
uses: actions/checkout@v3
with:
submodules: true
- name: Get version from tag.
uses: little-core-labs/get-git-tag@v3.0.2
+3
View File
@@ -0,0 +1,3 @@
[submodule "client/elm-material"]
path = client/elm-material
url = git@github.com:Lattyware/elm-material.git
+3 -1
View File
@@ -17,9 +17,11 @@ RUN ["apk", "add", "--no-cache", "python3", "make", "g++"]
ENV MD_VERSION ${VERSION}
ENV WEBPACK_MODE ${MODE}
COPY ["./elm-material/package.json", "./elm-material/package-lock.json", "./"]
COPY ["./package.json", "./package-lock.json", "./"]
RUN ["npm", "ci"]
COPY ["./elm-material", "./elm-material"]
COPY ["./tsconfig.json", "postcss.config.js", "./webpack.config.js", "./elm.json", "./"]
COPY ["./src", "./src"]
COPY ["./assets", "./assets"]
@@ -49,5 +51,5 @@ LABEL org.opencontainers.image.licenses="AGPL-3.0+"
LABEL org.opencontainers.image.title="Massive Decks (Client)"
LABEL org.opencontainers.image.description="The web client for Massive Decks, a comedy party game."
COPY --from=static ["/md/dist", "/usr/share/nginx/html/"]
COPY --from=static ["/", "/usr/share/nginx/html/"]
COPY ["./nginx.conf", "/etc/nginx/nginx.conf"]
Submodule client/elm-material added at 035cca888c
+2 -1
View File
@@ -1,7 +1,8 @@
{
"type": "application",
"source-directories": [
"./src/elm"
"./src/elm",
"./elm-material/src/elm"
],
"elm-version": "0.19.1",
"dependencies": {
+322 -246
View File
File diff suppressed because it is too large Load Diff
+2 -14
View File
@@ -22,22 +22,10 @@
"> 0.2%"
],
"dependencies": {
"@webcomponents/webcomponentsjs": "^2.6.0",
"@fortawesome/fontawesome-svg-core": "^6.1.1",
"@material/card": "^14.0.0",
"@material/mwc-button": "^0.26.1",
"@material/mwc-fab": "^0.26.1",
"@material/mwc-icon-button": "^0.26.1",
"@material/mwc-linear-progress": "^0.26.1",
"@material/mwc-menu": "^0.26.1",
"@material/mwc-select": "^0.26.1",
"@material/mwc-slider": "^0.26.1",
"@material/mwc-switch": "^0.26.1",
"@material/mwc-tab": "^0.26.1",
"@material/mwc-tab-bar": "^0.26.1",
"@material/mwc-textarea": "^0.26.1",
"@material/mwc-textfield": "^0.26.1",
"elm-material": "file:elm-material",
"@polymer/paper-tooltip": "^3.0.1",
"@webcomponents/webcomponentsjs": "^2.5.0",
"canvas-confetti": "^1.3.2"
},
"devDependencies": {
@@ -24,7 +24,6 @@ import MassiveDecks.Strings as Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html as Html
import MassiveDecks.Util.Maybe as Maybe
import MassiveDecks.Util.NeList as NeList
import Material.Button as Button
import Material.IconButton as IconButton
import Material.TextArea as TextArea
@@ -132,10 +131,13 @@ view wrap shared { parts, selected, error } =
addSlot =
addAction (Parts.Slot nextSlotIndex Part.NoTransform Part.NoStyle)
inlineButton string icon action =
Button.view Button.Outlined Button.Padded (string |> Lang.string shared) (Just icon) action
inlineControls =
Html.p []
[ Button.view shared Button.Outlined Strings.AddText Strings.AddText (Icon.add |> Icon.view) [ addAction (Parts.Text "..." Part.NoStyle) |> HtmlE.onClick ]
, Button.view shared Button.Outlined Strings.AddSlot Strings.AddSlot (Icon.add |> Icon.view) [ addSlot |> HtmlE.onClick ]
[ inlineButton Strings.AddText (Icon.add |> Icon.view) (Parts.Text "..." Part.NoStyle |> addAction |> Just)
, inlineButton Strings.AddSlot (Icon.add |> Icon.view) (Just addSlot)
]
selectedPart =
@@ -166,13 +168,12 @@ view wrap shared { parts, selected, error } =
in
Form.section shared
"part-editor"
(TextField.view shared
Strings.Blank
(TextField.viewWithAttrs
(Strings.Blank |> Lang.string shared)
TextField.Number
(slotIndex + 1 |> String.fromInt)
[ HtmlA.min "1"
, HtmlE.onInput setSlotIndex
]
(setSlotIndex |> Just)
[ HtmlA.min "1" ]
)
[ Message.info Strings.SlotIndexExplanation ]
@@ -242,18 +243,21 @@ controls wrap shared max selected =
move by test =
index |> Maybe.andThen (\i -> Move i by |> wrap |> Maybe.justIf (test i))
iconButton string icon action =
IconButton.view icon (string |> Lang.string shared) action
generalControls =
[ IconButton.view shared Strings.Remove (Icon.remove |> NeList.just) (index |> Maybe.map (Remove >> wrap))
, IconButton.view shared Strings.MoveLeft (Icon.left |> NeList.just) (move -1 ((<) 0))
, IconButton.view shared Strings.MoveRight (Icon.right |> NeList.just) (move 1 ((>) max))
[ iconButton Strings.Remove (Icon.remove |> Icon.view) (index |> Maybe.map (Remove >> wrap))
, iconButton Strings.MoveLeft (Icon.left |> Icon.view) (move -1 ((<) 0))
, iconButton Strings.MoveRight (Icon.right |> Icon.view) (move 1 ((>) max))
]
setIfDifferent old updated new =
index |> Maybe.andThen (\i -> Set i (updated new) |> wrap |> Maybe.justIf (old /= new))
styleControls setStyle =
[ IconButton.view shared Strings.Normal (Icon.normalText |> NeList.just) (setStyle Part.NoStyle)
, IconButton.view shared Strings.Emphasise (Icon.italicText |> NeList.just) (setStyle Part.Em)
[ iconButton Strings.Normal (Icon.normalText |> Icon.view) (setStyle Part.NoStyle)
, iconButton Strings.Emphasise (Icon.italicText |> Icon.view) (setStyle Part.Em)
]
transformControls setTransform =
@@ -261,9 +265,9 @@ controls wrap shared max selected =
textIcon text =
Icon.layers [] [ Icon.text [] text ]
in
[ IconButton.viewCustomIcon shared Strings.Normal (textIcon "aa") (setTransform Part.NoTransform)
, IconButton.viewCustomIcon shared Strings.Capitalise (textIcon "Aa") (setTransform Part.Capitalize)
, IconButton.viewCustomIcon shared Strings.UpperCase (textIcon "AA") (setTransform Part.UpperCase)
[ iconButton Strings.Normal (textIcon "aa") (setTransform Part.NoTransform)
, iconButton Strings.Capitalise (textIcon "Aa") (setTransform Part.Capitalize)
, iconButton Strings.UpperCase (textIcon "AA") (setTransform Part.UpperCase)
]
( replaceStyle, replaceTransform ) =
+5 -3
View File
@@ -196,14 +196,16 @@ generalEditor shared existing currentValue update submit noOp =
, meta = Nothing
}
in
( Select.view shared
{ label = Strings.DeckSource
( Select.view
{ label = Strings.DeckSource |> Lang.string shared
, idToString = generalToString
, idFromString = generalFromString
, selected = currentValue |> generalMatching |> Just
, wrap = Maybe.map (empty shared) >> Maybe.withDefault (default shared) >> update
, disabled = False
, fullWidth = True
, attrs = [ HtmlA.id "source-selector", HtmlA.class "primary" ]
}
[ HtmlA.id "source-selector", HtmlA.class "primary" ]
(enabledSources |> List.filterMap (Maybe.map toItem))
, editor shared existing currentValue update submit noOp
)
@@ -125,14 +125,16 @@ editor selected shared existing update _ _ =
}
in
Html.div [ HtmlA.class "primary" ]
[ Select.view shared
{ label = Strings.Deck
[ Select.view
{ label = Strings.Deck |> Lang.string shared
, idToString = toString
, idFromString = fromString shared.sources.builtIn
, selected = Just selected
, wrap = Maybe.withDefault (hardcoded "") >> Source.BuiltIn >> update
, disabled = False
, fullWidth = True
, attrs = [ HtmlA.id "built-in-selector" ]
}
[ HtmlA.id "built-in-selector" ]
(decks
|> NeList.toList
|> List.sortWith (sortClosestFirst (Lang.currentLanguage shared |> Lang.code) |> Order.map .language)
@@ -15,6 +15,7 @@ import MassiveDecks.Icon as Icon
import MassiveDecks.Model exposing (..)
import MassiveDecks.Pages.Lobby.Configure.Decks.Model exposing (DeckOrError)
import MassiveDecks.Strings as Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html as Html
import MassiveDecks.Util.Maybe as Maybe
import Material.Select as Select
@@ -111,14 +112,16 @@ editor selected shared existing update _ _ =
}
in
Html.span [ HtmlA.id "json-against-humanity-editor", HtmlA.class "primary" ]
[ Select.view shared
{ label = Strings.Deck
[ Select.view
{ label = Strings.Deck |> Lang.string shared
, idToString = toString
, idFromString = fromString shared.sources.jsonAgainstHumanity
, selected = Just selected
, wrap = Maybe.withDefault (hardcoded "") >> Source.JsonAgainstHumanity >> update
, disabled = False
, fullWidth = True
, attrs = [ HtmlA.id "built-in-selector" ]
}
[ HtmlA.id "built-in-selector" ]
(decks |> List.map deck)
]
@@ -6,8 +6,6 @@ module MassiveDecks.Card.Source.ManyDecks exposing
import FontAwesome as Icon
import Html as Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import Json.Decode as Json
import MassiveDecks.Card.Source.ManyDecks.Model exposing (..)
import MassiveDecks.Card.Source.Methods as Source
import MassiveDecks.Card.Source.Model as Source
@@ -93,15 +91,13 @@ problems dc () =
editor : DeckCode -> Shared -> List DeckOrError -> (Source.External -> msg) -> Maybe msg -> msg -> Html msg
editor dc shared _ update submit noOp =
Html.div [ HtmlA.class "primary" ]
[ TextField.view shared
Strings.ManyDecksDeckCodeTitle
[ TextField.viewWithReturn
(Strings.ManyDecksDeckCodeTitle |> Lang.string shared)
TextField.Text
(dc |> toString)
[ HtmlE.onInput (deckCode >> Source.ManyDecks >> update)
, HtmlE.keyCode
|> Json.map (\k -> submit |> Maybe.andThen (Maybe.justIf (k == 13)) |> Maybe.withDefault noOp)
|> HtmlE.on "keydown"
]
(deckCode >> Source.ManyDecks >> update |> Just)
(submit |> Maybe.withDefault noOp)
noOp
]
@@ -1,4 +1,4 @@
module MassiveDecks.Components.Menu exposing
module MassiveDecks.Components.ContextMenu exposing
( button
, link
, open
@@ -10,7 +10,7 @@ import FontAwesome as Icon exposing (Icon)
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Attributes.Aria as HtmlA
import MassiveDecks.Components.Menu.Model exposing (..)
import MassiveDecks.Components.ContextMenu.Model exposing (..)
import MassiveDecks.Model exposing (..)
import MassiveDecks.Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
@@ -22,25 +22,25 @@ import Material.Menu as Menu
{-| Toggle the state of a menu.
-}
toggle : State -> State
toggle : Menu.State -> Menu.State
toggle state =
case state of
Open ->
Closed
Menu.Open ->
Menu.Closed
Closed ->
Open
Menu.Closed ->
Menu.Open
{-| Get an open state from a boolean indicating if the menu is open.
-}
open : Bool -> State
open : Bool -> Menu.State
open isOpen =
if isOpen then
Open
Menu.Open
else
Closed
Menu.Closed
{-| Convenience function for a menu button.
@@ -59,7 +59,7 @@ link icon text description href =
{-| Render a menu to Html.
-}
view : Shared -> msg -> State -> Corner -> Html msg -> Menu msg -> Html msg
view : Shared -> msg -> Menu.State -> Menu.Corner -> Html msg -> Menu msg -> Html msg
view shared onClose state corner anchor menu =
Menu.view onClose state corner anchor (menu |> List.map (menuItem shared))
@@ -72,24 +72,30 @@ menuItem : Shared -> Part msg -> Html msg
menuItem shared mi =
case mi of
Button { icon, text, description } action ->
ListView.viewItem (ListView.action action)
(Just icon)
(description |> Lang.string shared)
Nothing
ListView.viewItem
(ListView.Button action)
(icon |> Icon.view |> Just)
([ description |> Lang.string shared |> Html.text ] |> Just)
Nothing
[ text |> Lang.string shared |> Html.text ]
Link { icon, text, description } href ->
let
linkify =
List.singleton
>> Html.blankA
[ href
|> Maybe.map HtmlA.href
|> Maybe.withDefault HtmlA.nothing
]
in
-- TODO: Deal with being disabled in a decent way.
Html.blankA [ href |> Maybe.map HtmlA.href |> Maybe.withDefault HtmlA.nothing ]
[ ListView.viewItem
ListView.Link
(Just icon)
(description |> Lang.string shared)
Nothing
Nothing
[ text |> Lang.string shared |> Html.text ]
]
ListView.viewItem
(ListView.Link linkify)
(icon |> Icon.view |> Just)
([ description |> Lang.string shared |> Html.text ] |> Just)
Nothing
[ text |> Lang.string shared |> Html.text ]
Separator ->
Html.li [ HtmlA.attribute "divider" "divider", HtmlA.role "separator" ] []
@@ -1,9 +1,7 @@
module MassiveDecks.Components.Menu.Model exposing
( Corner(..)
, Item
module MassiveDecks.Components.ContextMenu.Model exposing
( Item
, Menu
, Part(..)
, State(..)
)
import FontAwesome as Icon exposing (Icon)
@@ -32,23 +30,3 @@ type alias Item =
, text : MdString
, description : MdString
}
{-| The corner of the anchor element the menu should position itself at.
-}
type Corner
= TopLeft
| TopRight
| BottomLeft
| BottomRight
| TopStart
| TopEnd
| BottomStart
| BottomEnd
{-| If the menu is visible or not.
-}
type State
= Open
| Closed
@@ -21,7 +21,6 @@ import MassiveDecks.Model exposing (..)
import MassiveDecks.Models.MdError as MdError exposing (MdError)
import MassiveDecks.Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.NeList as NeList exposing (NeList(..))
import Material.IconButton as IconButton
import Svg.Attributes as Svg
@@ -137,4 +136,8 @@ internalMessage shared { severity, description, fixes } =
viewFix : Shared -> Fix msg -> Html msg
viewFix shared { icon, description, action } =
Html.li [] [ IconButton.view shared description (icon |> NeList.just) (Just action) ]
Html.li []
[ IconButton.view (icon |> Icon.view)
(description |> Lang.string shared)
(Just action)
]
@@ -30,13 +30,13 @@ view shared route model =
else
[ Html.div [ HtmlA.class "error-overlay" ]
[ Html.div [ HtmlA.class "actions" ]
[ IconButton.view shared
Strings.Close
(Icon.close |> NeList.just)
[ IconButton.view
(Icon.close |> Icon.view)
(Strings.Close |> Lang.string shared)
(Clear |> Global.ErrorMsg |> Just)
, IconButton.view shared
Strings.Refresh
(Icon.redo |> NeList.just)
, IconButton.view
(Icon.redo |> Icon.view)
(Strings.Refresh |> Lang.string shared)
(Just Global.Refresh)
]
, Card.view [ HtmlA.class "help" ]
+29 -28
View File
@@ -13,6 +13,7 @@ import Browser.Events as Browser
import Dict exposing (Dict)
import FontAwesome as Icon
import FontAwesome.Attributes as Icon
import FontAwesome.Layering as Icon
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
@@ -1173,14 +1174,13 @@ viewWinner wrapLobby shared users localUser winners =
let
configureNextGame =
if users |> Dict.get localUser |> Maybe.map (.privilege >> (==) User.Privileged) |> Maybe.withDefault False then
Button.view shared
Button.viewWithAttrs
Button.Raised
Strings.ConfigureNextGame
Strings.ConfigureNextGame
(Icon.configure |> Icon.view)
[ HtmlA.id "new-game-config"
, Lobby.Configure |> Just |> Lobby.ChangeSection |> wrapLobby |> HtmlE.onClick
]
Button.Padded
(Strings.ConfigureNextGame |> Lang.string shared)
(Icon.configure |> Icon.view |> Just)
(Lobby.Configure |> Just |> Lobby.ChangeSection |> wrapLobby |> Just)
[ HtmlA.id "new-game-config" ]
else
Html.nothing
@@ -1257,7 +1257,7 @@ viewRound wrap shared auth timeAnchor config users model =
-- TODO: Hide this when at top. Waiting on native elm scroll events, as currently we'd have to ping constantly.
, Html.div [ HtmlA.class "scroll-top" ]
[ IconButton.view shared Strings.ScrollToTop (Icon.toTop |> NeList.just) (ScrollToTop |> wrap |> Just) ]
[ IconButton.view (Icon.toTop |> Icon.view) (Strings.ScrollToTop |> Lang.string shared) (ScrollToTop |> wrap |> Just) ]
, renderDiscarded wrap shared config users model.discarded |> Maybe.withDefault Html.nothing
]
@@ -1278,12 +1278,12 @@ renderDiscarded wrap shared config users discarded =
[ Strings.Discarded { player = name } |> Lang.html shared
]
, card |> Response.view shared config Card.Front []
, Button.view shared
, Button.view
Button.Standard
Strings.Accept
Strings.Accept
(Icon.accept |> Icon.view)
[ DismissDiscard |> wrap |> HtmlE.onClick ]
Button.Padded
(Strings.Accept |> Lang.string shared)
(Icon.accept |> Icon.view |> Just)
(DismissDiscard |> wrap |> Just)
]
]
|> Just
@@ -1297,15 +1297,16 @@ toggleHelp wrap shared enabled =
let
extra =
if enabled then
[ Icon.slash |> Icon.styled [ Icon.fw ] ]
[ Icon.slash |> Icon.styled [ Icon.fw ] |> Icon.view ]
else
[]
icon =
Icon.help |> Icon.styled [ Icon.fw ] |> NeList.just |> NeList.extend extra
((Icon.help |> Icon.styled [ Icon.fw ] |> Icon.view) :: extra)
|> Icon.layers []
in
IconButton.view shared Strings.ViewHelpAction icon (ToggleHelp |> wrap |> Just)
IconButton.view icon (Strings.ViewHelpAction |> Lang.string shared) (ToggleHelp |> wrap |> Just)
timer : Time.Anchor -> Model -> Html msg
@@ -1406,9 +1407,9 @@ minorActions wrap shared auth game helpEnabled =
enforceTimeLimit =
if timedOut && game.rules.stages.mode == Rules.Soft then
IconButton.view shared
Strings.EnforceTimeLimitAction
(Icon.skip |> NeList.just)
IconButton.view
(Icon.skip |> Icon.view)
(Strings.EnforceTimeLimitAction |> Lang.string shared)
(EnforceTimeLimit |> wrap |> Just)
|> Just
@@ -1439,17 +1440,17 @@ discardButton wrap shared game =
_ ->
Nothing
in
IconButton.view shared
Strings.Discard
(Icon.discard |> NeList.just)
IconButton.view
(Icon.discard |> Icon.view)
(Strings.Discard |> Lang.string shared)
action
historyButton : (Msg -> msg) -> Shared -> Html msg
historyButton wrap shared =
IconButton.view shared
Strings.ViewGameHistoryAction
(Icon.history |> NeList.just)
IconButton.view
(Icon.history |> Icon.view)
(Strings.ViewGameHistoryAction |> Lang.string shared)
(ToggleHistoryView |> wrap |> Just)
@@ -1463,9 +1464,9 @@ rebootButton wrap shared score reboot =
else
Redraw |> wrap |> Just
in
IconButton.view shared
({ cost = reboot.cost } |> Strings.HouseRuleRebootAction)
(Icon.random |> NeList.just)
IconButton.view
(Icon.random |> Icon.view)
({ cost = reboot.cost } |> Strings.HouseRuleRebootAction |> Lang.string shared)
action
+4 -3
View File
@@ -8,6 +8,7 @@ import MassiveDecks.Game.Messages as Game exposing (Msg)
import MassiveDecks.Icon as Icon
import MassiveDecks.Model exposing (..)
import MassiveDecks.Strings as Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import Material.Fab as Fab
@@ -64,10 +65,10 @@ viewSingle wrap shared visible action =
Discard ->
IconView Icon.discard normal Fab.Mini Strings.HouseRuleNeverHaveIEver Game.Discard
in
Fab.view shared
Fab.view
type_
title
icon
(title |> Lang.string shared)
(icon |> Icon.view)
(onClick |> wrap |> Just)
(HtmlA.classList [ ( "action", True ), ( "exited", visible /= Just action ) ] :: attrs)
+4 -4
View File
@@ -16,9 +16,9 @@ import MassiveDecks.Icon as Icon
import MassiveDecks.Model exposing (Shared)
import MassiveDecks.Pages.Lobby.Configure.Model exposing (Config)
import MassiveDecks.Strings as Strings
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.User as User exposing (User)
import MassiveDecks.Util.Maybe as Maybe
import MassiveDecks.Util.NeList as NeList
import Material.IconButton as IconButton
@@ -26,9 +26,9 @@ view : (Msg -> msg) -> Shared -> Config -> Dict User.Id User -> String -> List (
view wrap shared config users name history =
[ Html.div [ HtmlA.id "top-content" ]
[ Html.div [ HtmlA.id "minor-actions" ]
[ IconButton.view shared
Strings.ViewGameHistoryAction
(Icon.back |> NeList.just)
[ IconButton.view
(Icon.back |> Icon.view)
(Strings.ViewGameHistoryAction |> Lang.string shared)
(ToggleHistoryView |> wrap |> Just)
]
]
+47 -46
View File
@@ -23,9 +23,9 @@ import MassiveDecks.Animated as Animated exposing (Animated)
import MassiveDecks.Card.Model as Card
import MassiveDecks.Cast.Client as Cast
import MassiveDecks.Cast.Model as Cast
import MassiveDecks.Components.ContextMenu as ContextMenu
import MassiveDecks.Components.ContextMenu.Model as ContextMenu
import MassiveDecks.Components.Form.Message as Message exposing (Message)
import MassiveDecks.Components.Menu as Menu
import MassiveDecks.Components.Menu.Model as Menu
import MassiveDecks.Error as MdError
import MassiveDecks.Error.Model as Error exposing (Error)
import MassiveDecks.Game as Game
@@ -64,6 +64,7 @@ import MassiveDecks.Util.NeList as NeList
import Material.Button as Button
import Material.Card as Card
import Material.IconButton as IconButton
import Material.Menu as Menu
changeRoute : Shared -> Route -> Model -> Route.Fork ( Model, Cmd msg )
@@ -573,9 +574,9 @@ viewWithUsers wrap wrapSettings shared s viewContent model =
(Html.div [ HtmlA.id "top-bar" ]
[ Html.div [ HtmlA.class "left" ]
(List.concat
[ [ IconButton.view shared
Strings.ToggleUserList
(usersIcon |> Icon.styled [ Icon.lg ] |> NeList.just)
[ [ IconButton.view
(usersIcon |> Icon.styled [ Icon.lg ] |> Icon.view)
(Strings.ToggleUserList |> Lang.string shared)
(usersShown |> not |> Settings.ChangeOpenUserList |> wrapSettings |> Just)
, lobbyMenu wrap shared model.gameMenu model.route s audienceMode localUser localPlayer (maybeGame |> Maybe.map .game)
]
@@ -654,7 +655,7 @@ lobbyMenu : (Msg -> msg) -> Shared -> Menu.State -> Route -> Section -> Bool ->
lobbyMenu wrap shared menuState r s audienceMode user player game =
let
lobbyMenuItems =
[ Menu.button Icon.invite Strings.InvitePlayers Strings.InvitePlayersDescription (ToggleInviteDialog |> wrap |> Just) ]
[ ContextMenu.button Icon.invite Strings.InvitePlayers Strings.InvitePlayersDescription (ToggleInviteDialog |> wrap |> Just) ]
setPresence =
setPresenceMenuItem wrap player
@@ -662,17 +663,17 @@ lobbyMenu wrap shared menuState r s audienceMode user player game =
playerState role =
case role of
User.Player ->
Menu.button Icon.spectator Strings.BecomeSpectator Strings.BecomeSpectatorDescription (SetUserRole Nothing User.Spectator |> wrap |> Just)
ContextMenu.button Icon.spectator Strings.BecomeSpectator Strings.BecomeSpectatorDescription (SetUserRole Nothing User.Spectator |> wrap |> Just)
User.Spectator ->
Menu.button Icon.player Strings.BecomePlayer Strings.BecomePlayerDescription (SetUserRole Nothing User.Player |> wrap |> Just)
ContextMenu.button Icon.player Strings.BecomePlayer Strings.BecomePlayerDescription (SetUserRole Nothing User.Player |> wrap |> Just)
userLobbyMenuItems =
[ setPresence |> Just
, user
|> Maybe.andThen (\u -> u |> Maybe.justIf (u.privilege == User.Privileged || not audienceMode))
|> Maybe.map (.role >> playerState)
, Menu.button
, ContextMenu.button
Icon.leave
Strings.LeaveGame
Strings.LeaveGameDescription
@@ -682,22 +683,22 @@ lobbyMenu wrap shared menuState r s audienceMode user player game =
|> List.filterMap identity
viewMenuItems =
[ Menu.link Icon.spectator Strings.Spectate Strings.SpectateDescription ({ r | section = Just Spectate } |> Route.Lobby |> Route.url |> Just)
[ ContextMenu.link Icon.spectator Strings.Spectate Strings.SpectateDescription ({ r | section = Just Spectate } |> Route.Lobby |> Route.url |> Just)
, case s of
Configure ->
Menu.button Icon.start Strings.ReturnViewToGame Strings.ReturnViewToGameDescription (Nothing |> ChangeSection |> wrap |> Maybe.justIf (game /= Nothing))
ContextMenu.button Icon.start Strings.ReturnViewToGame Strings.ReturnViewToGameDescription (Nothing |> ChangeSection |> wrap |> Maybe.justIf (game /= Nothing))
_ ->
Menu.button Icon.configure Strings.ViewConfiguration Strings.ViewConfigurationDescription (Configure |> Just |> ChangeSection |> wrap |> Just)
ContextMenu.button Icon.configure Strings.ViewConfiguration Strings.ViewConfigurationDescription (Configure |> Just |> ChangeSection |> wrap |> Just)
]
privilegedLobbyMenuItems =
[ Menu.button Icon.end Strings.EndGame Strings.EndGameDescription (game |> Maybe.andThen (\g -> EndGame |> wrap |> Maybe.justIf (g.winner == Nothing)))
[ ContextMenu.button Icon.end Strings.EndGame Strings.EndGameDescription (game |> Maybe.andThen (\g -> EndGame |> wrap |> Maybe.justIf (g.winner == Nothing)))
]
mdMenuItems =
[ Menu.link Icon.info Strings.AboutTheGame Strings.AboutTheGameDescription (Just "https://github.com/lattyware/massivedecks")
, Menu.link Icon.bug Strings.ReportError Strings.ReportErrorDescription (Just "https://github.com/Lattyware/massivedecks/issues/new")
[ ContextMenu.link Icon.info Strings.AboutTheGame Strings.AboutTheGameDescription (Just "https://github.com/lattyware/massivedecks")
, ContextMenu.link Icon.bug Strings.ReportError Strings.ReportErrorDescription (Just "https://github.com/Lattyware/massivedecks/issues/new")
]
menuItems =
@@ -709,16 +710,16 @@ lobbyMenu wrap shared menuState r s audienceMode user player game =
]
separatedMenuItems =
menuItems |> List.filterMap identity |> List.intersperse [ Menu.Separator ] |> List.concat
menuItems |> List.filterMap identity |> List.intersperse [ ContextMenu.Separator ] |> List.concat
in
Menu.view shared
ContextMenu.view shared
(Menu.Closed |> SetGameMenuState |> wrap)
menuState
Menu.BottomEnd
(IconButton.view shared
Strings.GameMenu
(Icon.menu |> Icon.styled [ Icon.lg ] |> NeList.just)
(menuState |> Menu.toggle |> SetGameMenuState |> wrap |> Just)
(IconButton.view
(Icon.menu |> Icon.styled [ Icon.lg ] |> Icon.view)
(Strings.GameMenu |> Lang.string shared)
(menuState |> ContextMenu.toggle |> SetGameMenuState |> wrap |> Just)
)
separatedMenuItems
@@ -871,14 +872,13 @@ viewNotification wrap shared users animationState notification =
[ Html.div [ HtmlA.class "content" ]
[ Html.span [ HtmlA.class "icon" ] [ icon ]
, Html.span [ HtmlA.class "message" ] [ message ]
, Button.view shared
, Button.viewWithAttrs
Button.Standard
Strings.Dismiss
Strings.Dismiss
Html.nothing
[ notification |> Animated.Exit |> NotificationMsg |> wrap |> HtmlE.onClick
, HtmlA.class "action"
]
Button.Padded
(Strings.Dismiss |> Lang.string shared)
Nothing
(notification |> Animated.Exit |> NotificationMsg |> wrap |> Just)
[ HtmlA.class "action" ]
]
]
@@ -990,7 +990,8 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
if localUserId /= userId then
case user.privilege of
User.Unprivileged ->
[ Menu.button Icon.userPromote
[ ContextMenu.button
Icon.userPromote
Strings.Promote
Strings.Promote
(SetPrivilege userId User.Privileged |> wrap |> Just)
@@ -998,7 +999,7 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
]
User.Privileged ->
[ Menu.button
[ ContextMenu.button
Icon.userDemote
Strings.Demote
Strings.Demote
@@ -1016,7 +1017,7 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
if (localUserId == userId && not audienceMode) || localUserPrivilege == User.Privileged then
case user.role of
User.Player ->
[ Menu.button Icon.spectator
[ ContextMenu.button Icon.spectator
Strings.BecomeSpectator
Strings.BecomeSpectatorDescription
(SetUserRole (Just userId) User.Spectator |> wrap |> Just)
@@ -1024,7 +1025,7 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
]
User.Spectator ->
[ Menu.button Icon.player
[ ContextMenu.button Icon.player
Strings.BecomePlayer
Strings.BecomePlayerDescription
(SetUserRole (Just userId) User.Player |> wrap |> Just)
@@ -1040,12 +1041,12 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
let
kickOrLeave =
if userId == localUserId then
Menu.button Icon.leave Strings.LeaveGame Strings.LeaveGame (Leave |> wrap |> Just) |> Just
ContextMenu.button Icon.leave Strings.LeaveGame Strings.LeaveGame (Leave |> wrap |> Just) |> Just
else
case localUserPrivilege of
User.Privileged ->
Menu.button Icon.userKick Strings.KickUser Strings.KickUser (userId |> Kick |> wrap |> Just) |> Just
ContextMenu.button Icon.userKick Strings.KickUser Strings.KickUser (userId |> Kick |> wrap |> Just) |> Just
User.Unprivileged ->
Nothing
@@ -1058,7 +1059,7 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
else if not isAway && game /= Nothing then
case localUserPrivilege of
User.Privileged ->
Menu.button Icon.userAway Strings.SetAway Strings.SetAway (userId |> SetAway |> wrap |> Just) |> Just
ContextMenu.button Icon.userAway Strings.SetAway Strings.SetAway (userId |> SetAway |> wrap |> Just) |> Just
User.Unprivileged ->
Nothing
@@ -1078,7 +1079,7 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
, presenceMenuItems
]
|> List.filterMap (\part -> part |> List.filterMap identity |> (\l -> l |> Maybe.justIf (l |> List.isEmpty >> not)))
|> List.intersperse [ Menu.Separator ]
|> List.intersperse [ ContextMenu.Separator ]
|> List.concat
else
@@ -1094,13 +1095,13 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
Just userId == openUserMenu
in
( \c ->
Menu.view shared
ContextMenu.view shared
(SetUserMenuState userId Menu.Closed |> wrap)
(isOpen |> Menu.open)
(isOpen |> ContextMenu.open)
Menu.BottomRight
c
menuItems
, [ not isOpen |> Menu.open |> SetUserMenuState userId |> wrap |> HtmlE.onClick
, [ not isOpen |> ContextMenu.open |> SetUserMenuState userId |> wrap |> HtmlE.onClick
, HtmlA.classList [ ( "active", isOpen ), ( "has-menu", True ) ]
]
)
@@ -1120,17 +1121,17 @@ viewUser wrap shared localUserId localUserPrivilege audienceMode openUserMenu ga
)
setPresenceMenuItem : (Msg -> msg) -> Maybe Player -> Menu.Part msg
setPresenceMenuItem : (Msg -> msg) -> Maybe Player -> ContextMenu.Part msg
setPresenceMenuItem wrap player =
case player |> Maybe.map .presence of
Just Player.Active ->
Menu.button Icon.userAway Strings.SetAway Strings.SetAway (Player.Away |> Game.SetPresence |> GameMsg |> wrap |> Just)
ContextMenu.button Icon.userAway Strings.SetAway Strings.SetAway (Player.Away |> Game.SetPresence |> GameMsg |> wrap |> Just)
Just Player.Away ->
Menu.button Icon.userBack Strings.SetBack Strings.SetBack (Player.Active |> Game.SetPresence |> GameMsg |> wrap |> Just)
ContextMenu.button Icon.userBack Strings.SetBack Strings.SetBack (Player.Active |> Game.SetPresence |> GameMsg |> wrap |> Just)
Nothing ->
Menu.button Icon.userAway Strings.SetAway Strings.SetAway Nothing
ContextMenu.button Icon.userAway Strings.SetAway Strings.SetAway Nothing
userDetails : Shared -> Maybe Game -> User.Id -> User -> ( List (Html msg), List (Html msg) )
@@ -1191,9 +1192,9 @@ viewDetails shared =
viewCastButton : (Msg -> msg) -> Shared -> Auth -> List (Html.Attribute msg) -> List (Html msg)
viewCastButton wrap shared auth attrs =
[ Html.div (HtmlA.class "cast-button" :: attrs)
[ IconButton.view shared
Strings.Cast
(Icon.chromecast |> Icon.styled [ Icon.lg ] |> NeList.just)
[ IconButton.view
(Icon.chromecast |> Icon.styled [ Icon.lg ] |> Icon.view)
(Strings.Cast |> Lang.string shared)
(auth |> TryCast |> wrap |> Just)
]
]
@@ -88,7 +88,7 @@ update shared msg model config =
( model, shared, Actions.startGame )
ChangeTab t ->
( { model | tab = t }, shared, Cmd.none )
( { model | tab = t |> Maybe.withDefault model.tab }, shared, Cmd.none )
ResolveConflict source id ->
case getComponent id of
@@ -191,12 +191,13 @@ view wrap wrapLobby shared return disabledReason gameCode { lobby, configure } =
Privacy.All |> PrivacyId |> getComponent |> Maybe.map viewComponent |> Maybe.withDefault []
viewReturnButton msg =
Button.view shared
Button.viewWithAttrs
Button.Raised
Strings.ReturnViewToGame
Strings.ReturnViewToGameDescription
(Icon.back |> Icon.view)
[ HtmlA.class "game-in-progress", HtmlE.onClick msg ]
Button.Padded
(Strings.ReturnViewToGame |> Lang.string shared)
(Icon.back |> Icon.view |> Just)
(Just msg)
[ HtmlA.class "game-in-progress" ]
returnButton =
return |> Maybe.map viewReturnButton |> Maybe.withDefault (Html.div [] [])
@@ -218,12 +219,13 @@ view wrap wrapLobby shared return disabledReason gameCode { lobby, configure } =
, disabledReason
|> Message.view shared
|> Maybe.withDefault Html.nothing
, Tabs.view shared
, Tabs.view
{ selected = model.tab
, change = ChangeTab >> wrap
, ids = tabs
, tab = tab
, tab = tab shared
, equals = (==)
, stacked = False
}
, Html.div [] tabComponent
, startGameSegment wrap wrapLobby shared canEdit model lobby returnButton
@@ -259,16 +261,16 @@ applyChange wrap change config model =
actions : (Msg -> msg) -> Shared -> Bool -> Config -> Html msg
actions wrap shared hasChanges config =
Html.div [ HtmlA.class "actions" ]
[ Fab.view shared
[ Fab.view
Fab.Normal
Strings.SaveChanges
Icon.save
(Strings.SaveChanges |> Lang.string shared)
(Icon.save |> Icon.view)
(SaveChanges |> wrap |> Maybe.justIf (Configurable.isValid (all wrap config) config))
[ HtmlA.classList [ ( "action", True ), ( "important", True ), ( "exited", not hasChanges ) ] ]
, Fab.view shared
, Fab.view
Fab.Mini
Strings.RevertChanges
Icon.undo
(Strings.RevertChanges |> Lang.string shared)
(Icon.undo |> Icon.view)
(RevertChanges |> wrap |> Just)
[ HtmlA.classList [ ( "action", True ), ( "exited", not hasChanges ), ( "normal", True ) ] ]
]
@@ -319,12 +321,13 @@ viewConflict wrap shared model local config conflict =
resolveButton : (Msg -> msg) -> Shared -> Id -> Config.Source -> MdString -> Html msg
resolveButton wrap shared conflict source description =
Button.view shared
Button.viewWithAttrs
Button.Raised
description
description
Html.nothing
[ HtmlA.class "resolve", ResolveConflict source conflict |> wrap |> HtmlE.onClick ]
Button.Padded
(description |> Lang.string shared)
Nothing
(ResolveConflict source conflict |> wrap |> Just)
[ HtmlA.class "resolve" ]
all : (Msg -> msg) -> Config -> Configurable.Component Id Config Model msg
@@ -390,13 +393,6 @@ startGameSegment wrap wrapLobby shared canEdit model lobby returnButton =
startErrors =
startGameProblems shared wrap wrapLobby lobby.users model config
startGameAttrs =
if List.isEmpty startErrors && canEdit then
StartGame |> wrap |> HtmlE.onClick
else
HtmlA.disabled True
in
Html.div []
[ Form.section
@@ -406,12 +402,12 @@ startGameSegment wrap wrapLobby shared canEdit model lobby returnButton =
(startErrors |> Maybe.justIf canEdit |> Maybe.withDefault [])
, Html.div [ HtmlA.class "button-spread" ]
[ returnButton
, Button.view shared
, Button.view
Button.Raised
Strings.StartGame
Strings.StartGame
(Icon.start |> Icon.view)
[ startGameAttrs ]
Button.Padded
(Strings.StartGame |> Lang.string shared)
(Icon.start |> Icon.view |> Just)
(StartGame |> wrap |> Maybe.justIf (List.isEmpty startErrors && canEdit))
]
]
@@ -626,14 +622,14 @@ startGameProblems shared wrap wrapLobby users model remote =
[ deckIssues, playerIssues, aisNoWriteGoodIssues, configurationIssues ] |> List.concat |> List.filterMap identity
tabs : NeList Tab
tabs : List Tab
tabs =
NeList Decks [ Rules, Stages, Privacy ]
[ Decks, Rules, Stages, Privacy ]
tab : Tab -> Tabs.TabModel
tab target =
{ label = target |> tabName
tab : Shared -> Tab -> Tabs.TabModel msg
tab shared target =
{ label = target |> tabName |> Lang.string shared
, icon = Nothing
}
@@ -15,14 +15,12 @@ module MassiveDecks.Pages.Lobby.Configure.Configurable.Editor exposing
import FontAwesome as Icon
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import MassiveDecks.Icon as Icon
import MassiveDecks.Model exposing (Shared)
import MassiveDecks.Strings as Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html.Events as HtmlE
import MassiveDecks.Util.Html as Html
import MassiveDecks.Util.Maybe as Maybe
import MassiveDecks.Util.NeList as NeList
import Material.IconButton as IconButton
import Material.Switch as Switch
import Material.TextField as TextField
@@ -55,23 +53,18 @@ maybe default base noOp update model value args =
Nothing ->
( False, True )
updateWithNewValue v =
if v then
default |> Just |> update
else
Nothing |> update
in
Switch.view
[ selected |> HtmlA.selected
, if readOnly || disabled then
HtmlA.disabled True
else
let
newValue =
if selected then
Nothing
else
Just default
in
newValue |> update |> HtmlE.onClick
]
Html.nothing
selected
(updateWithNewValue |> Maybe.justIf (not (readOnly || disabled)))
:: base noOp (Just >> update) model (value |> Maybe.andThen identity) args
@@ -81,28 +74,14 @@ bool label _ update _ value { shared, readOnly } =
disabled =
readOnly || value == Nothing
labelClick =
value |> Maybe.andThen (Maybe.justIf (not disabled)) |> Maybe.map (not >> update >> HtmlE.onClick)
selected =
value |> Maybe.withDefault False
in
[ Html.label
(List.filterMap identity
[ labelClick
, HtmlA.class "primary" |> Just
]
)
[ Switch.view
[ selected |> HtmlA.selected
, if disabled then
HtmlA.disabled True
else
selected |> not |> update |> HtmlE.onClickNoPropagation
]
, label |> Lang.html shared
]
[ Switch.viewWithAttrs
(label |> Lang.html shared)
selected
(update |> Maybe.justIf (not disabled))
[ HtmlA.class "primary" ]
]
@@ -125,33 +104,23 @@ map f g base noOp update model value args =
string : MdString -> Def String model msg
string label _ update _ value { shared, readOnly } =
[ TextField.view shared
label
[ TextField.viewWithAttrs
(label |> Lang.string shared)
TextField.Text
(value |> Maybe.withDefault "")
[ if readOnly || value == Nothing then
HtmlA.disabled True
else
HtmlE.onInput update
, HtmlA.class "primary"
]
(update |> Maybe.justIf (not (readOnly || (value == Nothing))))
[ HtmlA.class "primary" ]
]
int : MdString -> Def Int model msg
int label noOp update _ value { shared, readOnly } =
[ TextField.view shared
label
[ TextField.viewWithAttrs
(label |> Lang.string shared)
TextField.Number
(value |> Maybe.withDefault 0 |> String.fromInt)
[ if readOnly || value == Nothing then
HtmlA.disabled True
else
HtmlE.onInput (String.toInt >> Maybe.map update >> Maybe.withDefault noOp)
, HtmlA.class "primary"
]
((String.toInt >> Maybe.map update >> Maybe.withDefault noOp) |> Maybe.justIf (not (readOnly || (value == Nothing))))
[ HtmlA.class "primary" ]
]
@@ -190,21 +159,16 @@ password setPasswordVisibility label _ update model value { shared, readOnly } =
( Icon.show, TextField.Password )
toggleVisibility =
IconButton.view shared
Strings.LobbyPassword
(icon |> NeList.just)
IconButton.view
(icon |> Icon.view)
(Strings.LobbyPassword |> Lang.string shared)
(model.passwordVisible |> not |> setPasswordVisibility |> Just)
in
[ TextField.view shared
label
[ TextField.viewWithAttrs
(label |> Lang.string shared)
type_
(value |> Maybe.withDefault "")
[ if readOnly || (value == Nothing) then
HtmlA.disabled True
else
HtmlE.onInput update
, HtmlA.class "primary"
]
(update |> Maybe.justIf (not (readOnly || (value == Nothing))))
[ HtmlA.class "primary" ]
, toggleVisibility
]
@@ -202,9 +202,9 @@ addDeckWidget wrap shared existing deckToAdd =
[ Html.div [ HtmlA.class "multipart" ] [ sourcePicker ]
, Html.div [ HtmlA.class "multipart" ]
[ deckPicker
, IconButton.view shared
Strings.AddDeck
(NeList Icon.add [])
, IconButton.view
(Icon.add |> Icon.view)
(Strings.AddDeck |> Lang.string shared)
(submit |> Result.toMaybe)
]
]
@@ -284,9 +284,8 @@ name wrap shared canEdit index source loading maybeError details =
let
removeButton =
IconButton.view
shared
Strings.RemoveDeck
(NeList Icon.remove [])
(Icon.remove |> Icon.view)
(Strings.RemoveDeck |> Lang.string shared)
(index |> Remove |> wrap |> Just)
|> Maybe.justIf canEdit
@@ -7,7 +7,7 @@ import MassiveDecks.Pages.Lobby.Configure.Model exposing (..)
type Msg
= ApplyChange Id Config
| DecksMsg Decks.Msg
| ChangeTab Tab
| ChangeTab (Maybe Tab)
| StartGame
| ResolveConflict Source Id
| SetPasswordVisibility Bool
@@ -42,7 +42,11 @@ enabled wrap =
always
[ Message.info Strings.HouseRuleCzarChoicesDescription
, Message.infoWithFix (Strings.SeeAlso { rule = Strings.DuringTitle })
[ { description = Strings.ConfigureTimeLimits, icon = Icon.show, action = ChangeTab Stages |> wrap } ]
[ { description = Strings.ConfigureTimeLimits
, icon = Icon.show
, action = Stages |> Just |> ChangeTab |> wrap
}
]
]
}
@@ -85,7 +85,11 @@ starting wrap =
always
[ Message.info Strings.StartingTimeLimitDescription
, Message.infoWithFix (Strings.SeeAlso { rule = Strings.HouseRuleCzarChoices })
[ { description = Strings.ConfigureRules, icon = Icon.show, action = Rules |> ChangeTab |> wrap } ]
[ { description = Strings.ConfigureRules
, icon = Icon.show
, action = Rules |> Just |> ChangeTab |> wrap
}
]
]
}
]
@@ -16,7 +16,6 @@ import MassiveDecks.Strings as Strings
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html as Html
import MassiveDecks.Util.Html.Events as HtmlE
import MassiveDecks.Util.NeList as NeList exposing (NeList(..))
import Material.Card as Card
import Material.IconButton as IconButton
import QRCode
@@ -27,7 +26,10 @@ import Url exposing (Url)
-}
button : (Msg -> msg) -> Shared -> Html msg
button wrap shared =
IconButton.view shared Strings.Invite (Icon.invite |> NeList.just) (ToggleInviteDialog |> wrap |> Just)
IconButton.view
(Icon.invite |> Icon.view)
(Strings.Invite |> Lang.string shared)
(ToggleInviteDialog |> wrap |> Just)
{-| A dialog overlay that displays information on how to invite people to the game.
@@ -43,9 +45,9 @@ dialog wrap shared gameCode password open =
, HtmlA.classList [ ( "open", open ) ]
, Lobby.ToggleInviteDialog |> wrap |> HtmlE.onClick
]
[ IconButton.viewNoPropagation shared
Strings.Close
(Icon.close |> NeList.just)
[ IconButton.viewNoPropagation
(Icon.close |> Icon.view)
(Strings.Close |> Lang.string shared)
(Lobby.ToggleInviteDialog |> wrap |> Just)
, Card.view [ HtmlE.onClickNoPropagation (wrap NoOp) ]
[ Strings.InviteExplanation { gameCode = GameCode.toString gameCode, password = password } |> Lang.html shared
@@ -59,9 +61,9 @@ dialog wrap shared gameCode password open =
, HtmlA.id "invite-link-field"
]
[]
, IconButton.view shared
Strings.Copy
(Icon.copy |> NeList.just)
, IconButton.view
(Icon.copy |> Icon.view)
(Strings.Copy |> Lang.string shared)
("invite-link-field" |> Copy |> wrap |> Just)
]
)
@@ -1,7 +1,6 @@
module MassiveDecks.Pages.Lobby.Messages exposing (Msg(..))
import MassiveDecks.Animated as Animated
import MassiveDecks.Components.Menu.Model as Menu
import MassiveDecks.Game.Messages as Game
import MassiveDecks.Game.Time as Time
import MassiveDecks.Models.MdError exposing (MdError)
@@ -11,6 +10,7 @@ import MassiveDecks.Pages.Lobby.Model exposing (..)
import MassiveDecks.Pages.Lobby.Route exposing (Section)
import MassiveDecks.Pages.Lobby.Spectate.Messages as Spectate
import MassiveDecks.User as User
import Material.Menu as Menu
type Msg
@@ -14,7 +14,6 @@ module MassiveDecks.Pages.Lobby.Model exposing
import Dict exposing (Dict)
import MassiveDecks.Animated exposing (Animated)
import MassiveDecks.Components.Menu.Model as Menu
import MassiveDecks.Error.Model exposing (Error)
import MassiveDecks.Game.Model as Game
import MassiveDecks.Game.Time as Time
@@ -24,6 +23,7 @@ import MassiveDecks.Pages.Lobby.GameCode exposing (GameCode)
import MassiveDecks.Pages.Lobby.Route exposing (..)
import MassiveDecks.Pages.Lobby.Spectate.Model as Spectate
import MassiveDecks.User as User exposing (User)
import Material.Menu as Menu
{-| A change. This is the result of the update function, and implies either an update to the current page or a redirect
@@ -26,7 +26,6 @@ import MassiveDecks.Pages.Start.Route as Start
import MassiveDecks.Strings as Strings
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.User as User
import MassiveDecks.Util.NeList as NeList
import Material.IconButton as IconButton
import QRCode
import Url exposing (Url)
@@ -97,17 +96,17 @@ viewSettings wrap changePage shared lobby =
( wrap BecomePlayer, Strings.BecomePlayerDescription )
in
[ Html.div [ HtmlA.id "spectate-actions" ]
[ IconButton.view shared
backDescription
(Icon.back |> NeList.just)
[ IconButton.view
(Icon.back |> Icon.view)
(backDescription |> Lang.string shared)
(Just backAction)
, IconButton.view shared
Strings.ViewConfigurationDescription
(Icon.configure |> NeList.just)
, IconButton.view
(Icon.configure |> Icon.view)
(Strings.ViewConfigurationDescription |> Lang.string shared)
({ route | section = Just Lobby.Configure } |> Route.Lobby |> changePage |> Just)
, IconButton.view shared
Strings.ToggleAdvertDescription
(advertiseIcon |> NeList.just)
, IconButton.view
(advertiseIcon |> Icon.view)
(Strings.ToggleAdvertDescription |> Lang.string shared)
(ToggleAdvert |> wrap |> Just)
]
]
+53 -57
View File
@@ -239,12 +239,13 @@ view shared model =
]
]
, Card.view []
[ Tabs.view shared
[ Tabs.view
{ selected = r.section
, change = \s -> Route.Start { r | section = s } |> Global.ChangePage
, ids = NeList New [ Join model.gameCode, Find, About ]
, tab = tabFor
, change = \s -> Route.Start { r | section = s |> Maybe.withDefault r.section } |> Global.ChangePage
, ids = [ New, Join model.gameCode, Find, About ]
, tab = tabFor shared
, equals = sectionsMatch
, stacked = False
}
, sectionContent shared model
]
@@ -280,20 +281,24 @@ view shared model =
{- Private -}
tabFor : Section -> Tabs.TabModel
tabFor section =
case section of
New ->
Tabs.TabModel Strings.NewGame (Just Icon.new)
tabFor : Shared -> Section -> Tabs.TabModel msg
tabFor shared section =
let
( name, icon ) =
case section of
New ->
( Strings.NewGame, Icon.new )
Join _ ->
Tabs.TabModel Strings.JoinPrivateGame (Just Icon.join)
Join _ ->
( Strings.JoinPrivateGame, Icon.join )
Find ->
Tabs.TabModel Strings.FindPublicGame (Just Icon.find)
Find ->
( Strings.FindPublicGame, Icon.find )
About ->
Tabs.TabModel Strings.AboutTheGame (Just Icon.about)
About ->
( Strings.AboutTheGame, Icon.about )
in
Tabs.TabModel (name |> Lang.string shared) (icon |> Icon.view |> Just)
overlay : Shared -> Maybe MdString -> Html Global.Msg
@@ -301,9 +306,9 @@ overlay shared content =
case content of
Just text ->
Html.div [ HtmlA.id "overlay" ]
[ IconButton.view shared
Strings.Close
(Icon.close |> NeList.just)
[ IconButton.view
(Icon.close |> Icon.view)
(Strings.Close |> Lang.string shared)
(HideOverlay |> Global.StartMsg |> Just)
, Card.view []
[ text |> Lang.html shared
@@ -397,24 +402,20 @@ newContent shared model =
loading =
loadingOrLoaded model
buttonAttr =
if model.name == "" || loading then
HtmlA.disabled True
else
StartGame HttpData.Pull |> Global.StartMsg |> HtmlE.onClick
buttonIcon =
if loading then
Icon.loading |> Icon.view
Icon.loading
else
Icon.view Icon.start
Icon.start
error =
model.newLobbyRequest.generalError
|> Maybe.map (Error.view shared (Route.Start model.route))
|> Maybe.withDefault Html.nothing
canStart =
not (model.name == "" || loading)
in
Html.div [ HtmlA.class "new-game start-tab" ]
[ Html.div [ HtmlA.class "tab-content" ]
@@ -422,12 +423,12 @@ newContent shared model =
, Html.p [] [ Strings.NewGameDescription |> Lang.html shared ]
, error
, nameField shared model Nothing
, Button.view shared
, Button.view
Button.Raised
Strings.PlayGame
Strings.PlayGame
buttonIcon
[ buttonAttr ]
Button.Padded
(Strings.PlayGame |> Lang.string shared)
(buttonIcon |> Icon.view |> Just)
(StartGame HttpData.Pull |> Global.StartMsg |> Maybe.justIf canStart)
]
]
@@ -438,19 +439,12 @@ joinContent shared model =
loading =
loadingOrLoaded model
buttonAttr =
if String.isEmpty model.name || model.gameCode == Nothing || loading then
HtmlA.disabled True
else
JoinGame HttpData.Pull |> Global.StartMsg |> HtmlE.onClick
buttonIcon =
if loading then
Icon.loading |> Icon.view
Icon.loading
else
Icon.view Icon.start
Icon.start
error =
model.joinLobbyRequest.generalError
@@ -472,6 +466,9 @@ joinContent shared model =
model.password
|> Maybe.map (passwordField shared passwordError)
|> Maybe.withDefault []
canStart =
not (String.isEmpty model.name || model.gameCode == Nothing || loading)
in
Html.div [ HtmlA.class "join-game start-tab" ]
[ Html.div [ HtmlA.class "tab-content" ]
@@ -484,25 +481,24 @@ joinContent shared model =
, [ nameField shared model nameError
, Form.section shared
"game-code-input"
(TextField.view shared
Strings.GameCodeTerm
(TextField.viewWithAttrs
(Strings.GameCodeTerm |> Lang.string shared)
TextField.Text
(model.gameCode |> Maybe.map GameCode.toString |> Maybe.withDefault "")
[ HtmlA.class "game-code-input"
, GameCodeChanged >> Global.StartMsg |> HtmlE.onInput
]
(GameCodeChanged >> Global.StartMsg |> Just)
[ HtmlA.class "game-code-input" ]
)
[ Message.info Strings.GameCodeHowToAcquire
, gameError |> Maybe.map Message.mdError |> Maybe.withDefault Message.none
]
]
, maybePasswordField
, [ Button.view shared
, [ Button.view
Button.Raised
Strings.PlayGame
Strings.PlayGame
buttonIcon
[ buttonAttr ]
Button.Padded
(Strings.PlayGame |> Lang.string shared)
(buttonIcon |> Icon.view |> Just)
(JoinGame HttpData.Pull |> Global.StartMsg |> Maybe.justIf canStart)
]
]
)
@@ -513,11 +509,11 @@ passwordField : Shared -> Maybe MdError -> String -> List (Html Global.Msg)
passwordField shared error password =
[ Form.section shared
"password-input"
(TextField.view shared
Strings.LobbyPassword
(TextField.view
(Strings.LobbyPassword |> Lang.string shared)
TextField.Password
password
[ PasswordChanged >> Global.StartMsg |> HtmlE.onInput ]
(PasswordChanged >> Global.StartMsg |> Just)
)
[ Message.info Strings.LobbyRequiresPassword
, error |> Maybe.map (MdError.describe >> Message.error) |> Maybe.withDefault Message.none
@@ -561,11 +557,11 @@ nameField : Shared -> Model -> Maybe MdError -> Html Global.Msg
nameField shared model error =
Form.section shared
"name-input"
(TextField.view shared
Strings.NameLabel
(TextField.view
(Strings.NameLabel |> Lang.string shared)
TextField.Text
model.name
[ NameChanged >> Global.StartMsg |> HtmlE.onInput ]
(NameChanged >> Global.StartMsg |> Just)
)
[ error |> Maybe.map (MdError.describe >> Message.error) |> Maybe.withDefault Message.none ]
@@ -162,9 +162,8 @@ lobby : Shared -> Summary -> ( String, Html Global.Msg )
lobby shared data =
( data.gameCode |> GameCode.toString
, ListView.viewItem
(ListView.Enabled (Route.Start { section = Start.Join (Just data.gameCode) } |> Global.ChangePage))
(Route.Start { section = Start.Join (Just data.gameCode) } |> Global.ChangePage |> Just |> ListView.Button)
Nothing
data.name
([ Html.span [ HtmlA.class "lobby-game-code" ]
[ Strings.GameCode { code = GameCode.toString data.gameCode } |> Lang.html shared ]
]
@@ -20,6 +20,7 @@ import MassiveDecks.Requests.HttpData.Messages exposing (..)
import MassiveDecks.Requests.HttpData.Model exposing (..)
import MassiveDecks.Requests.Request as Request
import MassiveDecks.Strings as Strings
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Maybe as Maybe
import MassiveDecks.Util.NeList as NeList exposing (NeList(..))
import Material.IconButton as IconButton
@@ -119,7 +120,7 @@ refreshButton shared { loading } =
else
identity
in
IconButton.view shared
Strings.Refresh
(Icon.refresh |> applyStyle |> NeList.just)
IconButton.view
(Icon.refresh |> applyStyle |> Icon.view)
(Strings.Refresh |> Lang.string shared)
(Pull |> Maybe.justIf (not loading))
+69 -72
View File
@@ -16,7 +16,6 @@ import FontAwesome as Icon
import FontAwesome.Attributes as Icon
import Html as Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import Http
import MassiveDecks.Card.Source as Source
import MassiveDecks.Card.Source.Model as Source
@@ -167,9 +166,9 @@ view wrap shared =
Icon.configure
button =
IconButton.view shared
Strings.SettingsTitle
(icon |> Icon.styled [ Icon.lg ] |> NeList.just)
IconButton.view
(icon |> Icon.styled [ Icon.lg ] |> Icon.view)
(Strings.SettingsTitle |> Lang.string shared)
(ToggleOpen |> wrap |> Just)
panel =
@@ -298,18 +297,18 @@ cardSize wrap shared =
[ HtmlA.class "card-size-slider" ]
[ Icon.minimalCardSize |> Icon.view
, Slider.view
[ HtmlA.class "primary"
, Slider.step 1
, Slider.min 1
, Slider.max 3
, Slider.withTickMarks 3
, cardSizeFromValue
>> Maybe.withDefault Full
>> ChangeCardSize
>> wrap
|> Slider.onChange
, settings.cardSize |> cardSizeToValue |> Slider.value
]
{ min = 1
, max = 3
, step = 1
, value = settings.cardSize |> cardSizeToValue
, onChange =
cardSizeFromValue
>> Maybe.withDefault Full
>> ChangeCardSize
>> wrap
|> Just
, attrs = [ HtmlA.class "primary" ]
}
, Icon.callCard |> Icon.view
]
]
@@ -331,15 +330,14 @@ autoAdvanceRound wrap shared =
(Html.div
[ HtmlA.class "multipart" ]
[ Switch.view
[ HtmlE.onClick (currentValue |> not |> ToggleAutoAdvance >> wrap)
, HtmlA.selected currentValue
, HtmlA.id "auto-advance-enable"
]
, Html.label [ HtmlA.for "auto-advance-enable" ]
[ Icon.view Icon.autoAdvance
, Html.text " "
, Strings.AutoAdvanceSetting |> Lang.html shared
]
(Html.span []
[ Icon.view Icon.autoAdvance
, Html.text " "
, Strings.AutoAdvanceSetting |> Lang.html shared
]
)
currentValue
(ToggleAutoAdvance >> wrap |> Just)
]
)
[ Message.info Strings.AutoAdvanceExplanation ]
@@ -380,28 +378,26 @@ speechVoiceSelector wrap shared =
[ Html.div
[ HtmlA.class "multipart" ]
[ Switch.view
[ HtmlE.onClick (enabled |> not |> ToggleSpeech >> wrap)
, HtmlA.disabled isDisabled
, HtmlA.selected enabled
, HtmlA.id "speech-enable"
]
, Html.label [ HtmlA.for "speech-enable" ]
[ Icon.view Icon.tts
, Html.text " "
, Strings.SpeechSetting |> Lang.html shared
]
(Html.span []
[ Icon.view Icon.tts
, Html.text " "
, Strings.SpeechSetting |> Lang.html shared
]
)
enabled
(ToggleSpeech >> wrap |> Maybe.justIf (not isDisabled))
]
, Html.div [ HtmlA.class "children" ]
[ Select.view shared
{ label = Strings.VoiceSetting
[ Select.view
{ label = Strings.VoiceSetting |> Lang.string shared
, idToString = identity
, idFromString = Just
, selected = selectedVoice
, wrap = ChangeSpeech >> wrap
, disabled = not enabled || isDisabled
, fullWidth = True
, attrs = [ HtmlA.class "secondary" ]
}
[ HtmlA.disabled (not enabled || isDisabled)
, HtmlA.class "secondary"
]
(voices |> List.sortWith voiceSortOrder |> List.map speechVoiceOption)
]
]
@@ -464,34 +460,34 @@ notificationsSwitch wrap shared =
settings =
shared.settings.settings.notifications
unsupported =
not (Notifications.supportsNotifications shared.notifications)
supported =
Notifications.supportsNotifications shared.notifications
enabled =
not unsupported && settings.enabled
supported && settings.enabled
visibilityUnsupported =
not (Notifications.supportsVisibility shared.notifications)
visibilityDisabled =
visibilityUnsupported || unsupported || not settings.enabled
visibilityUnsupported || not enabled
in
Form.section shared
"notifications"
(Html.div []
[ Html.div
[ HtmlA.class "multipart" ]
[ Switch.view
[ HtmlE.onClick (enabled |> not |> ToggleNotifications >> wrap)
, HtmlA.disabled unsupported
, HtmlA.selected enabled
, HtmlA.id "notifications-enable"
]
, Html.label [ HtmlA.for "notifications-enable" ]
[ Icon.view Icon.notification
, Html.text " "
, Strings.NotificationsSetting |> Lang.html shared
]
[ Switch.viewWithAttrs
(Html.span
[]
[ Icon.view Icon.notification
, Html.text " "
, Strings.NotificationsSetting |> Lang.html shared
]
)
enabled
(ToggleNotifications >> wrap |> Maybe.justIf supported)
[ HtmlA.id "notifications-enable" ]
]
, Html.div [ HtmlA.classList [ ( "children", True ), ( "inactive", not enabled ) ] ]
[ Form.section
@@ -499,17 +495,16 @@ notificationsSwitch wrap shared =
"only-when-hidden"
(Html.div
[ HtmlA.class "multipart" ]
[ Switch.view
[ HtmlE.onClick (settings.requireNotVisible |> not |> ToggleOnlyWhenHidden >> wrap)
, HtmlA.disabled visibilityDisabled
, HtmlA.selected settings.requireNotVisible
, HtmlA.id "only-when-hidden-toggle"
]
, Html.label [ HtmlA.for "only-when-hidden-toggle" ]
[ Icon.view Icon.hide
, Html.text " "
, Strings.NotificationOnlyWhenHiddenSetting |> Lang.html shared
]
[ Switch.viewWithAttrs
(Html.span []
[ Icon.view Icon.hide
, Html.text " "
, Strings.NotificationOnlyWhenHiddenSetting |> Lang.html shared
]
)
settings.requireNotVisible
(ToggleOnlyWhenHidden >> wrap |> Maybe.justIf (not visibilityDisabled))
[ HtmlA.id "only-when-hidden-enable" ]
]
)
[ Message.info Strings.NotificationsOnlyWhenHiddenExplanation
@@ -524,11 +519,11 @@ notificationsSwitch wrap shared =
)
[ Message.info Strings.NotificationsExplanation
, Message.info Strings.NotificationsBrowserPermissions
, if unsupported then
Message.warning Strings.NotificationsUnsupportedExplanation
, if supported then
Message.none
else
Message.none
Message.warning Strings.NotificationsUnsupportedExplanation
]
@@ -541,14 +536,16 @@ languageSelector wrap shared =
Form.section
shared
"language"
(Select.view shared
{ label = Strings.LanguageSetting
(Select.view
{ label = Strings.LanguageSetting |> Lang.string shared
, idToString = Lang.code
, idFromString = Lang.fromCode
, selected = Just selected
, wrap = ChangeLang >> wrap
, disabled = False
, fullWidth = True
, attrs = []
}
[]
(Lang.languages |> List.map (languageOption shared selected))
)
[ Message.info Strings.MissingLanguage ]
-24
View File
@@ -1,24 +0,0 @@
module Material.Attributes exposing
( label
, maxLength
, minLength
)
import Html
import Html.Attributes as HtmlA
import Json.Encode as Json
label : String -> Html.Attribute msg
label =
HtmlA.attribute "label"
minLength : Int -> Html.Attribute msg
minLength =
Json.int >> HtmlA.property "minLength"
maxLength : Int -> Html.Attribute msg
maxLength =
Json.int >> HtmlA.property "maxLength"
-47
View File
@@ -1,47 +0,0 @@
module Material.Button exposing
( Type(..)
, view
)
import Html exposing (Html)
import Html.Attributes as HtmlA
import MassiveDecks.Model exposing (Shared)
import MassiveDecks.Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html.Attributes as HtmlA
type Type
= Standard
| Outlined
| Raised
| Unelevated
view : Shared -> Type -> MdString -> MdString -> Html msg -> List (Html.Attribute msg) -> Html msg
view shared type_ label title icon attributes =
let
typeAttr =
case type_ of
Standard ->
[]
Outlined ->
[ HtmlA.attribute "outlined" "" ]
Raised ->
[ HtmlA.attribute "raised" "" ]
Unelevated ->
[ HtmlA.attribute "unelevated" "" ]
allAttrs =
List.concat
[ [ label |> Lang.label shared
, title |> Lang.title shared
]
, typeAttr
, attributes
]
in
Html.node "mwc-button" allAttrs [ Html.span [ HtmlA.slot "icon" ] [ icon ] ]
-9
View File
@@ -1,9 +0,0 @@
module Material.Card exposing (view)
import Html as HtmlA
import Html.Attributes as HtmlA
view : List (HtmlA.Attribute msg) -> List (HtmlA.Html msg) -> HtmlA.Html msg
view attributes =
HtmlA.div (HtmlA.class "mdc-card" :: attributes)
-51
View File
@@ -1,51 +0,0 @@
module Material.Fab exposing
( Type(..)
, view
)
import FontAwesome as Icon exposing (Icon)
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import MassiveDecks.Model exposing (Shared)
import MassiveDecks.Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html.Attributes as HtmlA
type Type
= Normal
| Extended
| Mini
view : Shared -> Type -> MdString -> Icon hasId -> Maybe msg -> List (Html.Attribute msg) -> Html msg
view shared type_ title icon action attrs =
let
content =
case type_ of
Extended ->
[ title |> Lang.html shared ]
_ ->
[]
style =
case type_ of
Mini ->
[ HtmlA.attribute "mini" "" ]
_ ->
[]
onClick =
case action of
Just msg ->
msg |> HtmlE.onClick
Nothing ->
HtmlA.attribute "disabled" ""
in
Html.node "mwc-fab"
(List.concat [ [ title |> Lang.title shared, onClick ], style, attrs ])
((icon |> Icon.styled [ HtmlA.slot "icon" ] |> Icon.view) :: content)
-68
View File
@@ -1,68 +0,0 @@
module Material.IconButton exposing
( view
, viewCustomIcon
, viewNoPropagation
)
import FontAwesome as Icon exposing (Icon)
import FontAwesome.Layering as Icon
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import MassiveDecks.Model exposing (Shared)
import MassiveDecks.Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html.Events as HtmlE
import MassiveDecks.Util.NeList exposing (NeList(..))
{-| View a button that displays as a simple icon.
-}
view : Shared -> MdString -> NeList (Icon hasId) -> Maybe msg -> Html msg
view shared title icon action =
viewRenderedIcon [ actionAttrFromMaybe HtmlE.onClick action ] shared title (renderIcon icon)
{-| View a button that displays as a simple icon, and blocks clicks propagating to other elements.
-}
viewNoPropagation : Shared -> MdString -> NeList (Icon hasId) -> Maybe msg -> Html msg
viewNoPropagation shared title icon action =
viewRenderedIcon [ actionAttrFromMaybe HtmlE.onClickNoPropagation action ] shared title (renderIcon icon)
{-| View a button that displays as a custom rendered icon.
-}
viewCustomIcon : Shared -> MdString -> Html msg -> Maybe msg -> Html msg
viewCustomIcon shared title icon action =
viewRenderedIcon [ actionAttrFromMaybe HtmlE.onClick action ] shared title icon
{- Private -}
actionAttrFromMaybe : (a -> Html.Attribute msg) -> Maybe a -> Html.Attribute msg
actionAttrFromMaybe onClick action =
case action of
Just msg ->
msg |> onClick
Nothing ->
HtmlA.disabled True
renderIcon : NeList (Icon hasId) -> Html msg
renderIcon (NeList first rest) =
case rest of
[] ->
first |> Icon.view
_ ->
(first :: rest) |> List.map Icon.view |> Icon.layers []
viewRenderedIcon : List (Html.Attribute msg) -> Shared -> MdString -> Html msg -> Html msg
viewRenderedIcon actionAttr shared title renderedIcon =
Html.node "mwc-icon-button"
((title |> Lang.title shared) :: actionAttr)
[ renderedIcon ]
@@ -1,44 +0,0 @@
module Material.LinearProgress exposing
( Progress(..)
, view
)
import Html exposing (Html)
import Html.Attributes as HtmlA
import Json.Encode as Json
{-| What progress to display.
-}
type
Progress
-- An unknown amount of progress.
= Indeterminate
-- A float progress from 0 (no progress) to 1 (complete).
| Progress Float
-- Complete.
| Closed
{-| A progress bar.
-}
view : Progress -> List (Html.Attribute msg) -> Html msg
view p attributes =
Html.node "mwc-linear-progress" (progress p :: attributes) []
{- Private -}
progress : Progress -> Html.Attribute msg
progress p =
case p of
Indeterminate ->
True |> Json.bool |> HtmlA.property "indeterminate"
Progress float ->
float |> Json.float |> HtmlA.property "progress"
Closed ->
True |> Json.bool |> HtmlA.property "closed"
-89
View File
@@ -1,89 +0,0 @@
module Material.ListView exposing
( Action(..)
, action
, interactive
, view
, viewItem
)
import FontAwesome as Icon exposing (Icon)
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import Json.Encode as Json
import MassiveDecks.Util.Html.Attributes as HtmlA
{-| A list.
-}
view : List (Html.Attribute msg) -> List (Html msg) -> Html msg
view attributes children =
Html.node "mwc-list" attributes children
{-| What happens when you interact with the item.
-}
type Action msg
= None
| Link
| Enabled msg
| Disabled
{-| A list item that is only sometimes enabled.
-}
interactive : msg -> Bool -> Action msg
interactive msg enabled =
if enabled then
Enabled msg
else
Disabled
{-| An action from a maybe, if it is enabled.
-}
action : Maybe msg -> Action msg
action a =
case a of
Just msg ->
Enabled msg
Nothing ->
Disabled
{-| An item within a list.
-}
viewItem : Action msg -> Maybe (Icon hasId) -> String -> Maybe (List (Html msg)) -> Maybe (List (Html msg)) -> List (Html msg) -> Html msg
viewItem action_ icon title secondary meta children =
let
( optionalAttrs, optionalSlots ) =
[ icon |> Maybe.map (\i -> ( HtmlA.attribute "graphic" "large", i |> Icon.styled [ HtmlA.slot "graphic" ] |> Icon.view ))
, meta |> Maybe.map (\m -> ( True |> Json.bool |> HtmlA.property "hasMeta", Html.span [ HtmlA.slot "meta" ] m ))
, secondary |> Maybe.map (\s -> ( True |> Json.bool |> HtmlA.property "twoline", Html.span [ HtmlA.slot "secondary" ] s ))
]
|> List.filterMap identity
|> List.unzip
actionAttr =
case action_ of
Enabled msg ->
msg |> HtmlE.onClick
Disabled ->
HtmlA.disabled True
Link ->
HtmlA.nothing
None ->
True |> Json.bool |> HtmlA.property "noninteractive"
attrs =
List.concat [ optionalAttrs, [ actionAttr, HtmlA.title title ] ]
slots =
List.concat [ optionalSlots, [ Html.span [] children ] ]
in
Html.node "mwc-list-item" attrs slots
-60
View File
@@ -1,60 +0,0 @@
module Material.Menu exposing (view)
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import Json.Decode
import Json.Encode as Json
import MassiveDecks.Components.Menu.Model exposing (..)
{-| View a pop-up menu.
-}
view : msg -> State -> Corner -> Html msg -> List (Html msg) -> Html msg
view onClose state corner anchor menuItems =
let
open =
case state of
Open ->
True
Closed ->
False
stringCorner =
case corner of
TopLeft ->
"TOP_LEFT"
TopRight ->
"TOP_RIGHT"
BottomLeft ->
"BOTTOM_LEFT"
BottomRight ->
"BOTTOM_RIGHT"
TopStart ->
"TOP_START"
TopEnd ->
"TOP_END"
BottomStart ->
"BOTTOM_START"
BottomEnd ->
"BOTTOM_END"
in
Html.div [ HtmlA.class "menu-anchor" ]
[ anchor
, Html.node "mwc-menu"
[ True |> Json.bool |> HtmlA.property "activatable"
, open |> Json.bool |> HtmlA.property "open"
, stringCorner |> HtmlA.attribute "corner"
, HtmlA.class "menu"
, onClose |> Json.Decode.succeed |> HtmlE.on "closed"
]
menuItems
]
-8
View File
@@ -1,8 +0,0 @@
module Material.Ripple exposing (view)
import Html as HtmlA
view : List (HtmlA.Attribute msg) -> List (HtmlA.Html msg) -> HtmlA.Html msg
view =
HtmlA.node "mwc-ripple"
-87
View File
@@ -1,87 +0,0 @@
module Material.Select exposing
( ItemModel
, Model
, view
)
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import Json.Decode as Json
import Json.Encode
import MassiveDecks.Model exposing (Shared)
import MassiveDecks.Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html.Attributes as HtmlA
{-| A combo box.
-}
view : Shared -> Model id msg -> List (Html.Attribute msg) -> List (ItemModel id msg) -> Html msg
view shared model attrs items =
let
allAttrs =
List.concat
[ [ model.label |> Lang.label shared
, model.idFromString >> model.wrap |> onChange
, HtmlA.fullWidth
]
, attrs
]
in
Html.node "mwc-select" allAttrs (items |> List.map (viewItem model))
{-| The things needed to render the select.
-}
type alias Model id msg =
{ label : MdString
, idToString : id -> String
, idFromString : String -> Maybe id
, selected : Maybe id
, wrap : Maybe id -> msg
}
{-| The things needed to render a specific item in the select.
-}
type alias ItemModel id msg =
{ id : id
, icon : Maybe (Html msg)
, primary : List (Html msg)
, secondary : Maybe (List (Html msg))
, meta : Maybe (Html msg)
}
{- Private -}
{-| An item within a list.
-}
viewItem : Model id msg -> ItemModel id msg -> Html msg
viewItem { idToString, selected } { id, icon, primary, secondary, meta } =
let
( optionalAttrs, optionalSlots ) =
[ icon |> Maybe.map (\i -> ( HtmlA.attribute "graphic" "large", Html.span [ HtmlA.slot "graphic" ] [ i ] ))
, meta |> Maybe.map (\m -> ( True |> Json.Encode.bool |> HtmlA.property "hasMeta", Html.span [ HtmlA.slot "meta" ] [ m ] ))
, secondary |> Maybe.map (\s -> ( True |> Json.Encode.bool |> HtmlA.property "twoline", Html.span [ HtmlA.slot "secondary" ] s ))
]
|> List.filterMap identity
|> List.unzip
attrs =
List.concat [ optionalAttrs, [ id |> idToString |> HtmlA.value, selected == Just id |> HtmlA.selected ] ]
slots =
List.concat [ primary, optionalSlots ] |> List.intersperse (Html.text " ")
in
Html.node "mwc-list-item" attrs slots
{-| An event for when the user changes the selection.
-}
onChange : (String -> msg) -> Html.Attribute msg
onChange wrap =
Json.at [ "target", "value" ] Json.string |> Json.map wrap |> HtmlE.on "change"
-56
View File
@@ -1,56 +0,0 @@
module Material.Slider exposing
( discrete
, max
, min
, onChange
, step
, value
, view
, withTickMarks
)
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import Json.Decode
import Json.Encode as Json
view : List (Html.Attribute msg) -> Html msg
view attributes =
Html.node "mwc-slider" attributes []
step : Int -> Html.Attribute msg
step =
Json.int >> HtmlA.property "step"
min : Int -> Html.Attribute msg
min =
Json.int >> HtmlA.property "min"
max : Int -> Html.Attribute msg
max =
Json.int >> HtmlA.property "max"
withTickMarks : Int -> Html.Attribute msg
withTickMarks =
Json.int >> HtmlA.property "withTickMarks"
value : Int -> Html.Attribute msg
value =
Json.int >> HtmlA.property "value"
discrete : Bool -> Html.Attribute msg
discrete =
Json.bool >> HtmlA.property "discrete"
onChange : (Int -> msg) -> Html.Attribute msg
onChange wrap =
Json.Decode.at [ "target", "value" ] Json.Decode.int |> Json.Decode.map wrap |> HtmlE.on "change"
-8
View File
@@ -1,8 +0,0 @@
module Material.Switch exposing (view)
import Html exposing (Html)
view : List (Html.Attribute msg) -> Html msg
view attributes =
Html.node "mwc-switch" attributes []
-88
View File
@@ -1,88 +0,0 @@
module Material.Tabs exposing
( Model
, TabModel
, view
)
import FontAwesome as Icon exposing (Icon)
import Html exposing (Html)
import Html.Attributes as HtmlA
import Html.Events as HtmlE
import Json.Decode
import Json.Encode
import List.Extra as List
import MassiveDecks.Model exposing (Shared)
import MassiveDecks.Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
import MassiveDecks.Util.Html as Html
import MassiveDecks.Util.Html.Attributes as HtmlA
import MassiveDecks.Util.NeList as NonEmptyList exposing (NeList)
{-| A model for a bar of tabs.
-}
type alias Model id msg =
{ selected : id
, change : id -> msg
, ids : NeList id
, tab : id -> TabModel
, equals : id -> id -> Bool
}
{-| A model for a tab.
-}
type alias TabModel =
{ label : MdString
, icon : Maybe (Icon Icon.WithoutId)
}
{-| View a bar of tabs.
-}
view : Shared -> Model id msg -> Html msg
view shared { selected, change, ids, tab, equals } =
let
idsList =
ids |> NonEmptyList.toList
attrs =
[ idsList |> List.findIndex (equals selected) |> Maybe.withDefault 0 |> activeIndex
, ((\id -> List.getAt id idsList) >> (ids |> NonEmptyList.head |> Maybe.withDefault) >> change) |> onActivated
]
viewTab { label, icon } =
let
( iconAttr, iconNode ) =
case icon of
Just i ->
( hasImageIcon, i |> Icon.styled [ HtmlA.slot "icon" ] |> Icon.view )
Nothing ->
( HtmlA.nothing, Html.nothing )
in
Html.node "mwc-tab" [ label |> Lang.label shared, iconAttr ] [ iconNode ]
tabs =
idsList |> List.map (tab >> viewTab)
in
Html.node "mwc-tab-bar" attrs tabs
{- Private -}
activeIndex : Int -> Html.Attribute msg
activeIndex =
Json.Encode.int >> HtmlA.property "activeIndex"
hasImageIcon : Html.Attribute msg
hasImageIcon =
HtmlA.attribute "hasImageIcon" "hasImageIcon"
onActivated : (Int -> msg) -> Html.Attribute msg
onActivated wrap =
Json.Decode.int |> Json.Decode.map wrap |> Json.Decode.at [ "target", "activeIndex" ] |> HtmlE.on "MDCTabBar:activated"
-8
View File
@@ -1,8 +0,0 @@
module Material.TextArea exposing (view)
import Html
view : List (Html.Attribute msg) -> List (Html.Html msg) -> Html.Html msg
view =
Html.node "mwc-textarea"
-96
View File
@@ -1,96 +0,0 @@
module Material.TextField exposing
( Type(..)
, view
)
import Html exposing (Html)
import Html.Attributes as HtmlA
import MassiveDecks.Model exposing (Shared)
import MassiveDecks.Strings exposing (MdString)
import MassiveDecks.Strings.Languages as Lang
{-| The type of field.
-}
type Type
= Text
| Search
| Tel
| Url
| Email
| Password
| Date
| Month
| Week
| Time
| DateTimeLocal
| Number
| Color
{-| A text field for the given type of data.
-}
view : Shared -> MdString -> Type -> String -> List (Html.Attribute msg) -> Html msg
view shared label t value attributes =
let
allAttrs =
List.concat
[ [ label |> Lang.label shared
, t |> type_
, value |> HtmlA.value
]
, attributes
]
in
Html.node "mwc-textfield" allAttrs []
{- Private -}
type_ : Type -> Html.Attribute msg
type_ t =
let
stringType =
case t of
Text ->
"text"
Search ->
"search"
Tel ->
"tel"
Url ->
"url"
Email ->
"email"
Password ->
"password"
Date ->
"date"
Month ->
"month"
Week ->
"week"
Time ->
"time"
DateTimeLocal ->
"datetime-local"
Number ->
"number"
Color ->
"color"
in
stringType |> HtmlA.attribute "type"
-76
View File
@@ -1,9 +1,6 @@
@use "_colors";
@use "_fonts";
@use "~@material/card";
@include card.core-styles;
/// Support styling for Material Web Components.
:root {
@@ -29,76 +26,3 @@
mwc-tab .svg-inline--fa {
font-size: 1em;
}
mwc-icon-button {
svg,
.fa-layers {
display: block !important;
width: 0.7em !important;
height: 0.7em !important;
}
}
.mdc-card {
padding: 1em;
}
mwc-select {
width: 100%;
}
mwc-textfield {
width: 100%;
}
mwc-fab {
line-height: 1;
&:focus,
&::-moz-focus-inner {
outline: none;
border: 0;
}
.svg-inline--fa {
margin-right: 0;
}
display: inline-flex;
justify-content: center;
transition: opacity 15ms linear 30ms,
transform 0.27s cubic-bezier(0, 0, 0.2, 1) 0ms;
&.exited {
transition: opacity 15ms linear 0.15s,
transform 0.18s cubic-bezier(0.4, 0, 1, 1) 0ms;
transform: scale(0);
opacity: 0;
}
&.large {
--button-fab-size: 3em;
font-size: 1.2em;
}
&[disabled] {
pointer-events: none;
--mdc-theme-secondary: #cccccc;
}
}
.menu-anchor {
position: relative;
mwc-menu {
position: absolute;
right: 0;
top: 0;
}
}
a > mwc-list-item {
height: 48px;
}
+1 -1
View File
@@ -16,7 +16,7 @@
}
}
.settings-panel {
div.settings-panel {
display: none;
position: absolute;
top: 4em;
+12 -11
View File
@@ -1,16 +1,17 @@
@use "_colors";
@use "_fonts";
@use "_material";
@use "./colors";
@use "./fonts";
@use "./material";
@use "_game";
@use "pages/_start";
@use "pages/_lobby";
@use "pages/_spectate";
@use "pages/_unknown-page";
@use "_settings";
@use "_error";
@use "./game";
@use "./pages/start";
@use "./pages/lobby";
@use "./pages/spectate";
@use "./pages/unknown-page";
@use "./settings";
@use "./error";
@use "@fortawesome/fontawesome-svg-core/styles.css";
@import "../../elm-material/src/scss/material";
@import "@fortawesome/fontawesome-svg-core/styles.css";
$min-page-width: 320px;
+3 -4
View File
@@ -14,9 +14,6 @@ $users-width: 18rem;
}
}
#lobby {
}
#top-bar {
position: absolute;
top: 0;
@@ -99,6 +96,8 @@ $users-width: 18rem;
transition: width 0.3s;
--mdc-menu-max-width: #{calc($users-width - 2em)};
mwc-menu {
left: 0;
right: 0;
@@ -210,7 +209,7 @@ $users-width: 18rem;
z-index: 500;
}
.notification {
div.notification {
position: fixed;
left: 0;
bottom: 0;
+5 -5
View File
@@ -1,5 +1,5 @@
import "@webcomponents/webcomponentsjs/webcomponents-loader";
import "./material";
import "../../elm-material/src/ts/material";
import "./paper";
import "../scss/massive-decks.scss";
import * as serverConnection from "./server-connection";
@@ -30,22 +30,22 @@ export function load(remoteMode: boolean) {
copy.register(app.ports.copyText);
notificationManager.register(
app.ports.notificationState,
app.ports.notificationCommands
app.ports.notificationCommands,
);
language.register(app.ports.languageChanged);
confetti.register(app.ports.startConfetti);
import(/* webpackChunkName: "cast-client" */ "./cast/client").then(
(cast) => {
cast.register(app.ports.tryCast, app.ports.castStatus);
}
},
);
} else {
import(/* webpackChunkName: "cast-server" */ "./cast/server").then(
(cast) => {
cast.register(app.ports.remoteControl);
}
},
);
}
}
},
);
}
-14
View File
@@ -1,14 +0,0 @@
import "@material/mwc-button";
import "@material/mwc-fab";
import "@material/mwc-switch";
import "@material/mwc-slider";
import "@material/mwc-select";
import "@material/mwc-tab";
import "@material/mwc-tab-bar";
import "@material/mwc-menu";
import "@material/mwc-list";
import "@material/mwc-list/mwc-list-item";
import "@material/mwc-textarea";
import "@material/mwc-textfield";
import "@material/mwc-icon-button";
import "@material/mwc-linear-progress";
+5 -10
View File
@@ -5,17 +5,12 @@
"noImplicitAny": true,
"preserveConstEnums": true,
"outDir": "dist",
"strict": true,
"strict": true,
"sourceMap": true,
"baseUrl": ".",
"baseUrl": ".",
"moduleResolution": "node",
"lib": [ "es2015", "dom" ]
"lib": ["es2015", "dom"]
},
"include": [
"src/ts/**/*"
],
"exclude": [
"node_modules",
"dist"
]
"include": ["src/ts/**/*", "elm-material/src/ts/**/*"],
"exclude": ["node_modules", "dist"]
}
+118 -118
View File
@@ -277,9 +277,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "17.0.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz",
"integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==",
"version": "17.0.38",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.38.tgz",
"integrity": "sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g==",
"dev": true
},
"node_modules/@types/pg": {
@@ -346,14 +346,14 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.26.0.tgz",
"integrity": "sha512-oGCmo0PqnRZZndr+KwvvAUvD3kNE4AfyoGCwOZpoCncSh4MVD06JTE8XQa2u9u+NX5CsyZMBTEc2C72zx38eYA==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz",
"integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.26.0",
"@typescript-eslint/type-utils": "5.26.0",
"@typescript-eslint/utils": "5.26.0",
"@typescript-eslint/scope-manager": "5.27.0",
"@typescript-eslint/type-utils": "5.27.0",
"@typescript-eslint/utils": "5.27.0",
"debug": "^4.3.4",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.2.0",
@@ -408,14 +408,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.26.0.tgz",
"integrity": "sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz",
"integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.26.0",
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/typescript-estree": "5.26.0",
"@typescript-eslint/scope-manager": "5.27.0",
"@typescript-eslint/types": "5.27.0",
"@typescript-eslint/typescript-estree": "5.27.0",
"debug": "^4.3.4"
},
"engines": {
@@ -435,13 +435,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.26.0.tgz",
"integrity": "sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz",
"integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/visitor-keys": "5.26.0"
"@typescript-eslint/types": "5.27.0",
"@typescript-eslint/visitor-keys": "5.27.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -452,12 +452,12 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.26.0.tgz",
"integrity": "sha512-7ccbUVWGLmcRDSA1+ADkDBl5fP87EJt0fnijsMFTVHXKGduYMgienC/i3QwoVhDADUAPoytgjbZbCOMj4TY55A==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz",
"integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==",
"dev": true,
"dependencies": {
"@typescript-eslint/utils": "5.26.0",
"@typescript-eslint/utils": "5.27.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -507,9 +507,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.26.0.tgz",
"integrity": "sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz",
"integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -520,13 +520,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.26.0.tgz",
"integrity": "sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz",
"integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/visitor-keys": "5.26.0",
"@typescript-eslint/types": "5.27.0",
"@typescript-eslint/visitor-keys": "5.27.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -576,15 +576,15 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.26.0.tgz",
"integrity": "sha512-PJFwcTq2Pt4AMOKfe3zQOdez6InIDOjUJJD3v3LyEtxHGVVRK3Vo7Dd923t/4M9hSH2q2CLvcTdxlLPjcIk3eg==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz",
"integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.26.0",
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/typescript-estree": "5.26.0",
"@typescript-eslint/scope-manager": "5.27.0",
"@typescript-eslint/types": "5.27.0",
"@typescript-eslint/typescript-estree": "5.27.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
},
@@ -600,12 +600,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz",
"integrity": "sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz",
"integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/types": "5.27.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -820,7 +820,7 @@
"node_modules/body-parser/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/boxen": {
"version": "5.1.2",
@@ -1801,7 +1801,7 @@
"node_modules/express/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
@@ -1925,7 +1925,7 @@
"node_modules/finalhandler/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/flat-cache": {
"version": "3.0.4",
@@ -2720,7 +2720,7 @@
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
"engines": {
"node": ">= 0.6"
}
@@ -2728,7 +2728,7 @@
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
},
"node_modules/merge2": {
"version": "1.4.1",
@@ -2742,7 +2742,7 @@
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"engines": {
"node": ">= 0.6"
}
@@ -2833,7 +2833,7 @@
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
"node_modules/negotiator": {
@@ -2915,7 +2915,7 @@
"node_modules/nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
"integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
"dev": true,
"dependencies": {
"abbrev": "1"
@@ -2967,7 +2967,7 @@
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"dependencies": {
"wrappy": "1"
@@ -3059,7 +3059,7 @@
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -3077,7 +3077,7 @@
"node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
"node_modules/path-type": {
"version": "4.0.0",
@@ -3185,7 +3185,7 @@
"node_modules/postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
"engines": {
"node": ">=0.10.0"
}
@@ -3221,7 +3221,7 @@
"node_modules/prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
"integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==",
"dev": true,
"engines": {
"node": ">=4"
@@ -3630,7 +3630,7 @@
"node_modules/send/node_modules/debug/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/send/node_modules/ms": {
"version": "2.1.3",
@@ -3921,9 +3921,9 @@
}
},
"node_modules/typescript": {
"version": "4.8.0-dev.20220530",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.0-dev.20220530.tgz",
"integrity": "sha512-NB9F5TGowxNmBQ9GY/ufx1dreQby8NuzdtuogOEFFsK1SruBRlmCCUX6YkrTUK76WnhEoSzoLGGFj45qb8wfbw==",
"version": "4.8.0-dev.20220602",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.0-dev.20220602.tgz",
"integrity": "sha512-1T4oqo8KYojf6edCkymgrNS7Rnmou3o02jhI3cT5zLQx7WeVqwFii9hTZ0E39oYOVnRKSoDDeQw9hPdX/3SOVA==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@@ -4390,9 +4390,9 @@
"dev": true
},
"@types/node": {
"version": "17.0.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz",
"integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==",
"version": "17.0.38",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.38.tgz",
"integrity": "sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g==",
"dev": true
},
"@types/pg": {
@@ -4459,14 +4459,14 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.26.0.tgz",
"integrity": "sha512-oGCmo0PqnRZZndr+KwvvAUvD3kNE4AfyoGCwOZpoCncSh4MVD06JTE8XQa2u9u+NX5CsyZMBTEc2C72zx38eYA==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz",
"integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.26.0",
"@typescript-eslint/type-utils": "5.26.0",
"@typescript-eslint/utils": "5.26.0",
"@typescript-eslint/scope-manager": "5.27.0",
"@typescript-eslint/type-utils": "5.27.0",
"@typescript-eslint/utils": "5.27.0",
"debug": "^4.3.4",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.2.0",
@@ -4494,34 +4494,34 @@
}
},
"@typescript-eslint/parser": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.26.0.tgz",
"integrity": "sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz",
"integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.26.0",
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/typescript-estree": "5.26.0",
"@typescript-eslint/scope-manager": "5.27.0",
"@typescript-eslint/types": "5.27.0",
"@typescript-eslint/typescript-estree": "5.27.0",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.26.0.tgz",
"integrity": "sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz",
"integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/visitor-keys": "5.26.0"
"@typescript-eslint/types": "5.27.0",
"@typescript-eslint/visitor-keys": "5.27.0"
}
},
"@typescript-eslint/type-utils": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.26.0.tgz",
"integrity": "sha512-7ccbUVWGLmcRDSA1+ADkDBl5fP87EJt0fnijsMFTVHXKGduYMgienC/i3QwoVhDADUAPoytgjbZbCOMj4TY55A==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz",
"integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==",
"dev": true,
"requires": {
"@typescript-eslint/utils": "5.26.0",
"@typescript-eslint/utils": "5.27.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -4545,19 +4545,19 @@
}
},
"@typescript-eslint/types": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.26.0.tgz",
"integrity": "sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz",
"integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.26.0.tgz",
"integrity": "sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz",
"integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/visitor-keys": "5.26.0",
"@typescript-eslint/types": "5.27.0",
"@typescript-eslint/visitor-keys": "5.27.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -4584,26 +4584,26 @@
}
},
"@typescript-eslint/utils": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.26.0.tgz",
"integrity": "sha512-PJFwcTq2Pt4AMOKfe3zQOdez6InIDOjUJJD3v3LyEtxHGVVRK3Vo7Dd923t/4M9hSH2q2CLvcTdxlLPjcIk3eg==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz",
"integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.26.0",
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/typescript-estree": "5.26.0",
"@typescript-eslint/scope-manager": "5.27.0",
"@typescript-eslint/types": "5.27.0",
"@typescript-eslint/typescript-estree": "5.27.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz",
"integrity": "sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==",
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz",
"integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.26.0",
"@typescript-eslint/types": "5.27.0",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -4766,7 +4766,7 @@
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}
}
},
@@ -5445,7 +5445,7 @@
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}
}
},
@@ -5632,7 +5632,7 @@
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}
}
},
@@ -6237,12 +6237,12 @@
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
},
"merge2": {
"version": "1.4.1",
@@ -6253,7 +6253,7 @@
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
},
"micromatch": {
"version": "4.0.5",
@@ -6317,7 +6317,7 @@
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
"negotiator": {
@@ -6378,7 +6378,7 @@
"nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
"integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
"dev": true,
"requires": {
"abbrev": "1"
@@ -6412,7 +6412,7 @@
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"requires": {
"wrappy": "1"
@@ -6488,7 +6488,7 @@
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true
},
"path-key": {
@@ -6500,7 +6500,7 @@
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
"path-type": {
"version": "4.0.0",
@@ -6577,7 +6577,7 @@
"postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="
},
"postgres-date": {
"version": "1.0.7",
@@ -6601,7 +6601,7 @@
"prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
"integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==",
"dev": true
},
"prettier": {
@@ -6878,7 +6878,7 @@
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}
}
},
@@ -7107,9 +7107,9 @@
}
},
"typescript": {
"version": "4.8.0-dev.20220530",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.0-dev.20220530.tgz",
"integrity": "sha512-NB9F5TGowxNmBQ9GY/ufx1dreQby8NuzdtuogOEFFsK1SruBRlmCCUX6YkrTUK76WnhEoSzoLGGFj45qb8wfbw==",
"version": "4.8.0-dev.20220602",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.0-dev.20220602.tgz",
"integrity": "sha512-1T4oqo8KYojf6edCkymgrNS7Rnmou3o02jhI3cT5zLQx7WeVqwFii9hTZ0E39oYOVnRKSoDDeQw9hPdX/3SOVA==",
"dev": true
},
"undefsafe": {