Resolve #23: Remember recent decks.
This commit is contained in:
@@ -18,6 +18,8 @@ import MassiveDecks.Notifications as Notifications
|
||||
import MassiveDecks.Pages as Pages
|
||||
import MassiveDecks.Pages.Loading as Loading
|
||||
import MassiveDecks.Pages.Lobby as Lobby
|
||||
import MassiveDecks.Pages.Lobby.Configure.Decks.Model as Decks
|
||||
import MassiveDecks.Pages.Lobby.Configure.Messages as Configure
|
||||
import MassiveDecks.Pages.Lobby.GameCode as GameCode
|
||||
import MassiveDecks.Pages.Lobby.Messages as Lobby
|
||||
import MassiveDecks.Pages.Lobby.Model as Lobby
|
||||
@@ -35,7 +37,6 @@ import MassiveDecks.Speech as Speech
|
||||
import MassiveDecks.Strings as Strings exposing (MdString)
|
||||
import MassiveDecks.Strings.Languages as Lang
|
||||
import MassiveDecks.User as User
|
||||
import MassiveDecks.Util as Util
|
||||
import MassiveDecks.Util.Url as Url
|
||||
import Url exposing (Url)
|
||||
|
||||
@@ -136,8 +137,11 @@ update msg model =
|
||||
case msg of
|
||||
ChangePage route ->
|
||||
if oldRoute /= route then
|
||||
changePageFromRoute model.shared route model.page
|
||||
|> Util.modelLift (\p -> { model | page = p })
|
||||
let
|
||||
( p, cmd ) =
|
||||
changePageFromRoute model.shared route model.page
|
||||
in
|
||||
( { model | page = p }, cmd )
|
||||
|
||||
else
|
||||
( model, Cmd.none )
|
||||
@@ -176,8 +180,8 @@ update msg model =
|
||||
|
||||
( ( lobby, lobbyCmd ), ( settings, settingsCmd ) ) =
|
||||
case Lobby.init shared { gameCode = auth.claims.gc, section = Nothing } (Just auth) of
|
||||
Route.Continue continue ->
|
||||
( continue |> Util.modelLift Pages.Lobby |> changePage shared
|
||||
Route.Continue ( continue, cmd ) ->
|
||||
( changePage shared ( continue |> Pages.Lobby, cmd )
|
||||
, Settings.onJoinLobby auth name shared.settings
|
||||
)
|
||||
|
||||
@@ -197,15 +201,20 @@ update msg model =
|
||||
let
|
||||
shared =
|
||||
model.shared
|
||||
|
||||
( settings, cmd ) =
|
||||
Settings.onTokenUpdate auth shared.settings
|
||||
in
|
||||
Util.modelLift (\settings -> { model | shared = { shared | settings = settings } })
|
||||
(Settings.onTokenUpdate auth shared.settings)
|
||||
( { model | shared = { shared | settings = settings } }, cmd )
|
||||
|
||||
StartMsg startMsg ->
|
||||
case model.page of
|
||||
Pages.Start startModel ->
|
||||
Util.modelLift (\newStartModel -> { model | page = Pages.Start newStartModel })
|
||||
(Start.update model.shared startMsg startModel)
|
||||
let
|
||||
( newStartModel, cmd ) =
|
||||
Start.update model.shared startMsg startModel
|
||||
in
|
||||
( { model | page = Pages.Start newStartModel }, cmd )
|
||||
|
||||
_ ->
|
||||
( model, Cmd.none )
|
||||
@@ -214,9 +223,11 @@ update msg model =
|
||||
let
|
||||
shared =
|
||||
model.shared
|
||||
|
||||
( s, cmd ) =
|
||||
Settings.update shared settingsMsg
|
||||
in
|
||||
Settings.update shared settingsMsg
|
||||
|> Util.modelLift (\s -> { model | shared = { shared | settings = s } })
|
||||
( { model | shared = { shared | settings = s } }, cmd )
|
||||
|
||||
LobbyMsg lobbyMsg ->
|
||||
case model.page of
|
||||
@@ -229,8 +240,11 @@ update msg model =
|
||||
SpectateMsg spectateMsg ->
|
||||
case model.page of
|
||||
Pages.Spectate spectateModel ->
|
||||
Util.modelLift (\newSpectateModel -> { model | page = Pages.Spectate newSpectateModel })
|
||||
(Spectate.update SpectateMsg model.shared spectateMsg spectateModel)
|
||||
let
|
||||
( newSpectateModel, newShared, cmd ) =
|
||||
Spectate.update SpectateMsg model.shared spectateMsg spectateModel
|
||||
in
|
||||
( { model | page = Pages.Spectate newSpectateModel, shared = newShared }, cmd )
|
||||
|
||||
_ ->
|
||||
( model, Cmd.none )
|
||||
@@ -354,13 +368,13 @@ view model =
|
||||
|
||||
|
||||
handleLobbyMsg : Model -> Lobby.Msg -> Lobby.Model -> ( Model, Cmd Msg )
|
||||
handleLobbyMsg model lobbyMsg lobbyModel =
|
||||
handleLobbyMsg baseModel lobbyMsg lobbyModel =
|
||||
let
|
||||
shared =
|
||||
model.shared
|
||||
( change, shared, lobbyCmd ) =
|
||||
Lobby.update LobbyMsg baseModel.shared lobbyMsg lobbyModel
|
||||
|
||||
( change, lobbyCmd ) =
|
||||
Lobby.update LobbyMsg shared lobbyMsg lobbyModel
|
||||
model =
|
||||
{ baseModel | shared = shared }
|
||||
in
|
||||
case change of
|
||||
Lobby.Stay newLobbyModel ->
|
||||
|
||||
@@ -24,6 +24,7 @@ import MassiveDecks.Card.Source.Model exposing (..)
|
||||
import MassiveDecks.Card.Source.Player as Player
|
||||
import MassiveDecks.Components.Form.Message exposing (Message)
|
||||
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 Weightless as Wl
|
||||
@@ -131,8 +132,8 @@ logo source =
|
||||
|
||||
{-| An editor for any supported external source.
|
||||
-}
|
||||
generalEditor : Shared -> External -> (External -> msg) -> List (Html msg)
|
||||
generalEditor shared currentValue update =
|
||||
generalEditor : Shared -> List DeckOrError -> External -> (External -> msg) -> List (Html msg)
|
||||
generalEditor shared existing currentValue update =
|
||||
[ Wl.select
|
||||
[ HtmlA.id "source-selector"
|
||||
, WlA.outlined
|
||||
@@ -142,15 +143,15 @@ generalEditor shared currentValue update =
|
||||
[ Strings.Cardcast |> Lang.html shared
|
||||
]
|
||||
]
|
||||
, editor shared currentValue update
|
||||
, editor shared existing currentValue update
|
||||
]
|
||||
|
||||
|
||||
{-| An editor for the given source value.
|
||||
-}
|
||||
editor : Shared -> External -> (External -> msg) -> Html msg
|
||||
editor shared source =
|
||||
shared |> (externalMethods source |> .editor)
|
||||
editor : Shared -> List DeckOrError -> External -> (External -> msg) -> Html msg
|
||||
editor shared existing source =
|
||||
(externalMethods source |> .editor) shared existing
|
||||
|
||||
|
||||
{-| Get a user message explaining the reason a source failed to load.
|
||||
|
||||
@@ -11,8 +11,10 @@ import MassiveDecks.Card.Source.Methods as Source
|
||||
import MassiveDecks.Card.Source.Model as Source exposing (Source)
|
||||
import MassiveDecks.Components.Form.Message as Message exposing (Message)
|
||||
import MassiveDecks.Model exposing (..)
|
||||
import MassiveDecks.Pages.Lobby.Configure.Decks.Model as Decks exposing (DeckOrError)
|
||||
import MassiveDecks.Strings as Strings exposing (MdString)
|
||||
import MassiveDecks.Strings.Languages as Lang
|
||||
import MassiveDecks.Util.Maybe as Maybe
|
||||
import Url.Builder as Url
|
||||
import Weightless as Wl
|
||||
import Weightless.Attributes as WlA
|
||||
@@ -69,16 +71,42 @@ problems (PlayCode pc) () =
|
||||
[]
|
||||
|
||||
|
||||
editor : PlayCode -> Shared -> (Source.External -> msg) -> Html msg
|
||||
editor (PlayCode pc) shared update =
|
||||
Wl.textField
|
||||
[ HtmlA.value pc
|
||||
, HtmlA.class "primary"
|
||||
, WlA.outlined
|
||||
, HtmlE.onInput (playCode >> Source.Cardcast >> update)
|
||||
, Strings.CardcastPlayCode |> Lang.label shared
|
||||
editor : PlayCode -> Shared -> List DeckOrError -> (Source.External -> msg) -> Html msg
|
||||
editor (PlayCode pc) shared existing update =
|
||||
let
|
||||
notAlreadyInGame potential =
|
||||
case potential of
|
||||
Source.Cardcast playCode ->
|
||||
let
|
||||
notSameDeck deckOrError =
|
||||
let
|
||||
source =
|
||||
case deckOrError of
|
||||
Decks.D d ->
|
||||
d.source
|
||||
|
||||
Decks.E e ->
|
||||
e.source
|
||||
in
|
||||
equals playCode source |> not
|
||||
in
|
||||
playCode |> Maybe.justIf (existing |> List.all notSameDeck)
|
||||
|
||||
recentDeck (PlayCode recent) =
|
||||
Html.option [ HtmlA.value recent ] []
|
||||
in
|
||||
Html.div [ HtmlA.class "primary" ]
|
||||
[ Html.datalist [ HtmlA.id "cardcast-recent-decks" ]
|
||||
(shared.settings.settings.recentDecks |> List.filterMap notAlreadyInGame |> List.map recentDeck)
|
||||
, Wl.textField
|
||||
[ HtmlA.value pc
|
||||
, WlA.outlined
|
||||
, WlA.list "cardcast-recent-decks"
|
||||
, HtmlE.onInput (playCode >> Source.Cardcast >> update)
|
||||
, Strings.CardcastPlayCode |> Lang.label shared
|
||||
]
|
||||
[ Html.span [ WlA.textFieldSlot WlA.BeforeText ] [ logoInternal ] ]
|
||||
]
|
||||
[ Html.span [ WlA.textFieldSlot WlA.BeforeText ] [ logoInternal ] ]
|
||||
|
||||
|
||||
details : PlayCode -> Shared -> Source.Details
|
||||
|
||||
@@ -12,6 +12,7 @@ import Html exposing (Html)
|
||||
import MassiveDecks.Card.Source.Model exposing (..)
|
||||
import MassiveDecks.Components.Form.Message exposing (Message)
|
||||
import MassiveDecks.Model exposing (..)
|
||||
import MassiveDecks.Pages.Lobby.Configure.Decks.Model exposing (DeckOrError)
|
||||
import MassiveDecks.Strings exposing (MdString)
|
||||
|
||||
|
||||
@@ -82,7 +83,7 @@ type alias IsSpecific general msg =
|
||||
-}
|
||||
type alias IsSpecificExternal general msg =
|
||||
{ general
|
||||
| editor : Shared -> (External -> msg) -> Html msg
|
||||
| editor : Shared -> List DeckOrError -> (External -> msg) -> Html msg
|
||||
, equals : External -> Bool
|
||||
, problems : () -> List (Message msg)
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ import MassiveDecks.Speech as Speech
|
||||
import MassiveDecks.Strings as Strings exposing (MdString)
|
||||
import MassiveDecks.Strings.Languages as Lang
|
||||
import MassiveDecks.User as User exposing (User)
|
||||
import MassiveDecks.Util as Util
|
||||
import MassiveDecks.Util.Html as Html
|
||||
import MassiveDecks.Util.Maybe as Maybe
|
||||
import Set exposing (Set)
|
||||
@@ -63,7 +62,11 @@ init wrap game hand pick =
|
||||
( round, roundCmd ) =
|
||||
case game.round of
|
||||
Round.P r ->
|
||||
Util.modelLift Round.P (Playing.init wrap r pick)
|
||||
let
|
||||
( playing, cmd ) =
|
||||
Playing.init wrap r pick
|
||||
in
|
||||
( Round.P playing, cmd )
|
||||
|
||||
_ ->
|
||||
( game.round, Cmd.none )
|
||||
|
||||
@@ -13,7 +13,6 @@ import MassiveDecks.Pages.Route as Route exposing (Route)
|
||||
import MassiveDecks.Pages.Spectate as Spectate
|
||||
import MassiveDecks.Pages.Start as Start
|
||||
import MassiveDecks.Pages.Unknown as Unknown
|
||||
import MassiveDecks.Util as Util
|
||||
|
||||
|
||||
subscriptions : Page -> Sub Msg
|
||||
@@ -36,19 +35,25 @@ fromRoute : Shared -> Maybe Page -> Route -> ( Page, Cmd Msg )
|
||||
fromRoute shared oldModel route =
|
||||
case route of
|
||||
Route.Start r ->
|
||||
(case oldModel of
|
||||
Just (Start old) ->
|
||||
Start.changeRoute r old
|
||||
let
|
||||
( start, cmd ) =
|
||||
case oldModel of
|
||||
Just (Start old) ->
|
||||
Start.changeRoute r old
|
||||
|
||||
_ ->
|
||||
Start.init shared r
|
||||
)
|
||||
|> Util.modelLift Start
|
||||
_ ->
|
||||
Start.init shared r
|
||||
in
|
||||
( Start start, cmd )
|
||||
|
||||
Route.Lobby r ->
|
||||
case oldModel of
|
||||
Just (Lobby old) ->
|
||||
Lobby.changeRoute r old |> Util.modelLift Lobby
|
||||
let
|
||||
( lobby, cmd ) =
|
||||
Lobby.changeRoute r old
|
||||
in
|
||||
( Lobby lobby, cmd )
|
||||
|
||||
_ ->
|
||||
case Lobby.init shared r Nothing of
|
||||
@@ -61,7 +66,11 @@ fromRoute shared oldModel route =
|
||||
Route.Spectate r ->
|
||||
case oldModel of
|
||||
Just (Spectate old) ->
|
||||
Spectate.changeRoute r old |> Util.modelLift Spectate
|
||||
let
|
||||
( spectate, cmd ) =
|
||||
Spectate.changeRoute r old
|
||||
in
|
||||
( Spectate spectate, cmd )
|
||||
|
||||
_ ->
|
||||
case Spectate.init shared r Nothing of
|
||||
@@ -72,14 +81,16 @@ fromRoute shared oldModel route =
|
||||
fromRoute shared oldModel redirectRoute
|
||||
|
||||
Route.Unknown r ->
|
||||
(case oldModel of
|
||||
Just (Unknown old) ->
|
||||
Unknown.changeRoute r old
|
||||
let
|
||||
( unknown, cmd ) =
|
||||
case oldModel of
|
||||
Just (Unknown old) ->
|
||||
Unknown.changeRoute r old
|
||||
|
||||
_ ->
|
||||
Unknown.init r
|
||||
)
|
||||
|> Util.modelLift Unknown
|
||||
_ ->
|
||||
Unknown.init r
|
||||
in
|
||||
( Unknown unknown, cmd )
|
||||
|
||||
Route.Loading ->
|
||||
( Loading, Cmd.none )
|
||||
|
||||
@@ -56,7 +56,6 @@ import MassiveDecks.Settings.Model as Settings exposing (Settings)
|
||||
import MassiveDecks.Strings as Strings exposing (MdString)
|
||||
import MassiveDecks.Strings.Languages as Lang
|
||||
import MassiveDecks.User as User exposing (User)
|
||||
import MassiveDecks.Util as Util
|
||||
import MassiveDecks.Util.Html as Html
|
||||
import MassiveDecks.Util.Html.Attributes as HtmlA
|
||||
import MassiveDecks.Util.Maybe as Maybe
|
||||
@@ -118,7 +117,7 @@ subscriptions wrap handleError model =
|
||||
]
|
||||
|
||||
|
||||
update : (Msg -> msg) -> Shared -> Msg -> Model -> ( Change, Cmd msg )
|
||||
update : (Msg -> msg) -> Shared -> Msg -> Model -> ( Change, Shared, Cmd msg )
|
||||
update wrap shared msg model =
|
||||
case msg of
|
||||
GameMsg gameMsg ->
|
||||
@@ -130,23 +129,24 @@ update wrap shared msg model =
|
||||
( updatedGame, gameCmd ) =
|
||||
Game.update (GameMsg >> wrap) shared gameMsg g
|
||||
in
|
||||
( Stay { model | lobby = Just { l | game = Just updatedGame } }, gameCmd )
|
||||
( Stay { model | lobby = Just { l | game = Just updatedGame } }, shared, gameCmd )
|
||||
|
||||
Nothing ->
|
||||
( Stay model, Cmd.none )
|
||||
( Stay model, shared, Cmd.none )
|
||||
|
||||
Nothing ->
|
||||
( Stay model, Cmd.none )
|
||||
( Stay model, shared, Cmd.none )
|
||||
|
||||
EventReceived event ->
|
||||
case model.lobby of
|
||||
Just lobby ->
|
||||
case event of
|
||||
Events.Sync { state, hand, play, partialTimeAnchor } ->
|
||||
applySync wrap model state hand play partialTimeAnchor
|
||||
applySync wrap shared model state hand play partialTimeAnchor
|
||||
|
||||
Events.Configured { change } ->
|
||||
( applyConfigured change model
|
||||
, shared
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
@@ -155,24 +155,30 @@ update wrap shared msg model =
|
||||
r =
|
||||
model.route
|
||||
|
||||
applyGame g =
|
||||
( g, cmd ) =
|
||||
Game.applyGameStarted (GameMsg >> wrap) lobby round hand
|
||||
|
||||
newGame =
|
||||
Stay
|
||||
{ model
|
||||
| lobby = Just { lobby | game = Just g }
|
||||
, route = { r | section = Just Play }
|
||||
}
|
||||
in
|
||||
Util.modelLift applyGame (Game.applyGameStarted (GameMsg >> wrap) lobby round hand)
|
||||
( newGame, shared, cmd )
|
||||
|
||||
Events.Game gameEvent ->
|
||||
let
|
||||
withGame game =
|
||||
let
|
||||
( g, cmd ) =
|
||||
Game.applyGameEvent (GameMsg >> wrap) (EventReceived >> wrap) model.auth shared gameEvent game
|
||||
in
|
||||
( Stay { model | lobby = Just { lobby | game = Just g } }, shared, cmd )
|
||||
in
|
||||
lobby.game
|
||||
|> Maybe.map
|
||||
(\game ->
|
||||
Util.modelLift
|
||||
(\g -> Stay { model | lobby = Just { lobby | game = Just g } })
|
||||
(Game.applyGameEvent (GameMsg >> wrap) (EventReceived >> wrap) model.auth shared gameEvent game)
|
||||
)
|
||||
|> Maybe.withDefault ( Stay model, Cmd.none )
|
||||
|> Maybe.map withGame
|
||||
|> Maybe.withDefault ( Stay model, shared, Cmd.none )
|
||||
|
||||
Events.Connection { user, state } ->
|
||||
let
|
||||
@@ -188,12 +194,12 @@ update wrap shared msg model =
|
||||
, UserDisconnected user
|
||||
)
|
||||
in
|
||||
addNotification wrap message { model | lobby = Just { lobby | users = newUsers } }
|
||||
addNotification wrap shared message { model | lobby = Just { lobby | users = newUsers } }
|
||||
|
||||
Events.Presence { user, state } ->
|
||||
case ( state, user == model.auth.claims.uid ) of
|
||||
( Events.UserLeft { reason }, True ) ->
|
||||
( LeftGame model.auth.claims.gc reason, Cmd.none )
|
||||
( LeftGame model.auth.claims.gc reason, shared, Cmd.none )
|
||||
|
||||
_ ->
|
||||
let
|
||||
@@ -224,6 +230,7 @@ update wrap shared msg model =
|
||||
}
|
||||
in
|
||||
addNotification wrap
|
||||
shared
|
||||
message
|
||||
{ model | lobby = Just { lobby | users = newUsers, game = game } }
|
||||
|
||||
@@ -232,23 +239,23 @@ update wrap shared msg model =
|
||||
users =
|
||||
lobby.users |> Dict.update user (Maybe.map (\u -> { u | privilege = privilege }))
|
||||
in
|
||||
( Stay { model | lobby = Just { lobby | users = users } }, Cmd.none )
|
||||
( Stay { model | lobby = Just { lobby | users = users } }, shared, Cmd.none )
|
||||
|
||||
Events.ErrorEncountered { error } ->
|
||||
( Stay { model | lobby = Just { lobby | errors = lobby.errors ++ [ error ] } }, Cmd.none )
|
||||
( Stay { model | lobby = Just { lobby | errors = lobby.errors ++ [ error ] } }, shared, Cmd.none )
|
||||
|
||||
Nothing ->
|
||||
case event of
|
||||
Events.Sync { state, hand, play, partialTimeAnchor } ->
|
||||
applySync wrap model state hand play partialTimeAnchor
|
||||
applySync wrap shared model state hand play partialTimeAnchor
|
||||
|
||||
_ ->
|
||||
( Stay model, Cmd.none )
|
||||
( Stay model, shared, Cmd.none )
|
||||
|
||||
ErrorReceived error ->
|
||||
case error of
|
||||
MdError.Authentication reason ->
|
||||
( AuthError model.auth.claims.gc reason, Cmd.none )
|
||||
( AuthError model.auth.claims.gc reason, shared, Cmd.none )
|
||||
|
||||
MdError.ActionExecution (MdError.ConfigEditConflict _) ->
|
||||
let
|
||||
@@ -256,6 +263,7 @@ update wrap shared msg model =
|
||||
model.configure
|
||||
in
|
||||
addNotification wrap
|
||||
shared
|
||||
(Error error)
|
||||
{ model
|
||||
| configure =
|
||||
@@ -265,48 +273,53 @@ update wrap shared msg model =
|
||||
}
|
||||
|
||||
_ ->
|
||||
addNotification wrap (Error error) model
|
||||
addNotification wrap shared (Error error) model
|
||||
|
||||
ConfigureMsg configureMsg ->
|
||||
case model.lobby of
|
||||
Just l ->
|
||||
Util.modelLift (\c -> Stay { model | configure = c })
|
||||
(Configure.update configureMsg model.configure l.config)
|
||||
let
|
||||
( c, s, cmd ) =
|
||||
Configure.update shared configureMsg model.configure l.config
|
||||
in
|
||||
( Stay { model | configure = c }, s, cmd )
|
||||
|
||||
Nothing ->
|
||||
( Stay model, Cmd.none )
|
||||
( Stay model, shared, Cmd.none )
|
||||
|
||||
NotificationMsg notificationMsg ->
|
||||
Util.modelLift
|
||||
(\notifications -> Stay { model | notifications = notifications })
|
||||
(Animated.update (NotificationMsg >> wrap) { removeDone = Just Animated.defaultDuration } notificationMsg model.notifications)
|
||||
let
|
||||
( notifications, cmd ) =
|
||||
Animated.update (NotificationMsg >> wrap) { removeDone = Just Animated.defaultDuration } notificationMsg model.notifications
|
||||
in
|
||||
( Stay { model | notifications = notifications }, shared, cmd )
|
||||
|
||||
ToggleInviteDialog ->
|
||||
( Stay { model | inviteDialogOpen = not model.inviteDialogOpen }, Cmd.none )
|
||||
( Stay { model | inviteDialogOpen = not model.inviteDialogOpen }, shared, Cmd.none )
|
||||
|
||||
Leave ->
|
||||
( Stay model, Actions.leave )
|
||||
( Stay model, shared, Actions.leave )
|
||||
|
||||
Kick id ->
|
||||
( Stay model, Actions.kick id )
|
||||
( Stay model, shared, Actions.kick id )
|
||||
|
||||
SetAway id ->
|
||||
( Stay model, Actions.setPlayerAway id )
|
||||
( Stay model, shared, Actions.setPlayerAway id )
|
||||
|
||||
SetPrivilege id privilege ->
|
||||
( Stay model, Actions.setPrivilege id privilege )
|
||||
( Stay model, shared, Actions.setPrivilege id privilege )
|
||||
|
||||
SetTimeAnchor anchor ->
|
||||
( Stay { model | timeAnchor = Just anchor }, Cmd.none )
|
||||
( Stay { model | timeAnchor = Just anchor }, shared, Cmd.none )
|
||||
|
||||
EndGame ->
|
||||
( Stay model, Actions.endGame )
|
||||
( Stay model, shared, Actions.endGame )
|
||||
|
||||
TryCast auth ->
|
||||
( Stay model, Cast.tryCast shared auth.token )
|
||||
( Stay model, shared, Cast.tryCast shared auth.token )
|
||||
|
||||
Copy id ->
|
||||
( Stay model, Ports.copyText id )
|
||||
( Stay model, shared, Ports.copyText id )
|
||||
|
||||
ChangeSection s ->
|
||||
let
|
||||
@@ -316,10 +329,10 @@ update wrap shared msg model =
|
||||
newRoute =
|
||||
{ r | section = Just s }
|
||||
in
|
||||
( Stay { model | route = newRoute }, newRoute |> Route.Lobby |> Route.url |> Navigation.replaceUrl shared.key )
|
||||
( Stay { model | route = newRoute }, shared, newRoute |> Route.Lobby |> Route.url |> Navigation.replaceUrl shared.key )
|
||||
|
||||
NoOp ->
|
||||
( Stay model, Cmd.none )
|
||||
( Stay model, shared, Cmd.none )
|
||||
|
||||
|
||||
view : (Msg -> msg) -> (Settings.Msg -> msg) -> Shared -> Model -> List (Html msg)
|
||||
@@ -501,13 +514,14 @@ notificationDuration =
|
||||
|
||||
applySync :
|
||||
(Msg -> msg)
|
||||
-> Shared
|
||||
-> Model
|
||||
-> Lobby
|
||||
-> Maybe (List Card.PotentiallyBlankResponse)
|
||||
-> Maybe (List Card.Played)
|
||||
-> Time.PartialAnchor
|
||||
-> ( Change, Cmd msg )
|
||||
applySync wrap model state hand pick partialTimeAnchor =
|
||||
-> ( Change, Shared, Cmd msg )
|
||||
applySync wrap shared model state hand pick partialTimeAnchor =
|
||||
let
|
||||
play =
|
||||
pick |> Maybe.map (\cards -> { state = Round.Submitted, cards = cards }) |> Maybe.withDefault Round.noPick
|
||||
@@ -515,7 +529,11 @@ applySync wrap model state hand pick partialTimeAnchor =
|
||||
( game, gameCmd ) =
|
||||
case state.game of
|
||||
Just g ->
|
||||
Util.modelLift Just (Game.init (GameMsg >> wrap) g.game (hand |> Maybe.withDefault []) play)
|
||||
let
|
||||
( newGame, cmd ) =
|
||||
Game.init (GameMsg >> wrap) g.game (hand |> Maybe.withDefault []) play
|
||||
in
|
||||
( Just newGame, cmd )
|
||||
|
||||
Nothing ->
|
||||
( Nothing, Cmd.none )
|
||||
@@ -531,12 +549,13 @@ applySync wrap model state hand pick partialTimeAnchor =
|
||||
| lobby = Just { state | game = game }
|
||||
, configure = { configure | localConfig = state.config }
|
||||
}
|
||||
, shared
|
||||
, Cmd.batch [ timeCmd, gameCmd ]
|
||||
)
|
||||
|
||||
|
||||
addNotification : (Msg -> msg) -> NotificationMessage -> Model -> ( Change, Cmd msg )
|
||||
addNotification wrap message model =
|
||||
addNotification : (Msg -> msg) -> Shared -> NotificationMessage -> Model -> ( Change, Shared, Cmd msg )
|
||||
addNotification wrap shared message model =
|
||||
let
|
||||
notification =
|
||||
{ id = model.notificationId, message = message }
|
||||
@@ -545,6 +564,7 @@ addNotification wrap message model =
|
||||
model.notifications ++ [ Animated.animate notification ]
|
||||
in
|
||||
( Stay { model | notifications = notifications, notificationId = model.notificationId + 1 }
|
||||
, shared
|
||||
, Animated.exitAfter (NotificationMsg >> wrap) notificationDuration notification
|
||||
)
|
||||
|
||||
|
||||
@@ -67,8 +67,8 @@ init =
|
||||
}
|
||||
|
||||
|
||||
update : Msg -> Model -> Config -> ( Model, Cmd msg )
|
||||
update msg model config =
|
||||
update : Shared -> Msg -> Model -> Config -> ( Model, Shared, Cmd msg )
|
||||
update shared msg model config =
|
||||
case msg of
|
||||
PrivacyMsg privacyMsg ->
|
||||
let
|
||||
@@ -78,14 +78,14 @@ update msg model config =
|
||||
( local, privacy, cmd ) =
|
||||
Privacy.update privacyMsg localConfig.privacy model.privacy
|
||||
in
|
||||
( { model | privacy = privacy, localConfig = { localConfig | privacy = local } }, cmd )
|
||||
( { model | privacy = privacy, localConfig = { localConfig | privacy = local } }, shared, cmd )
|
||||
|
||||
DecksMsg decksMsg ->
|
||||
let
|
||||
( decks, cmd ) =
|
||||
Decks.update decksMsg model.decks
|
||||
( decks, newShared, cmd ) =
|
||||
Decks.update shared decksMsg model.decks
|
||||
in
|
||||
( { model | decks = decks }, cmd )
|
||||
( { model | decks = decks }, newShared, cmd )
|
||||
|
||||
TimeLimitsMsg timeLimitsMsg ->
|
||||
let
|
||||
@@ -102,6 +102,7 @@ update msg model config =
|
||||
| timeLimits = timeLimits
|
||||
, localConfig = { localConfig | rules = { rules | timeLimits = local } }
|
||||
}
|
||||
, shared
|
||||
, cmd
|
||||
)
|
||||
|
||||
@@ -117,14 +118,15 @@ update msg model config =
|
||||
| rules = newRules
|
||||
, localConfig = { localConfig | rules = local }
|
||||
}
|
||||
, shared
|
||||
, cmd
|
||||
)
|
||||
|
||||
StartGame ->
|
||||
( model, Actions.startGame )
|
||||
( model, shared, Actions.startGame )
|
||||
|
||||
ChangeTab t ->
|
||||
( { model | tab = t }, Cmd.none )
|
||||
( { model | tab = t }, shared, Cmd.none )
|
||||
|
||||
ResolveConflict source id ->
|
||||
let
|
||||
@@ -146,24 +148,25 @@ update msg model config =
|
||||
|> Maybe.withDefault Cmd.none
|
||||
)
|
||||
in
|
||||
( { model | localConfig = newLocal, conflicts = model.conflicts |> List.filter ((/=) id) }, cmd )
|
||||
( { model | localConfig = newLocal, conflicts = model.conflicts |> List.filter ((/=) id) }, shared, cmd )
|
||||
|
||||
SaveChanges ->
|
||||
if Component.isValid all model.localConfig then
|
||||
( model
|
||||
, shared
|
||||
, patchFor config model.localConfig
|
||||
|> Maybe.map Actions.configure
|
||||
|> Maybe.withDefault Cmd.none
|
||||
)
|
||||
|
||||
else
|
||||
( model, Cmd.none )
|
||||
( model, shared, Cmd.none )
|
||||
|
||||
RevertChanges ->
|
||||
( { model | localConfig = config }, Cmd.none )
|
||||
( { model | localConfig = config }, shared, Cmd.none )
|
||||
|
||||
NoOp ->
|
||||
( model, Cmd.none )
|
||||
( model, shared, Cmd.none )
|
||||
|
||||
|
||||
view : (Msg -> msg) -> (Lobby.Msg -> msg) -> Shared -> Maybe msg -> Bool -> Model -> GameCode -> Lobby -> Html msg
|
||||
|
||||
@@ -27,6 +27,7 @@ import MassiveDecks.Pages.Lobby.Configure.Component as Component exposing (Compo
|
||||
import MassiveDecks.Pages.Lobby.Configure.Component.Validator as Validator exposing (Validator)
|
||||
import MassiveDecks.Pages.Lobby.Configure.ConfigOption as ConfigOption
|
||||
import MassiveDecks.Pages.Lobby.Configure.Decks.Model exposing (..)
|
||||
import MassiveDecks.Settings as Settings
|
||||
import MassiveDecks.Strings as Strings
|
||||
import MassiveDecks.Strings.Languages as Lang
|
||||
import MassiveDecks.Util.Html as Html
|
||||
@@ -55,17 +56,24 @@ default =
|
||||
|
||||
{-| React to user input.
|
||||
-}
|
||||
update : Msg -> Model -> ( Model, Cmd msg )
|
||||
update msg model =
|
||||
update : Shared -> Msg -> Model -> ( Model, Shared, Cmd msg )
|
||||
update shared msg model =
|
||||
case msg of
|
||||
Update source ->
|
||||
( { model | toAdd = source }, Cmd.none )
|
||||
( { model | toAdd = source }, shared, Cmd.none )
|
||||
|
||||
Add source ->
|
||||
( { model | toAdd = Source.emptyMatching source }, Actions.configure (addDeck source) )
|
||||
let
|
||||
( settings, settingsCmd ) =
|
||||
Settings.onAddDeck source shared.settings
|
||||
in
|
||||
( { model | toAdd = Source.emptyMatching source }
|
||||
, { shared | settings = settings }
|
||||
, Cmd.batch [ Actions.configure (addDeck source), settingsCmd ]
|
||||
)
|
||||
|
||||
Remove index ->
|
||||
( model, Actions.configure (removeDeck index) )
|
||||
( model, shared, Actions.configure (removeDeck index) )
|
||||
|
||||
|
||||
{-| View the editor/viewer for decks.
|
||||
@@ -199,7 +207,7 @@ addDeckWidget wrap shared existing deckToAdd =
|
||||
"add-deck"
|
||||
(Html.div [ HtmlA.class "multipart" ]
|
||||
(List.concat
|
||||
[ Source.generalEditor shared deckToAdd (Update >> wrap)
|
||||
[ Source.generalEditor shared existing deckToAdd (Update >> wrap)
|
||||
, [ Components.floatingActionButton
|
||||
[ HtmlA.type_ "submit"
|
||||
, Result.isError submit |> HtmlA.disabled
|
||||
|
||||
@@ -93,19 +93,19 @@ subscriptions wrap handleError model =
|
||||
Lobby.subscriptions (LobbyMsg >> wrap) handleError model.lobby
|
||||
|
||||
|
||||
update : (Msg -> msg) -> Shared -> Msg -> Model -> ( Model, Cmd msg )
|
||||
update : (Msg -> msg) -> Shared -> Msg -> Model -> ( Model, Shared, Cmd msg )
|
||||
update wrap shared msg model =
|
||||
case msg of
|
||||
LobbyMsg lobbyMsg ->
|
||||
case Lobby.update (LobbyMsg >> wrap) shared lobbyMsg model.lobby of
|
||||
( Lobby.Stay newModel, cmd ) ->
|
||||
( { model | lobby = newModel }, cmd )
|
||||
( Lobby.Stay newModel, newShared, cmd ) ->
|
||||
( { model | lobby = newModel }, newShared, cmd )
|
||||
|
||||
_ ->
|
||||
( model, Cmd.none )
|
||||
( model, shared, Cmd.none )
|
||||
|
||||
ToggleAdvert ->
|
||||
( { model | advertise = not model.advertise }, Cmd.none )
|
||||
( { model | advertise = not model.advertise }, shared, Cmd.none )
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ import MassiveDecks.Requests.HttpData.Model as HttpData exposing (HttpData)
|
||||
import MassiveDecks.Requests.Request as Request
|
||||
import MassiveDecks.Strings as Strings exposing (MdString)
|
||||
import MassiveDecks.Strings.Languages as Lang
|
||||
import MassiveDecks.Util as Util
|
||||
import MassiveDecks.Util.Html as Html
|
||||
import MassiveDecks.Util.Maybe as Maybe
|
||||
import MassiveDecks.Version as Version
|
||||
@@ -127,24 +126,33 @@ update shared msg model =
|
||||
( { model | name = name }, Cmd.none )
|
||||
|
||||
StartGame httpDataMsg ->
|
||||
Util.modelLift (\nlr -> { model | newLobbyRequest = nlr })
|
||||
(HttpData.update (startGameRequest model.name) httpDataMsg model.newLobbyRequest)
|
||||
let
|
||||
( nlr, cmd ) =
|
||||
HttpData.update (startGameRequest model.name) httpDataMsg model.newLobbyRequest
|
||||
in
|
||||
( { model | newLobbyRequest = nlr }, cmd )
|
||||
|
||||
JoinGame httpDataMsg ->
|
||||
case model.gameCode of
|
||||
Just gc ->
|
||||
Util.modelLift (\jlr -> { model | joinLobbyRequest = jlr })
|
||||
(HttpData.update
|
||||
(joinGameRequest gc model.name model.password)
|
||||
httpDataMsg
|
||||
model.joinLobbyRequest
|
||||
)
|
||||
let
|
||||
( jlr, cmd ) =
|
||||
HttpData.update
|
||||
(joinGameRequest gc model.name model.password)
|
||||
httpDataMsg
|
||||
model.joinLobbyRequest
|
||||
in
|
||||
( { model | joinLobbyRequest = jlr }, cmd )
|
||||
|
||||
_ ->
|
||||
( model, Cmd.none )
|
||||
|
||||
LobbyBrowserMsg lbm ->
|
||||
Util.modelLift (\lobbies -> { model | lobbies = lobbies }) (LobbyBrowser.update lbm model.lobbies)
|
||||
let
|
||||
( lobbies, cmd ) =
|
||||
LobbyBrowser.update lbm model.lobbies
|
||||
in
|
||||
( { model | lobbies = lobbies }, cmd )
|
||||
|
||||
PasswordChanged newPassword ->
|
||||
( { model | password = Just newPassword }, Cmd.none )
|
||||
|
||||
@@ -2,6 +2,7 @@ module MassiveDecks.Settings exposing
|
||||
( auths
|
||||
, defaults
|
||||
, init
|
||||
, onAddDeck
|
||||
, onJoinLobby
|
||||
, onTokenUpdate
|
||||
, removeToken
|
||||
@@ -18,6 +19,8 @@ import 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
|
||||
import MassiveDecks.Components as Components
|
||||
import MassiveDecks.Components.Form as Form
|
||||
import MassiveDecks.Components.Form.Message as Message
|
||||
@@ -170,6 +173,24 @@ view wrap shared =
|
||||
Html.div [] [ button, panel ]
|
||||
|
||||
|
||||
{-| Add a deck to the recent decks list, shuffling the oldest off if needed.
|
||||
-}
|
||||
onAddDeck : Source.External -> Model -> ( Model, Cmd msg )
|
||||
onAddDeck source model =
|
||||
let
|
||||
settings =
|
||||
model.settings
|
||||
|
||||
newRecentDecks =
|
||||
(source :: (settings.recentDecks |> List.filter (Source.equals source >> not)))
|
||||
|> List.take maxRecentDecks
|
||||
|
||||
updatedSettings =
|
||||
{ settings | recentDecks = newRecentDecks }
|
||||
in
|
||||
( { model | settings = updatedSettings }, LocalStorage.store updatedSettings )
|
||||
|
||||
|
||||
{-| Add a token to the token list and set the last used name, because the user has joined a lobby.
|
||||
We take an `Auth` here even though we don't really use it to ensure the token has been successfully parsed.
|
||||
-}
|
||||
@@ -233,6 +254,11 @@ auths settings =
|
||||
{- Private -}
|
||||
|
||||
|
||||
maxRecentDecks : Int
|
||||
maxRecentDecks =
|
||||
20
|
||||
|
||||
|
||||
changeSettings : (Settings -> Settings) -> Model -> ( Model, Cmd msg )
|
||||
changeSettings f model =
|
||||
let
|
||||
|
||||
@@ -4,7 +4,6 @@ module MassiveDecks.Settings.Model exposing
|
||||
, Settings
|
||||
, cardSizeFromValue
|
||||
, cardSizeToValue
|
||||
, cardSizes
|
||||
)
|
||||
|
||||
import Dict exposing (Dict)
|
||||
@@ -44,11 +43,6 @@ type CardSize
|
||||
| Full
|
||||
|
||||
|
||||
cardSizes : List CardSize
|
||||
cardSizes =
|
||||
[ Minimal, Square, Full ]
|
||||
|
||||
|
||||
cardSizeToValue : CardSize -> Int
|
||||
cardSizeToValue size =
|
||||
case size of
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
module MassiveDecks.Util exposing
|
||||
( batchUpdate
|
||||
, modelLift
|
||||
)
|
||||
|
||||
{-| General utility methods.
|
||||
-}
|
||||
|
||||
|
||||
{-| Take a `(model, cmd)` for a specific component and turn the model into a more general one.
|
||||
-}
|
||||
modelLift : (subModel -> model) -> ( subModel, Cmd msg ) -> ( model, Cmd msg )
|
||||
modelLift liftModel ( subModel, cmd ) =
|
||||
( liftModel subModel, cmd )
|
||||
|
||||
|
||||
{-| Perform the given update task for each of the messages in a row.
|
||||
-}
|
||||
batchUpdate : List msg -> model -> (msg -> model -> ( model, Cmd cmdMsg )) -> ( model, Cmd cmdMsg )
|
||||
batchUpdate messages model update =
|
||||
let
|
||||
( newModel, cmdList ) =
|
||||
messages |> List.foldl (batchUpdateStep update) ( model, [] )
|
||||
in
|
||||
( newModel, cmdList |> List.reverse |> Cmd.batch )
|
||||
|
||||
|
||||
|
||||
{- Private -}
|
||||
|
||||
|
||||
batchUpdateStep : (msg -> model -> ( model, Cmd cmdMsg )) -> msg -> ( model, List (Cmd cmdMsg) ) -> ( model, List (Cmd cmdMsg) )
|
||||
batchUpdateStep update msg ( model, cmdList ) =
|
||||
let
|
||||
( newModel, newCmd ) =
|
||||
update msg model
|
||||
in
|
||||
( newModel, newCmd :: cmdList )
|
||||
Reference in New Issue
Block a user