Resolve #23: Remember recent decks.

This commit is contained in:
Gareth Latty
2020-02-08 02:52:03 +00:00
parent a664a9d357
commit ff69d71d5f
14 changed files with 254 additions and 175 deletions
+32 -18
View File
@@ -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 ->
+7 -6
View File
@@ -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)
}
+5 -2
View File
@@ -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 )
+28 -17
View File
@@ -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 )
+65 -45
View File
@@ -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 )
+18 -10
View File
@@ -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 )
+26
View File
@@ -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
-38
View File
@@ -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 )