From 79d527866f13f273052b49fa02828526db77db60 Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Tue, 28 Jan 2020 00:31:55 -0500 Subject: [PATCH 1/5] added callback to EditPlayerState --- src/Mtlstats/Types.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Mtlstats/Types.hs b/src/Mtlstats/Types.hs index 54c79db..17f8116 100644 --- a/src/Mtlstats/Types.hs +++ b/src/Mtlstats/Types.hs @@ -98,6 +98,7 @@ module Mtlstats.Types ( -- ** EditPlayerState Lenses epsSelectedPlayer, epsMode, + epsCallback, -- ** EditGoalieState Lenses egsSelectedGoalie, egsMode, @@ -350,6 +351,8 @@ data EditPlayerState = EditPlayerState -- ^ The index number of the player being edited , _epsMode :: EditPlayerMode -- ^ The editing mode + , _epsCallback :: Action () + -- ^ The action to perform when the edit is complete } -- | Player editing mode @@ -818,6 +821,7 @@ newEditPlayerState :: EditPlayerState newEditPlayerState = EditPlayerState { _epsSelectedPlayer = Nothing , _epsMode = EPMenu + , _epsCallback = return () } -- | Constructor for an 'EditGoalieState' value From 2f0a3a5c57d3938fedf4eafce0f9f527e1198ceb Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Wed, 29 Jan 2020 01:19:25 -0500 Subject: [PATCH 2/5] perform follow-up action on player edit --- src/Mtlstats/Control/EditPlayer.hs | 80 ++++++++++++++------------- src/Mtlstats/Prompt/EditPlayer.hs | 88 +++++++++++++++++++++--------- 2 files changed, 105 insertions(+), 63 deletions(-) diff --git a/src/Mtlstats/Control/EditPlayer.hs b/src/Mtlstats/Control/EditPlayer.hs index d97f378..c31340b 100644 --- a/src/Mtlstats/Control/EditPlayer.hs +++ b/src/Mtlstats/Control/EditPlayer.hs @@ -37,58 +37,64 @@ import Mtlstats.Util editPlayerC :: EditPlayerState -> Controller editPlayerC eps | null $ eps^.epsSelectedPlayer = selectPlayerC - | otherwise = case eps^.epsMode of - EPMenu -> menuC - EPNumber -> numberC - EPName -> nameC - EPPosition -> positionC - EPYtd -> ytdC - EPLifetime -> lifetimeC - EPYtdGoals b -> ytdGoalsC b - EPYtdAssists b -> ytdAssistsC b - EPYtdPMin -> ytdPMinC - EPLtGoals b -> ltGoalsC b - EPLtAssists b -> ltAssistsC b - EPLtPMin -> ltPMinC + | otherwise = + ( case eps^.epsMode of + EPMenu -> menuC + EPNumber -> numberC + EPName -> nameC + EPPosition -> positionC + EPYtd -> ytdC + EPLifetime -> lifetimeC + EPYtdGoals b -> ytdGoalsC b + EPYtdAssists b -> ytdAssistsC b + EPYtdPMin -> ytdPMinC + EPLtGoals b -> ltGoalsC b + EPLtAssists b -> ltAssistsC b + EPLtPMin -> ltPMinC + ) $ eps^.epsCallback selectPlayerC :: Controller selectPlayerC = promptController playerToEditPrompt -menuC :: Controller -menuC = menuControllerWith header editPlayerMenu +menuC :: Action () -> Controller +menuC _ = menuControllerWith header editPlayerMenu -numberC :: Controller -numberC = promptController editPlayerNumPrompt +numberC :: Action () -> Controller +numberC = promptController . editPlayerNumPrompt -nameC :: Controller -nameC = promptController editPlayerNamePrompt +nameC :: Action () -> Controller +nameC = promptController . editPlayerNamePrompt -positionC :: Controller -positionC = promptController editPlayerPosPrompt +positionC :: Action () -> Controller +positionC = promptController . editPlayerPosPrompt -ytdC :: Controller -ytdC = menuControllerWith header editPlayerYtdMenu +ytdC :: Action () -> Controller +ytdC _ = menuControllerWith header editPlayerYtdMenu -lifetimeC :: Controller -lifetimeC = menuControllerWith header editPlayerLtMenu +lifetimeC :: Action () -> Controller +lifetimeC _ = menuControllerWith header editPlayerLtMenu -ytdGoalsC :: Bool -> Controller -ytdGoalsC = promptController . editPlayerYtdGoalsPrompt +ytdGoalsC :: Bool -> Action () -> Controller +ytdGoalsC batchMode callback = promptController $ + editPlayerYtdGoalsPrompt batchMode callback -ytdAssistsC :: Bool -> Controller -ytdAssistsC = promptController . editPlayerYtdAssistsPrompt +ytdAssistsC :: Bool -> Action () -> Controller +ytdAssistsC batchMode callback = promptController $ + editPlayerYtdAssistsPrompt batchMode callback -ytdPMinC :: Controller -ytdPMinC = promptController editPlayerYtdPMinPrompt +ytdPMinC :: Action () -> Controller +ytdPMinC = promptController . editPlayerYtdPMinPrompt -ltGoalsC :: Bool -> Controller -ltGoalsC = promptController . editPlayerLtGoalsPrompt +ltGoalsC :: Bool -> Action () -> Controller +ltGoalsC batchMode callback = promptController $ + editPlayerLtGoalsPrompt batchMode callback -ltAssistsC :: Bool -> Controller -ltAssistsC = promptController . editPlayerLtAssistsPrompt +ltAssistsC :: Bool -> Action () -> Controller +ltAssistsC batchMode callback = promptController $ + editPlayerLtAssistsPrompt batchMode callback -ltPMinC :: Controller -ltPMinC = promptController editPlayerLtPMinPrompt +ltPMinC :: Action () -> Controller +ltPMinC = promptController . editPlayerLtPMinPrompt header :: ProgState -> C.Update () header s = C.drawString $ fromMaybe "" $ do diff --git a/src/Mtlstats/Prompt/EditPlayer.hs b/src/Mtlstats/Prompt/EditPlayer.hs index 2d48051..2ae6b5c 100644 --- a/src/Mtlstats/Prompt/EditPlayer.hs +++ b/src/Mtlstats/Prompt/EditPlayer.hs @@ -39,46 +39,68 @@ import Mtlstats.Prompt import Mtlstats.Types -- | Prompt to edit a player's number -editPlayerNumPrompt :: Prompt +editPlayerNumPrompt + :: Action () + -- ^ The action to be performed upon completion + -> Prompt editPlayerNumPrompt = editNum "Player number: " EPMenu (pNumber .~) -- | Prompt to edit a player's name -editPlayerNamePrompt :: Prompt -editPlayerNamePrompt = namePrompt "Player name: " $ \name -> +editPlayerNamePrompt + :: Action () + -- ^ The action to be performed upon completion + -> Prompt +editPlayerNamePrompt callback = namePrompt "Player name: " $ \name -> do if null name - then goto EPMenu - else doEdit EPMenu $ pName .~ name + then goto EPMenu + else doEdit EPMenu $ pName .~ name + callback -- | Prompt to edit a player's position -editPlayerPosPrompt :: Prompt -editPlayerPosPrompt = ucStrPrompt "Player position: " $ \pos -> +editPlayerPosPrompt + :: Action () + -- ^ The action to be performed upon completion + -> Prompt +editPlayerPosPrompt callback = ucStrPrompt "Player position: " $ \pos -> do if null pos - then goto EPMenu - else doEdit EPMenu $ pPosition .~ pos + then goto EPMenu + else doEdit EPMenu $ pPosition .~ pos + callback -- | Prompt to edit a player's year-to-date goals editPlayerYtdGoalsPrompt :: Bool -- ^ Indicates wheter or not we're editing in batch mode + -> Action () + -- ^ The action to be performed upon completion -> Prompt -editPlayerYtdGoalsPrompt batchMode = editNum "Year-to-date goals: " mode - (pYtd.psGoals .~) +editPlayerYtdGoalsPrompt batchMode callback = editNum "Year-to-date goals: " mode + (pYtd.psGoals .~) callback' where - mode = if batchMode then EPYtdAssists True else EPYtd + (mode, callback') = if batchMode + then (EPYtdAssists True, return ()) + else (EPYtd, callback) -- | Prompt to edit a player's year-to-date assists editPlayerYtdAssistsPrompt :: Bool -- ^ Indicates wheter or not we're editing in batch mode + -> Action () + -- ^ The action to be performed upon completion -> Prompt -editPlayerYtdAssistsPrompt batchMode = editNum "Year-to-date assists: " mode - (pYtd.psAssists .~) +editPlayerYtdAssistsPrompt batchMode callback = editNum "Year-to-date assists: " mode + (pYtd.psAssists .~) callback' where - mode = if batchMode then EPYtdPMin else EPYtd + (mode, callback') = if batchMode + then (EPYtdPMin, return ()) + else (EPYtd, callback) -- | Prompt to edit a player's year-to-date penalty minutes -editPlayerYtdPMinPrompt :: Prompt +editPlayerYtdPMinPrompt + :: Action () + -- ^ The action to be performed upon completion + -> Prompt editPlayerYtdPMinPrompt = editNum "Year-to-date penalty minutes: " EPYtd (pYtd.psPMin .~) @@ -86,24 +108,35 @@ editPlayerYtdPMinPrompt = editNum "Year-to-date penalty minutes: " EPYtd editPlayerLtGoalsPrompt :: Bool -- ^ Indicates wheter or not we're editing in batch mode + -> Action () + -- ^ The action to be performed upon completion -> Prompt -editPlayerLtGoalsPrompt batchMode = editNum "Lifetime goals: " mode - (pLifetime.psGoals .~) +editPlayerLtGoalsPrompt batchMode callback = editNum "Lifetime goals: " mode + (pLifetime.psGoals .~) callback' where - mode = if batchMode then EPLtAssists True else EPLifetime + (mode, callback') = if batchMode + then (EPLtAssists True, return ()) + else (EPLifetime, callback) -- | Prompt to edit a player's lifetime assists editPlayerLtAssistsPrompt :: Bool -- ^ Indicates wheter or not we're editing in batch mode + -> Action () + -- ^ The action to be performed upon completion -> Prompt -editPlayerLtAssistsPrompt batchMode = editNum "Lifetime assists: " mode - (pLifetime.psAssists .~) +editPlayerLtAssistsPrompt batchMode callback = editNum "Lifetime assists: " mode + (pLifetime.psAssists .~) callback' where - mode = if batchMode then EPLtPMin else EPLifetime + (mode, callback') = if batchMode + then (EPLtPMin, return ()) + else (EPLifetime, callback) -- | Prompt to edit a player's lifetime penalty minutes -editPlayerLtPMinPrompt :: Prompt +editPlayerLtPMinPrompt + :: Action () + -- ^ The action to be performed upon completion + -> Prompt editPlayerLtPMinPrompt = editNum "Lifetime penalty minutes: " EPLifetime (pLifetime.psPMin .~) @@ -111,10 +144,13 @@ editNum :: String -> EditPlayerMode -> (Int -> Player -> Player) + -> Action () -> Prompt -editNum pStr mode f = numPromptWithFallback pStr - (goto mode) - (doEdit mode . f) +editNum pStr mode f callback = numPromptWithFallback pStr + (goto mode >> callback) + (\num -> do + doEdit mode $ f num + callback) doEdit :: EditPlayerMode -> (Player -> Player) -> Action () doEdit mode f = do From ffc139075541ae98b95d95b1b6486d611ddc8c50 Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Wed, 29 Jan 2020 12:10:57 -0500 Subject: [PATCH 3/5] created Mtlstats.Control.CreatePlayer module --- src/Mtlstats/Control.hs | 64 +++------------------ src/Mtlstats/Control/CreatePlayer.hs | 85 ++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 src/Mtlstats/Control/CreatePlayer.hs diff --git a/src/Mtlstats/Control.hs b/src/Mtlstats/Control.hs index b4964d6..1c192be 100644 --- a/src/Mtlstats/Control.hs +++ b/src/Mtlstats/Control.hs @@ -25,15 +25,15 @@ import Control.Monad (join) import Control.Monad.Trans.State (gets, modify) import Data.Maybe (fromJust) import Lens.Micro ((^.)) -import Lens.Micro.Extras (view) import qualified UI.NCurses as C import Mtlstats.Actions -import Mtlstats.Control.TitleScreen +import Mtlstats.Control.CreatePlayer import Mtlstats.Control.EditGoalie import Mtlstats.Control.EditPlayer import Mtlstats.Control.EditStandings import Mtlstats.Control.NewGame +import Mtlstats.Control.TitleScreen import Mtlstats.Handlers import Mtlstats.Menu import Mtlstats.Prompt @@ -43,16 +43,12 @@ import Mtlstats.Types -- run dispatch :: ProgState -> Controller dispatch s = case s^.progMode of - TitleScreen -> titleScreenC - MainMenu -> mainMenuC - NewSeason flag -> newSeasonC flag - NewGame gs -> newGameC gs - EditMenu -> editMenuC - CreatePlayer cps - | null $ cps^.cpsNumber -> getPlayerNumC - | null $ cps^.cpsName -> getPlayerNameC - | null $ cps^.cpsPosition -> getPlayerPosC - | otherwise -> confirmCreatePlayerC + TitleScreen -> titleScreenC + MainMenu -> mainMenuC + NewSeason flag -> newSeasonC flag + NewGame gs -> newGameC gs + EditMenu -> editMenuC + CreatePlayer cps -> createPlayerC cps CreateGoalie cgs | null $ cgs^.cgsNumber -> getGoalieNumC | null $ cgs^.cgsName -> getGoalieNameC @@ -74,50 +70,6 @@ newSeasonC True = menuController newSeasonMenu editMenuC :: Controller editMenuC = menuController editMenu -getPlayerNumC :: Controller -getPlayerNumC = Controller - { drawController = drawPrompt playerNumPrompt - , handleController = \e -> do - promptHandler playerNumPrompt e - return True - } - -getPlayerNameC :: Controller -getPlayerNameC = Controller - { drawController = drawPrompt playerNamePrompt - , handleController = \e -> do - promptHandler playerNamePrompt e - return True - } - -getPlayerPosC :: Controller -getPlayerPosC = Controller - { drawController = drawPrompt playerPosPrompt - , handleController = \e -> do - promptHandler playerPosPrompt e - return True - } - -confirmCreatePlayerC :: Controller -confirmCreatePlayerC = Controller - { drawController = \s -> do - let cps = s^.progMode.createPlayerStateL - C.drawString $ " Player number: " ++ show (fromJust $ cps^.cpsNumber) ++ "\n" - C.drawString $ " Player name: " ++ cps^.cpsName ++ "\n" - C.drawString $ "Player position: " ++ cps^.cpsPosition ++ "\n\n" - C.drawString "Create player: are you sure? (Y/N)" - return C.CursorInvisible - , handleController = \e -> do - case ynHandler e of - Just True -> do - modify addPlayer - join $ gets $ view $ progMode.createPlayerStateL.cpsSuccessCallback - Just False -> - join $ gets $ view $ progMode.createPlayerStateL.cpsFailureCallback - Nothing -> return () - return True - } - getGoalieNumC :: Controller getGoalieNumC = Controller { drawController = drawPrompt goalieNumPrompt diff --git a/src/Mtlstats/Control/CreatePlayer.hs b/src/Mtlstats/Control/CreatePlayer.hs new file mode 100644 index 0000000..afebf22 --- /dev/null +++ b/src/Mtlstats/Control/CreatePlayer.hs @@ -0,0 +1,85 @@ +{- | + +mtlstats +Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe + + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +-} + +module Mtlstats.Control.CreatePlayer (createPlayerC) where + +import Control.Monad (join) +import Control.Monad.Trans.State (gets, modify) +import Data.Maybe (fromJust) +import Lens.Micro ((^.)) +import qualified UI.NCurses as C + +import Mtlstats.Actions +import Mtlstats.Handlers +import Mtlstats.Prompt +import Mtlstats.Types + +-- | Handles player creation +createPlayerC :: CreatePlayerState -> Controller +createPlayerC cps + | null $ cps^.cpsNumber = getPlayerNumC + | null $ cps^.cpsName = getPlayerNameC + | null $ cps^.cpsPosition = getPlayerPosC + | otherwise = confirmCreatePlayerC + +getPlayerNumC :: Controller +getPlayerNumC = Controller + { drawController = drawPrompt playerNumPrompt + , handleController = \e -> do + promptHandler playerNumPrompt e + return True + } + +getPlayerNameC :: Controller +getPlayerNameC = Controller + { drawController = drawPrompt playerNamePrompt + , handleController = \e -> do + promptHandler playerNamePrompt e + return True + } + +getPlayerPosC :: Controller +getPlayerPosC = Controller + { drawController = drawPrompt playerPosPrompt + , handleController = \e -> do + promptHandler playerPosPrompt e + return True + } + +confirmCreatePlayerC :: Controller +confirmCreatePlayerC = Controller + { drawController = \s -> do + let cps = s^.progMode.createPlayerStateL + C.drawString $ " Player number: " ++ show (fromJust $ cps^.cpsNumber) ++ "\n" + C.drawString $ " Player name: " ++ cps^.cpsName ++ "\n" + C.drawString $ "Player position: " ++ cps^.cpsPosition ++ "\n\n" + C.drawString "Create player: are you sure? (Y/N)" + return C.CursorInvisible + , handleController = \e -> do + case ynHandler e of + Just True -> do + modify addPlayer + join $ gets (^.progMode.createPlayerStateL.cpsSuccessCallback) + Just False -> + join $ gets (^.progMode.createPlayerStateL.cpsFailureCallback) + Nothing -> return () + return True + } From 95e74accd4290ac9a529272a4b93922c81807a48 Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Thu, 30 Jan 2020 23:39:20 -0500 Subject: [PATCH 4/5] edit lifetime stats on new player creation --- src/Mtlstats/Control/CreatePlayer.hs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Mtlstats/Control/CreatePlayer.hs b/src/Mtlstats/Control/CreatePlayer.hs index afebf22..01b8275 100644 --- a/src/Mtlstats/Control/CreatePlayer.hs +++ b/src/Mtlstats/Control/CreatePlayer.hs @@ -24,7 +24,7 @@ module Mtlstats.Control.CreatePlayer (createPlayerC) where import Control.Monad (join) import Control.Monad.Trans.State (gets, modify) import Data.Maybe (fromJust) -import Lens.Micro ((^.)) +import Lens.Micro ((^.), (.~), (?~), (%~), to) import qualified UI.NCurses as C import Mtlstats.Actions @@ -76,8 +76,14 @@ confirmCreatePlayerC = Controller , handleController = \e -> do case ynHandler e of Just True -> do - modify addPlayer - join $ gets (^.progMode.createPlayerStateL.cpsSuccessCallback) + pid <- gets (^.database.dbPlayers.to length) + cb <- gets (^.progMode.createPlayerStateL.cpsSuccessCallback) + modify + $ (progMode.editPlayerStateL + %~ (epsSelectedPlayer ?~ pid) + . (epsMode .~ EPLtGoals True) + . (epsCallback .~ cb)) + . addPlayer Just False -> join $ gets (^.progMode.createPlayerStateL.cpsFailureCallback) Nothing -> return () From 6418ab0eea8e98da3fcff3666ae4697d4bad0aec Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Thu, 30 Jan 2020 23:41:08 -0500 Subject: [PATCH 5/5] update change log --- ChangeLog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index b74b28e..5346e18 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,8 @@ # Changelog for mtlstats +## current +- Edit lifetime stats on new player creation + ## 0.11.0 - Added active flag to players/goalies - Clear rookie flag on new (regular) season