Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
994087a0e6 | ||
|
|
7fbeaac933 | ||
|
|
de56f4f94d | ||
|
|
04ba17324e | ||
|
|
d6ae171dc8 | ||
|
|
72b6f05700 | ||
|
|
4c7a756c5e | ||
|
|
ea3ca4e578 | ||
|
|
179a864cfa | ||
|
|
f2b2ff3fef | ||
|
|
9c2e2291c8 | ||
|
|
abad72ce01 | ||
|
|
a9d4d3351f | ||
|
|
45aea607b2 | ||
|
|
be9d7d80bb | ||
|
|
683c36e2b6 | ||
|
|
83c408cea2 | ||
|
|
dcbd68cdda | ||
|
|
717f2d5932 | ||
|
|
d5de834510 | ||
|
|
75a47ca852 | ||
|
|
d4de7c6f8b | ||
|
|
d50d055b0b | ||
|
|
9c7c295a4b | ||
|
|
49963277be | ||
|
|
264d9f81e2 | ||
|
|
6a0d1f7203 | ||
|
|
18683c1c6e | ||
|
|
107ed507e2 | ||
|
|
baf040deea | ||
|
|
c3bac5e624 | ||
|
|
119cb873eb | ||
|
|
82603ba504 | ||
|
|
a909b9ba7a | ||
|
|
802bf7314e | ||
|
|
a3124aca58 | ||
|
|
f113e46564 | ||
|
|
39646f3fa7 | ||
|
|
2bf8d15bd4 | ||
|
|
3009a8f60c | ||
|
|
3b4ce50ae8 | ||
|
|
fcfbcea72f | ||
|
|
d132ebd502 | ||
|
|
75cd253f3f | ||
|
|
063bebfbb5 | ||
|
|
7923827d22 | ||
|
|
461fb5d942 | ||
|
|
e38275aefe |
12
ChangeLog.md
12
ChangeLog.md
@@ -1,5 +1,13 @@
|
|||||||
# Changelog for mtlstats
|
# Changelog for mtlstats
|
||||||
|
|
||||||
|
## 0.11.0
|
||||||
|
- Added active flag to players/goalies
|
||||||
|
- Clear rookie flag on new (regular) season
|
||||||
|
- Save a copy of the database on new season
|
||||||
|
- Implemented game standings editing
|
||||||
|
- Added title screen
|
||||||
|
- Changed sytling of menus
|
||||||
|
|
||||||
## 0.10.0
|
## 0.10.0
|
||||||
- Don't show player number zero in reports
|
- Don't show player number zero in reports
|
||||||
- Fixed player/goalie name capitalisation on edit
|
- Fixed player/goalie name capitalisation on edit
|
||||||
@@ -33,24 +41,20 @@
|
|||||||
- Reset game standings on new season
|
- Reset game standings on new season
|
||||||
|
|
||||||
## 0.5.0
|
## 0.5.0
|
||||||
|
|
||||||
- Fixed player creation bug
|
- Fixed player creation bug
|
||||||
- Prompt for goalie informaiton on game data entry
|
- Prompt for goalie informaiton on game data entry
|
||||||
- Implemented player editing
|
- Implemented player editing
|
||||||
|
|
||||||
## v0.4.0
|
## v0.4.0
|
||||||
|
|
||||||
- Record penalty minutes
|
- Record penalty minutes
|
||||||
- Calculate total game statistics
|
- Calculate total game statistics
|
||||||
- Generate year-to-date statistics report
|
- Generate year-to-date statistics report
|
||||||
|
|
||||||
## v0.3.0
|
## v0.3.0
|
||||||
|
|
||||||
- Record goals and assists
|
- Record goals and assists
|
||||||
- Track goals for and goals against
|
- Track goals for and goals against
|
||||||
|
|
||||||
## v0.2.0
|
## v0.2.0
|
||||||
|
|
||||||
- Overtime losses don't count in the loss column
|
- Overtime losses don't count in the loss column
|
||||||
- Confirm game data with user before updating stats
|
- Confirm game data with user before updating stats
|
||||||
- Implemented player creation
|
- Implemented player creation
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: mtlstats
|
name: mtlstats
|
||||||
version: 0.10.0
|
version: 0.11.0
|
||||||
github: "mtlstats/mtlstats"
|
github: "mtlstats/mtlstats"
|
||||||
license: GPL-3
|
license: GPL-3
|
||||||
author: "Jonathan Lamothe"
|
author: "Jonathan Lamothe"
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
module Mtlstats.Actions
|
module Mtlstats.Actions
|
||||||
( startNewSeason
|
( startNewSeason
|
||||||
, resetYtd
|
, resetYtd
|
||||||
|
, clearRookies
|
||||||
, resetStandings
|
, resetStandings
|
||||||
, startNewGame
|
, startNewGame
|
||||||
, addChar
|
, addChar
|
||||||
@@ -42,18 +43,29 @@ module Mtlstats.Actions
|
|||||||
, backHome
|
, backHome
|
||||||
, scrollUp
|
, scrollUp
|
||||||
, scrollDown
|
, scrollDown
|
||||||
|
, saveDatabase
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad.Trans.State (modify)
|
import Control.Monad.IO.Class (liftIO)
|
||||||
|
import Control.Monad.Trans.State (gets, modify)
|
||||||
|
import Data.Aeson (encodeFile)
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Lens.Micro ((^.), (&), (.~), (%~))
|
import Lens.Micro ((^.), (&), (.~), (%~))
|
||||||
|
import System.EasyFile
|
||||||
|
( createDirectoryIfMissing
|
||||||
|
, getAppUserDataDirectory
|
||||||
|
, (</>)
|
||||||
|
)
|
||||||
|
|
||||||
|
import Mtlstats.Config
|
||||||
import Mtlstats.Types
|
import Mtlstats.Types
|
||||||
import Mtlstats.Util
|
import Mtlstats.Util
|
||||||
|
|
||||||
-- | Starts a new season
|
-- | Starts a new season
|
||||||
startNewSeason :: ProgState -> ProgState
|
startNewSeason :: ProgState -> ProgState
|
||||||
startNewSeason = (progMode .~ NewSeason) . (database . dbGames .~ 0)
|
startNewSeason
|
||||||
|
= (progMode .~ NewSeason False)
|
||||||
|
. (database.dbGames .~ 0)
|
||||||
|
|
||||||
-- | Resets all players year-to-date stats
|
-- | Resets all players year-to-date stats
|
||||||
resetYtd :: ProgState -> ProgState
|
resetYtd :: ProgState -> ProgState
|
||||||
@@ -61,6 +73,12 @@ resetYtd
|
|||||||
= (database . dbPlayers %~ map (pYtd .~ newPlayerStats))
|
= (database . dbPlayers %~ map (pYtd .~ newPlayerStats))
|
||||||
. (database . dbGoalies %~ map (gYtd .~ newGoalieStats))
|
. (database . dbGoalies %~ map (gYtd .~ newGoalieStats))
|
||||||
|
|
||||||
|
-- | Clears the rookie flag from all players/goalies
|
||||||
|
clearRookies :: ProgState -> ProgState
|
||||||
|
clearRookies = database
|
||||||
|
%~ (dbPlayers %~ map (pRookie .~ False))
|
||||||
|
. (dbGoalies %~ map (gRookie .~ False))
|
||||||
|
|
||||||
-- | Resets game standings
|
-- | Resets game standings
|
||||||
resetStandings :: ProgState -> ProgState
|
resetStandings :: ProgState -> ProgState
|
||||||
resetStandings = database
|
resetStandings = database
|
||||||
@@ -189,3 +207,13 @@ scrollUp = scrollOffset %~ max 0 . pred
|
|||||||
-- | Scrolls the display down
|
-- | Scrolls the display down
|
||||||
scrollDown :: ProgState -> ProgState
|
scrollDown :: ProgState -> ProgState
|
||||||
scrollDown = scrollOffset %~ succ
|
scrollDown = scrollOffset %~ succ
|
||||||
|
|
||||||
|
-- | Saves the database
|
||||||
|
saveDatabase :: String -> Action ()
|
||||||
|
saveDatabase fn = do
|
||||||
|
db <- gets (^.database)
|
||||||
|
liftIO $ do
|
||||||
|
dir <- getAppUserDataDirectory appName
|
||||||
|
let dbFile = dir </> fn
|
||||||
|
createDirectoryIfMissing True dir
|
||||||
|
encodeFile dbFile db
|
||||||
|
|||||||
70
src/Mtlstats/Actions/EditStandings.hs
Normal file
70
src/Mtlstats/Actions/EditStandings.hs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
{- |
|
||||||
|
|
||||||
|
mtlstats
|
||||||
|
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||||
|
<rheal.lamothe@gmail.com>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Mtlstats.Actions.EditStandings
|
||||||
|
( editStandings
|
||||||
|
, editHomeStandings
|
||||||
|
, editAwayStandings
|
||||||
|
, editWins
|
||||||
|
, editLosses
|
||||||
|
, editOvertime
|
||||||
|
, editGoalsFor
|
||||||
|
, editGoalsAgainst
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Lens.Micro ((.~))
|
||||||
|
|
||||||
|
import Mtlstats.Types
|
||||||
|
|
||||||
|
-- | Enters edit standings mode
|
||||||
|
editStandings :: ProgState -> ProgState
|
||||||
|
editStandings = progMode .~ EditStandings ESMMenu
|
||||||
|
|
||||||
|
-- | Edits the home standings
|
||||||
|
editHomeStandings :: ProgState -> ProgState
|
||||||
|
editHomeStandings = progMode .~ EditStandings (ESMHome ESMSubMenu)
|
||||||
|
|
||||||
|
-- | Edits the road standings
|
||||||
|
editAwayStandings :: ProgState -> ProgState
|
||||||
|
editAwayStandings = progMode .~ EditStandings (ESMAway ESMSubMenu)
|
||||||
|
|
||||||
|
-- | Changes to edit wins mode
|
||||||
|
editWins :: ProgState -> ProgState
|
||||||
|
editWins = doEdit ESMEditWins
|
||||||
|
|
||||||
|
-- | Changes to edit losses mode
|
||||||
|
editLosses :: ProgState -> ProgState
|
||||||
|
editLosses = doEdit ESMEditLosses
|
||||||
|
|
||||||
|
-- | Changes to edit overtime mode
|
||||||
|
editOvertime :: ProgState -> ProgState
|
||||||
|
editOvertime = doEdit ESMEditOvertime
|
||||||
|
|
||||||
|
-- | Changes to edit goals for mode
|
||||||
|
editGoalsFor :: ProgState -> ProgState
|
||||||
|
editGoalsFor = doEdit ESMEditGoalsFor
|
||||||
|
|
||||||
|
-- | Changes to edit goals against mode
|
||||||
|
editGoalsAgainst :: ProgState -> ProgState
|
||||||
|
editGoalsAgainst = doEdit ESMEditGoalsAgainst
|
||||||
|
|
||||||
|
doEdit :: ESMSubMode -> ProgState -> ProgState
|
||||||
|
doEdit = (progMode.editStandingsModeL.esmSubModeL .~)
|
||||||
@@ -29,8 +29,10 @@ import Lens.Micro.Extras (view)
|
|||||||
import qualified UI.NCurses as C
|
import qualified UI.NCurses as C
|
||||||
|
|
||||||
import Mtlstats.Actions
|
import Mtlstats.Actions
|
||||||
|
import Mtlstats.Control.TitleScreen
|
||||||
import Mtlstats.Control.EditGoalie
|
import Mtlstats.Control.EditGoalie
|
||||||
import Mtlstats.Control.EditPlayer
|
import Mtlstats.Control.EditPlayer
|
||||||
|
import Mtlstats.Control.EditStandings
|
||||||
import Mtlstats.Control.NewGame
|
import Mtlstats.Control.NewGame
|
||||||
import Mtlstats.Handlers
|
import Mtlstats.Handlers
|
||||||
import Mtlstats.Menu
|
import Mtlstats.Menu
|
||||||
@@ -41,10 +43,11 @@ import Mtlstats.Types
|
|||||||
-- run
|
-- run
|
||||||
dispatch :: ProgState -> Controller
|
dispatch :: ProgState -> Controller
|
||||||
dispatch s = case s^.progMode of
|
dispatch s = case s^.progMode of
|
||||||
MainMenu -> mainMenuC
|
TitleScreen -> titleScreenC
|
||||||
NewSeason -> newSeasonC
|
MainMenu -> mainMenuC
|
||||||
NewGame gs -> newGameC gs
|
NewSeason flag -> newSeasonC flag
|
||||||
EditMenu -> editMenuC
|
NewGame gs -> newGameC gs
|
||||||
|
EditMenu -> editMenuC
|
||||||
CreatePlayer cps
|
CreatePlayer cps
|
||||||
| null $ cps^.cpsNumber -> getPlayerNumC
|
| null $ cps^.cpsNumber -> getPlayerNumC
|
||||||
| null $ cps^.cpsName -> getPlayerNameC
|
| null $ cps^.cpsName -> getPlayerNameC
|
||||||
@@ -54,8 +57,9 @@ dispatch s = case s^.progMode of
|
|||||||
| null $ cgs^.cgsNumber -> getGoalieNumC
|
| null $ cgs^.cgsNumber -> getGoalieNumC
|
||||||
| null $ cgs^.cgsName -> getGoalieNameC
|
| null $ cgs^.cgsName -> getGoalieNameC
|
||||||
| otherwise -> confirmCreateGoalieC
|
| otherwise -> confirmCreateGoalieC
|
||||||
EditPlayer eps -> editPlayerC eps
|
EditPlayer eps -> editPlayerC eps
|
||||||
EditGoalie egs -> editGoalieC egs
|
EditGoalie egs -> editGoalieC egs
|
||||||
|
(EditStandings esm) -> editStandingsC esm
|
||||||
|
|
||||||
mainMenuC :: Controller
|
mainMenuC :: Controller
|
||||||
mainMenuC = Controller
|
mainMenuC = Controller
|
||||||
@@ -63,13 +67,9 @@ mainMenuC = Controller
|
|||||||
, handleController = menuHandler mainMenu
|
, handleController = menuHandler mainMenu
|
||||||
}
|
}
|
||||||
|
|
||||||
newSeasonC :: Controller
|
newSeasonC :: Bool -> Controller
|
||||||
newSeasonC = Controller
|
newSeasonC False = promptController newSeasonPrompt
|
||||||
{ drawController = const $ drawMenu newSeasonMenu
|
newSeasonC True = menuController newSeasonMenu
|
||||||
, handleController = \e -> do
|
|
||||||
menuHandler newSeasonMenu e
|
|
||||||
return True
|
|
||||||
}
|
|
||||||
|
|
||||||
editMenuC :: Controller
|
editMenuC :: Controller
|
||||||
editMenuC = menuController editMenu
|
editMenuC = menuController editMenu
|
||||||
|
|||||||
87
src/Mtlstats/Control/EditStandings.hs
Normal file
87
src/Mtlstats/Control/EditStandings.hs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
{- |
|
||||||
|
|
||||||
|
mtlstats
|
||||||
|
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||||
|
<rheal.lamothe@gmail.com>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
|
||||||
|
module Mtlstats.Control.EditStandings (editStandingsC) where
|
||||||
|
|
||||||
|
import Lens.Micro ((^.))
|
||||||
|
import qualified UI.NCurses as C
|
||||||
|
|
||||||
|
import Mtlstats.Format
|
||||||
|
import Mtlstats.Menu
|
||||||
|
import Mtlstats.Menu.EditStandings
|
||||||
|
import Mtlstats.Prompt
|
||||||
|
import Mtlstats.Prompt.EditStandings
|
||||||
|
import Mtlstats.Types
|
||||||
|
import Mtlstats.Types.Menu
|
||||||
|
|
||||||
|
-- | Controller for the edit standings menu
|
||||||
|
editStandingsC :: EditStandingsMode -> Controller
|
||||||
|
editStandingsC = \case
|
||||||
|
ESMMenu -> menuControllerWith header editStandingsMenu
|
||||||
|
ESMHome m -> editHomeStandingsC m
|
||||||
|
ESMAway m -> editAwayStandingsC m
|
||||||
|
|
||||||
|
editHomeStandingsC :: ESMSubMode -> Controller
|
||||||
|
editHomeStandingsC = \case
|
||||||
|
ESMSubMenu -> menuC editHomeStandingsMenu
|
||||||
|
ESMEditWins -> promptC editHomeWinsPrompt
|
||||||
|
ESMEditLosses -> promptC editHomeLossesPrompt
|
||||||
|
ESMEditOvertime -> promptC editHomeOvertimePrompt
|
||||||
|
ESMEditGoalsFor -> promptC editHomeGoalsForPrompt
|
||||||
|
ESMEditGoalsAgainst -> promptC editHomeGoalsAgainstPrompt
|
||||||
|
|
||||||
|
editAwayStandingsC :: ESMSubMode -> Controller
|
||||||
|
editAwayStandingsC = \case
|
||||||
|
ESMSubMenu -> menuC editAwayStandingsMenu
|
||||||
|
ESMEditWins -> promptC editAwayWinsPrompt
|
||||||
|
ESMEditLosses -> promptC editAwayLossesPrompt
|
||||||
|
ESMEditOvertime -> promptC editAwayOvertimePrompt
|
||||||
|
ESMEditGoalsFor -> promptC editAwayGoalsForPrompt
|
||||||
|
ESMEditGoalsAgainst -> promptC editAwayGoalsAgainstPrompt
|
||||||
|
|
||||||
|
menuC :: Menu () -> Controller
|
||||||
|
menuC = menuControllerWith header
|
||||||
|
|
||||||
|
promptC :: Prompt -> Controller
|
||||||
|
promptC = promptControllerWith header
|
||||||
|
|
||||||
|
header :: ProgState -> C.Update ()
|
||||||
|
header = do
|
||||||
|
db <- (^.database)
|
||||||
|
let
|
||||||
|
home = db^.dbHomeGameStats
|
||||||
|
away = db^.dbAwayGameStats
|
||||||
|
table = numTable [" W", " L", " OT", " GF", " GA"]
|
||||||
|
[ ( "HOME", valsFor home )
|
||||||
|
, ( "ROAD", valsFor away )
|
||||||
|
]
|
||||||
|
return $ C.drawString $ unlines $ table ++ [""]
|
||||||
|
|
||||||
|
valsFor :: GameStats -> [Int]
|
||||||
|
valsFor gs =
|
||||||
|
[ gs^.gmsWins
|
||||||
|
, gs^.gmsLosses
|
||||||
|
, gs^.gmsOvertime
|
||||||
|
, gs^.gmsGoalsFor
|
||||||
|
, gs^.gmsGoalsAgainst
|
||||||
|
]
|
||||||
142
src/Mtlstats/Control/TitleScreen.hs
Normal file
142
src/Mtlstats/Control/TitleScreen.hs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
{- |
|
||||||
|
|
||||||
|
mtlstats
|
||||||
|
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||||
|
<rheal.lamothe@gmail.com>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
|
||||||
|
module Mtlstats.Control.TitleScreen (titleScreenC) where
|
||||||
|
|
||||||
|
import Control.Monad.Trans.State (modify)
|
||||||
|
import Data.Char (chr)
|
||||||
|
import qualified UI.NCurses as C
|
||||||
|
|
||||||
|
import Mtlstats.Actions
|
||||||
|
import Mtlstats.Format
|
||||||
|
import Mtlstats.Types
|
||||||
|
|
||||||
|
titleScreenC :: Controller
|
||||||
|
titleScreenC = Controller
|
||||||
|
{ drawController = const $ do
|
||||||
|
(_, cols) <- C.windowSize
|
||||||
|
C.drawString $ unlines $ map (centre $ fromIntegral $ pred cols)
|
||||||
|
$ [ ""
|
||||||
|
, "MONTREAL CANADIENS STATISTICS"
|
||||||
|
]
|
||||||
|
++ titleText
|
||||||
|
++ [ ""
|
||||||
|
, "Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe"
|
||||||
|
, "<rheal.lamothe@gmail.com>"
|
||||||
|
, ""
|
||||||
|
, "Press any key to continue..."
|
||||||
|
]
|
||||||
|
return C.CursorInvisible
|
||||||
|
, handleController = \case
|
||||||
|
C.EventCharacter _ -> modify backHome >> return True
|
||||||
|
C.EventSpecialKey _ -> modify backHome >> return True
|
||||||
|
_ -> return True
|
||||||
|
}
|
||||||
|
|
||||||
|
titleText :: [String]
|
||||||
|
titleText = box $ map (map blockify) $ foldl joinBlocks (repeat "")
|
||||||
|
[chM, chT, chL, chS, chT, chA, chT, chS]
|
||||||
|
|
||||||
|
box :: [String] -> [String]
|
||||||
|
box strs
|
||||||
|
= [[tl] ++ replicate width horiz ++ [tr]]
|
||||||
|
++ map (\str -> [vert] ++ str ++ [vert]) strs
|
||||||
|
++ [[bl] ++ replicate width horiz ++ [br]]
|
||||||
|
where
|
||||||
|
width = length $ head strs
|
||||||
|
tl = chr 0x2554
|
||||||
|
tr = chr 0x2557
|
||||||
|
bl = chr 0x255a
|
||||||
|
br = chr 0x255d
|
||||||
|
horiz = chr 0x2550
|
||||||
|
vert = chr 0x2551
|
||||||
|
|
||||||
|
blockify :: Char -> Char
|
||||||
|
blockify = \case
|
||||||
|
'#' -> chr 0x2588
|
||||||
|
'>' -> chr 0x2590
|
||||||
|
'<' -> chr 0x258c
|
||||||
|
ch -> ch
|
||||||
|
|
||||||
|
joinBlocks :: [String] -> [String] -> [String]
|
||||||
|
joinBlocks = zipWith (++)
|
||||||
|
|
||||||
|
chM :: [String]
|
||||||
|
chM =
|
||||||
|
[ "##< >##"
|
||||||
|
, ">## ##<"
|
||||||
|
, ">##< >##<"
|
||||||
|
, ">### ###<"
|
||||||
|
, ">#######<"
|
||||||
|
, ">#<###>#<"
|
||||||
|
, ">#<>#<>#<"
|
||||||
|
, "##< >##"
|
||||||
|
]
|
||||||
|
|
||||||
|
chT :: [String]
|
||||||
|
chT =
|
||||||
|
[ ">########<"
|
||||||
|
, ">## ## ##<"
|
||||||
|
, ">#< ## >#<"
|
||||||
|
, " ## "
|
||||||
|
, " ## "
|
||||||
|
, " ## "
|
||||||
|
, " ## "
|
||||||
|
, " >##< "
|
||||||
|
]
|
||||||
|
|
||||||
|
chL :: [String]
|
||||||
|
chL =
|
||||||
|
[ "### "
|
||||||
|
, ">#< "
|
||||||
|
, ">#< "
|
||||||
|
, ">#< "
|
||||||
|
, ">#< "
|
||||||
|
, ">#< ##"
|
||||||
|
, ">#< >##"
|
||||||
|
, "#######"
|
||||||
|
]
|
||||||
|
|
||||||
|
chS :: [String]
|
||||||
|
chS =
|
||||||
|
[ " #####< "
|
||||||
|
, ">#< ## "
|
||||||
|
, "## "
|
||||||
|
, " #####< "
|
||||||
|
, " >#<"
|
||||||
|
, " ##"
|
||||||
|
, ">#< >#<"
|
||||||
|
, " ###### "
|
||||||
|
]
|
||||||
|
|
||||||
|
chA :: [String]
|
||||||
|
chA =
|
||||||
|
[ " >##< "
|
||||||
|
, " ## "
|
||||||
|
, " >##< "
|
||||||
|
, " #### "
|
||||||
|
, " >#<>#< "
|
||||||
|
, " ###### "
|
||||||
|
, ">#< >#<"
|
||||||
|
, "### ###"
|
||||||
|
]
|
||||||
@@ -51,8 +51,12 @@ goalieDetails g = let
|
|||||||
goalieName :: Goalie -> String
|
goalieName :: Goalie -> String
|
||||||
goalieName g = let
|
goalieName g = let
|
||||||
|
|
||||||
|
prefix = if g^.gActive
|
||||||
|
then ""
|
||||||
|
else "*"
|
||||||
|
|
||||||
suffix = if g^.gRookie
|
suffix = if g^.gRookie
|
||||||
then "*"
|
then "*"
|
||||||
else ""
|
else ""
|
||||||
|
|
||||||
in g^.gName ++ suffix
|
in prefix ++ g^.gName ++ suffix
|
||||||
|
|||||||
@@ -49,8 +49,12 @@ playerDetails p = unlines $ top ++ [""] ++ table
|
|||||||
playerName :: Player -> String
|
playerName :: Player -> String
|
||||||
playerName p = let
|
playerName p = let
|
||||||
|
|
||||||
|
prefix = if p^.pActive
|
||||||
|
then ""
|
||||||
|
else "*"
|
||||||
|
|
||||||
suffix = if p^.pRookie
|
suffix = if p^.pRookie
|
||||||
then "*"
|
then "*"
|
||||||
else ""
|
else ""
|
||||||
|
|
||||||
in p^.pName ++ suffix
|
in prefix ++ p^.pName ++ suffix
|
||||||
|
|||||||
@@ -35,24 +35,18 @@ module Mtlstats.Menu (
|
|||||||
editMenu
|
editMenu
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad.IO.Class (liftIO)
|
|
||||||
import Control.Monad.Trans.State (gets, modify)
|
import Control.Monad.Trans.State (gets, modify)
|
||||||
import Data.Aeson (encodeFile)
|
|
||||||
import Data.Char (toUpper)
|
import Data.Char (toUpper)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Data.Maybe (mapMaybe)
|
import Data.Maybe (mapMaybe)
|
||||||
import Lens.Micro ((^.), (?~))
|
import Lens.Micro ((^.), (?~))
|
||||||
import Lens.Micro.Extras (view)
|
|
||||||
import System.EasyFile
|
|
||||||
( createDirectoryIfMissing
|
|
||||||
, getAppUserDataDirectory
|
|
||||||
, (</>)
|
|
||||||
)
|
|
||||||
import qualified UI.NCurses as C
|
import qualified UI.NCurses as C
|
||||||
|
|
||||||
import Mtlstats.Actions
|
import Mtlstats.Actions
|
||||||
import qualified Mtlstats.Actions.NewGame.GoalieInput as GI
|
import qualified Mtlstats.Actions.NewGame.GoalieInput as GI
|
||||||
|
import Mtlstats.Actions.EditStandings
|
||||||
import Mtlstats.Config
|
import Mtlstats.Config
|
||||||
|
import Mtlstats.Format
|
||||||
import Mtlstats.Types
|
import Mtlstats.Types
|
||||||
import Mtlstats.Types.Menu
|
import Mtlstats.Types.Menu
|
||||||
import Mtlstats.Util
|
import Mtlstats.Util
|
||||||
@@ -96,7 +90,11 @@ menuStateController menuFunc = Controller
|
|||||||
-- | The draw function for a 'Menu'
|
-- | The draw function for a 'Menu'
|
||||||
drawMenu :: Menu a -> C.Update C.CursorMode
|
drawMenu :: Menu a -> C.Update C.CursorMode
|
||||||
drawMenu m = do
|
drawMenu m = do
|
||||||
C.drawString $ show m
|
(_, cols) <- C.windowSize
|
||||||
|
let
|
||||||
|
width = fromIntegral $ pred cols
|
||||||
|
menuText = map (centre width) $ lines $ show m
|
||||||
|
C.drawString $ unlines menuText
|
||||||
return C.CursorInvisible
|
return C.CursorInvisible
|
||||||
|
|
||||||
-- | The event handler for a 'Menu'
|
-- | The event handler for a 'Menu'
|
||||||
@@ -109,61 +107,56 @@ menuHandler m _ = return $ m^.menuDefault
|
|||||||
|
|
||||||
-- | The main menu
|
-- | The main menu
|
||||||
mainMenu :: Menu Bool
|
mainMenu :: Menu Bool
|
||||||
mainMenu = Menu "*** MAIN MENU ***" True
|
mainMenu = Menu "MASTER MENU" True
|
||||||
[ MenuItem '1' "New Season" $
|
[ MenuItem 'A' "NEW SEASON" $
|
||||||
modify startNewSeason >> return True
|
modify startNewSeason >> return True
|
||||||
, MenuItem '2' "New Game" $
|
, MenuItem 'B' "NEW GAME" $
|
||||||
modify startNewGame >> return True
|
modify startNewGame >> return True
|
||||||
, MenuItem '3' "Edit" $
|
, MenuItem 'C' "EDIT MENU" $
|
||||||
modify edit >> return True
|
modify edit >> return True
|
||||||
, MenuItem 'X' "Exit" $ do
|
, MenuItem 'E' "EXIT" $
|
||||||
db <- gets $ view database
|
saveDatabase dbFname >> return False
|
||||||
liftIO $ do
|
|
||||||
dir <- getAppUserDataDirectory appName
|
|
||||||
let dbFile = dir </> dbFname
|
|
||||||
createDirectoryIfMissing True dir
|
|
||||||
encodeFile dbFile db
|
|
||||||
return False
|
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | The new season menu
|
-- | The new season menu
|
||||||
newSeasonMenu :: Menu ()
|
newSeasonMenu :: Menu ()
|
||||||
newSeasonMenu = Menu "*** SEASON TYPE ***" ()
|
newSeasonMenu = Menu "SEASON TYPE" ()
|
||||||
[ MenuItem 'R' "Regular Season" $ modify
|
[ MenuItem 'R' "REGULAR SEASON" $ modify
|
||||||
$ resetYtd
|
$ resetYtd
|
||||||
|
. clearRookies
|
||||||
. resetStandings
|
. resetStandings
|
||||||
. startNewGame
|
. startNewGame
|
||||||
, MenuItem 'P' "Playoffs" $ modify
|
, MenuItem 'P' "PLAYOFFS" $ modify
|
||||||
$ resetStandings
|
$ resetStandings
|
||||||
. startNewGame
|
. startNewGame
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | Requests the month in which the game took place
|
-- | Requests the month in which the game took place
|
||||||
gameMonthMenu :: Menu ()
|
gameMonthMenu :: Menu ()
|
||||||
gameMonthMenu = Menu "Month:" () $ map
|
gameMonthMenu = Menu "MONTH:" () $ map
|
||||||
(\(ch, name, val) ->
|
(\(ch, name, val) ->
|
||||||
MenuItem ch name $
|
MenuItem ch name $
|
||||||
modify $ progMode.gameStateL.gameMonth ?~ val)
|
modify $ progMode.gameStateL.gameMonth ?~ val)
|
||||||
[ ( 'A', "January", 1 )
|
[ ( 'A', "JANUARY", 1 )
|
||||||
, ( 'B', "February", 2 )
|
, ( 'B', "FEBRUARY", 2 )
|
||||||
, ( 'C', "March", 3 )
|
, ( 'C', "MARCH", 3 )
|
||||||
, ( 'D', "April", 4 )
|
, ( 'D', "APRIL", 4 )
|
||||||
, ( 'E', "May", 5 )
|
, ( 'E', "MAY", 5 )
|
||||||
, ( 'F', "June", 6 )
|
, ( 'F', "JUNE", 6 )
|
||||||
, ( 'G', "July", 7 )
|
, ( 'G', "JULY", 7 )
|
||||||
, ( 'H', "August", 8 )
|
, ( 'H', "AUGUST", 8 )
|
||||||
, ( 'I', "September", 9 )
|
, ( 'I', "SEPTEMBER", 9 )
|
||||||
, ( 'J', "October", 10 )
|
, ( 'J', "OCTOBER", 10 )
|
||||||
, ( 'K', "November", 11 )
|
, ( 'K', "NOVEMBER", 11 )
|
||||||
, ( 'L', "December", 12 )
|
, ( 'L', "DECEMBER", 12 )
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | The game type menu (home/away)
|
-- | The game type menu (home/away)
|
||||||
gameTypeMenu :: Menu ()
|
gameTypeMenu :: Menu ()
|
||||||
gameTypeMenu = Menu "Game type:" ()
|
gameTypeMenu = Menu "GAME TYPE:" ()
|
||||||
[ MenuItem '1' "Home Game" $
|
[ MenuItem 'H' "HOME GAME" $
|
||||||
modify $ progMode.gameStateL.gameType ?~ HomeGame
|
modify $ progMode.gameStateL.gameType ?~ HomeGame
|
||||||
, MenuItem '2' "Away Game" $
|
, MenuItem 'A' "AWAY GAME" $
|
||||||
modify $ progMode.gameStateL.gameType ?~ AwayGame
|
modify $ progMode.gameStateL.gameType ?~ AwayGame
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -184,15 +177,17 @@ gameGoalieMenu s = let
|
|||||||
|
|
||||||
-- | The edit menu
|
-- | The edit menu
|
||||||
editMenu :: Menu ()
|
editMenu :: Menu ()
|
||||||
editMenu = Menu "*** EDIT ***" ()
|
editMenu = Menu "EDIT MENU" ()
|
||||||
[ MenuItem '1' "Create Player" $
|
[ MenuItem 'A' "CREATE PLAYER" $
|
||||||
modify createPlayer
|
modify createPlayer
|
||||||
, MenuItem '2' "Create Goalie" $
|
, MenuItem 'B' "CREATE GOALIE" $
|
||||||
modify createGoalie
|
modify createGoalie
|
||||||
, MenuItem '3' "Edit Player" $
|
, MenuItem 'C' "EDIT PLAYER" $
|
||||||
modify editPlayer
|
modify editPlayer
|
||||||
, MenuItem '4' "Edit Goalie" $
|
, MenuItem 'D' "EDIT GOALIE" $
|
||||||
modify editGoalie
|
modify editGoalie
|
||||||
, MenuItem 'R' "Return to Main Menu" $
|
, MenuItem 'E' "EDIT STANDINGS" $
|
||||||
|
modify editStandings
|
||||||
|
, MenuItem 'R' "RETURN TO MAIN MENU" $
|
||||||
modify backHome
|
modify backHome
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -34,51 +34,53 @@ import Mtlstats.Types.Menu
|
|||||||
|
|
||||||
-- | The 'Goalie' edit menu
|
-- | The 'Goalie' edit menu
|
||||||
editGoalieMenu :: Menu ()
|
editGoalieMenu :: Menu ()
|
||||||
editGoalieMenu = Menu "*** EDIT GOALTENDER ***" () $ map
|
editGoalieMenu = Menu "EDIT GOALTENDER" () $ map
|
||||||
(\(ch, label, action) -> MenuItem ch label $ modify action)
|
(\(ch, label, action) -> MenuItem ch label $ modify action)
|
||||||
|
|
||||||
-- key, label, value
|
-- key, label, value
|
||||||
[ ( '1', "Edit number", set EGNumber )
|
[ ( 'A', "EDIT NUMBER", set EGNumber )
|
||||||
, ( '2', "Edit name", set EGName )
|
, ( 'B', "EDIT NAME", set EGName )
|
||||||
, ( '3', "Toggle rookie flag", toggle )
|
, ( 'C', "TOGGLE ROOKIE FLAG", toggleRookie )
|
||||||
, ( '4', "Edit YTD stats", set EGYtd )
|
, ( 'D', "TOGGLE ACTIVE FLAG", toggleActive )
|
||||||
, ( '5', "Edit Lifetime stats", set EGLifetime )
|
, ( 'E', "EDIT YTD STATS", set EGYtd )
|
||||||
, ( 'R', "Return to Edit Menu", edit )
|
, ( 'F', "EDIT LIFETIME STATS", set EGLifetime )
|
||||||
|
, ( 'R', "RETURN TO EDIT MENU", edit )
|
||||||
]
|
]
|
||||||
|
|
||||||
where
|
where
|
||||||
set mode = progMode.editGoalieStateL.egsMode .~ mode
|
set mode = progMode.editGoalieStateL.egsMode .~ mode
|
||||||
toggle = editSelectedGoalie (gRookie %~ not)
|
toggleRookie = editSelectedGoalie (gRookie %~ not)
|
||||||
|
toggleActive = editSelectedGoalie (gActive %~ not)
|
||||||
|
|
||||||
-- | The 'Goalie' YTD edit menu
|
-- | The 'Goalie' YTD edit menu
|
||||||
editGoalieYtdMenu :: Menu ()
|
editGoalieYtdMenu :: Menu ()
|
||||||
editGoalieYtdMenu = editMenu "*** EDIT GOALTENDER YEAR-TO-DATE ***"
|
editGoalieYtdMenu = editMenu "EDIT GOALTENDER YEAR-TO-DATE"
|
||||||
-- key, label, value
|
-- key, label, value
|
||||||
[ ( '1', "Edit all YTD stats", EGYtdGames True )
|
[ ( 'A', "EDIT ALL YTD STATS", EGYtdGames True )
|
||||||
, ( '2', "Edit YTD games", EGYtdGames False )
|
, ( 'B', "EDIT YTD GAMES", EGYtdGames False )
|
||||||
, ( '3', "Edit YTD minutes", EGYtdMins False )
|
, ( 'C', "EDIT YTD MINUTES", EGYtdMins False )
|
||||||
, ( '4', "Edit YTD goals", EGYtdGoals False )
|
, ( 'D', "EDIT YTD GOALS", EGYtdGoals False )
|
||||||
, ( '5', "Edit YTD shutouts", EGYtdShutouts False )
|
, ( 'E', "EDIT YTD SHUTOUTS", EGYtdShutouts False )
|
||||||
, ( '6', "Edit YTD wins", EGYtdWins False )
|
, ( 'F', "EDIT YTD WINS", EGYtdWins False )
|
||||||
, ( '7', "Edit YTD losses", EGYtdLosses False )
|
, ( 'G', "EDIT YTD LOSSES", EGYtdLosses False )
|
||||||
, ( '8', "Edit YTD ties", EGYtdTies )
|
, ( 'H', "EDIT YTD TIES", EGYtdTies )
|
||||||
, ( 'R', "Return to edit menu", EGMenu )
|
, ( 'R', "RETURN TO EDIT MENU", EGMenu )
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | The 'Goalie' lifetime edit menu
|
-- | The 'Goalie' lifetime edit menu
|
||||||
editGoalieLtMenu :: Menu ()
|
editGoalieLtMenu :: Menu ()
|
||||||
editGoalieLtMenu = editMenu
|
editGoalieLtMenu = editMenu
|
||||||
"*** EDIT GOALTENDER LIFETIME ***"
|
"EDIT GOALTENDER LIFETIME"
|
||||||
-- key, label, value
|
-- key, label, value
|
||||||
[ ( '1', "Edit all lifetime stats", EGLtGames True )
|
[ ( 'A', "EDIT ALL LIFETIME STATS", EGLtGames True )
|
||||||
, ( '2', "Edit lifetime games", EGLtGames False )
|
, ( 'B', "EDIT LIFETIME GAMES", EGLtGames False )
|
||||||
, ( '3', "Edit lifetime minutes", EGLtMins False )
|
, ( 'C', "EDIT LIFETIME MINUTES", EGLtMins False )
|
||||||
, ( '4', "Edit lifetime goals", EGLtGoals False )
|
, ( 'D', "EDIT LIFETIME GOALS", EGLtGoals False )
|
||||||
, ( '5', "Edit lifetime shutouts", EGLtShutouts False )
|
, ( 'E', "EDIT LIFETIME SHUTOUTS", EGLtShutouts False )
|
||||||
, ( '6', "Edit lifetime wins", EGLtWins False )
|
, ( 'F', "EDIT LIFETIME WINS", EGLtWins False )
|
||||||
, ( '7', "Edit lifetime losses", EGLtLosses False )
|
, ( 'G', "EDIT LIFETIME LOSSES", EGLtLosses False )
|
||||||
, ( '8', "Edit lifetime ties", EGLtTies )
|
, ( 'H', "EDIT LIFETIME TIES", EGLtTies )
|
||||||
, ( 'R', "Return to edit menu", EGMenu )
|
, ( 'R', "RETURN TO EDIT MENU", EGMenu )
|
||||||
]
|
]
|
||||||
|
|
||||||
editMenu :: String -> [(Char, String, EditGoalieMode)] -> Menu ()
|
editMenu :: String -> [(Char, String, EditGoalieMode)] -> Menu ()
|
||||||
|
|||||||
@@ -34,45 +34,47 @@ import Mtlstats.Types.Menu
|
|||||||
|
|
||||||
-- | The 'Player' edit menu
|
-- | The 'Player' edit menu
|
||||||
editPlayerMenu :: Menu ()
|
editPlayerMenu :: Menu ()
|
||||||
editPlayerMenu = Menu "*** EDIT PLAYER ***" () $ map
|
editPlayerMenu = Menu "EDIT PLAYER" () $ map
|
||||||
(\(ch, label, action) -> MenuItem ch label $ modify action)
|
(\(ch, label, action) -> MenuItem ch label $ modify action)
|
||||||
|
|
||||||
-- key, label, value
|
-- key, label, value
|
||||||
[ ( '1', "Edit number", set EPNumber )
|
[ ( 'A', "EDIT NUMBER", set EPNumber )
|
||||||
, ( '2', "Edit name", set EPName )
|
, ( 'B', "EDIT NAME", set EPName )
|
||||||
, ( '3', "Edit position", set EPPosition )
|
, ( 'C', "EDIT POSITION", set EPPosition )
|
||||||
, ( '4', "Toggle rookie flag", toggle )
|
, ( 'D', "TOGGLE ROOKIE FLAG", toggleRookie )
|
||||||
, ( '5', "Edit YTD stats", set EPYtd )
|
, ( 'E', "TOGGLE ACTIVE FLAG", toggleActive )
|
||||||
, ( '6', "Edit lifetime stats", set EPLifetime )
|
, ( 'F', "EDIT YTD STATS", set EPYtd )
|
||||||
, ( 'R', "Return to Edit Menu", edit )
|
, ( 'G', "EDIT LIFETIME STATS", set EPLifetime )
|
||||||
|
, ( 'R', "RETURN TO EDIT MENU", edit )
|
||||||
]
|
]
|
||||||
|
|
||||||
where
|
where
|
||||||
set mode = progMode.editPlayerStateL.epsMode .~ mode
|
set mode = progMode.editPlayerStateL.epsMode .~ mode
|
||||||
toggle = editSelectedPlayer $ pRookie %~ not
|
toggleRookie = editSelectedPlayer $ pRookie %~ not
|
||||||
|
toggleActive = editSelectedPlayer $ pActive %~ not
|
||||||
|
|
||||||
-- | The 'Player' YTD stats edit menu
|
-- | The 'Player' YTD stats edit menu
|
||||||
editPlayerYtdMenu :: Menu ()
|
editPlayerYtdMenu :: Menu ()
|
||||||
editPlayerYtdMenu = editMenu
|
editPlayerYtdMenu = editMenu
|
||||||
"*** EDIT PLAYER YEAR-TO-DATE ***"
|
"EDIT PLAYER YEAR-TO-DATE"
|
||||||
-- key, label, value
|
-- key, label, value
|
||||||
[ ( '1', "Edit all YTD stats", EPYtdGoals True )
|
[ ( 'A', "EDIT ALL YTD STATS", EPYtdGoals True )
|
||||||
, ( '2', "Edit YTD goals", EPYtdGoals False )
|
, ( 'B', "EDIT YTD GOALS", EPYtdGoals False )
|
||||||
, ( '3', "Edit YTD assists", EPYtdAssists False )
|
, ( 'C', "EDIT YTD ASSISTS", EPYtdAssists False )
|
||||||
, ( '4', "Edit YTD penalty mins", EPYtdPMin )
|
, ( 'D', "EDIT YTD PENALTY MINS", EPYtdPMin )
|
||||||
, ( 'R', "Return to player edit menu", EPMenu )
|
, ( 'R', "RETURN TO PLAYER EDIT MENU", EPMenu )
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | The 'Player' lifetime stats edit menu
|
-- | The 'Player' lifetime stats edit menu
|
||||||
editPlayerLtMenu :: Menu ()
|
editPlayerLtMenu :: Menu ()
|
||||||
editPlayerLtMenu = editMenu
|
editPlayerLtMenu = editMenu
|
||||||
"*** EDIT PLAYER LIFETIME ***"
|
"EDIT PLAYER LIFETIME"
|
||||||
-- key, label, value
|
-- key, label, value
|
||||||
[ ( '1', "Edit all lifetime stats", EPLtGoals True )
|
[ ( 'A', "EDIT ALL LIFETIME STATS", EPLtGoals True )
|
||||||
, ( '2', "Edit lifetime goals", EPLtGoals False )
|
, ( 'B', "EDIT LIFETIME GOALS", EPLtGoals False )
|
||||||
, ( '3', "Edit lifetime assits", EPLtAssists False )
|
, ( 'C', "EDIT LIFETIME ASSITS", EPLtAssists False )
|
||||||
, ( '4', "Edit lifetime penalty mins", EPLtPMin )
|
, ( 'D', "EDIT LIFETIME PENALTY MINS", EPLtPMin )
|
||||||
, ( 'R', "Return to edit player menu", EPMenu )
|
, ( 'R', "RETURN TO EDIT PLAYER MENU", EPMenu )
|
||||||
]
|
]
|
||||||
|
|
||||||
editMenu :: String -> [(Char, String, EditPlayerMode)] -> Menu ()
|
editMenu :: String -> [(Char, String, EditPlayerMode)] -> Menu ()
|
||||||
|
|||||||
64
src/Mtlstats/Menu/EditStandings.hs
Normal file
64
src/Mtlstats/Menu/EditStandings.hs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{- |
|
||||||
|
|
||||||
|
mtlstats
|
||||||
|
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||||
|
<rheal.lamothe@gmail.com>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Mtlstats.Menu.EditStandings
|
||||||
|
( editStandingsMenu
|
||||||
|
, editHomeStandingsMenu
|
||||||
|
, editAwayStandingsMenu
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Control.Monad.Trans.State (modify)
|
||||||
|
|
||||||
|
import Mtlstats.Actions
|
||||||
|
import Mtlstats.Actions.EditStandings
|
||||||
|
import Mtlstats.Types.Menu
|
||||||
|
|
||||||
|
editStandingsMenu :: Menu ()
|
||||||
|
editStandingsMenu = Menu "EDIT STANDINGS" ()
|
||||||
|
[ MenuItem 'A' "EDIT HOME STANDINGS" $
|
||||||
|
modify editHomeStandings
|
||||||
|
, MenuItem 'B' "EDIT ROAD STANDINGS" $
|
||||||
|
modify editAwayStandings
|
||||||
|
, MenuItem 'R' "RETURN TO MAIN MENU" $
|
||||||
|
modify backHome
|
||||||
|
]
|
||||||
|
|
||||||
|
editHomeStandingsMenu :: Menu ()
|
||||||
|
editHomeStandingsMenu = subMenu "HOME"
|
||||||
|
|
||||||
|
editAwayStandingsMenu :: Menu ()
|
||||||
|
editAwayStandingsMenu = subMenu "ROAD"
|
||||||
|
|
||||||
|
subMenu :: String -> Menu ()
|
||||||
|
subMenu str = Menu (str ++ " STANDINGS") ()
|
||||||
|
[ MenuItem 'W' "EDIT WINS" $
|
||||||
|
modify editWins
|
||||||
|
, MenuItem 'L' "EDIT LOSSES" $
|
||||||
|
modify editLosses
|
||||||
|
, MenuItem 'O' "EDIT OVERTIME GAMES" $
|
||||||
|
modify editOvertime
|
||||||
|
, MenuItem 'F' "EDIT GOALS FOR" $
|
||||||
|
modify editGoalsFor
|
||||||
|
, MenuItem 'A' "EDIT GOALS AGAINST" $
|
||||||
|
modify editGoalsAgainst
|
||||||
|
, MenuItem 'R' "RETURN TO EDIT STANDINGS MENU" $
|
||||||
|
modify editStandings
|
||||||
|
]
|
||||||
@@ -34,6 +34,7 @@ module Mtlstats.Prompt (
|
|||||||
numPromptWithFallback,
|
numPromptWithFallback,
|
||||||
selectPrompt,
|
selectPrompt,
|
||||||
-- * Individual prompts
|
-- * Individual prompts
|
||||||
|
newSeasonPrompt,
|
||||||
playerNumPrompt,
|
playerNumPrompt,
|
||||||
playerNamePrompt,
|
playerNamePrompt,
|
||||||
playerPosPrompt,
|
playerPosPrompt,
|
||||||
@@ -47,7 +48,7 @@ module Mtlstats.Prompt (
|
|||||||
import Control.Monad (when)
|
import Control.Monad (when)
|
||||||
import Control.Monad.Extra (whenJust)
|
import Control.Monad.Extra (whenJust)
|
||||||
import Control.Monad.Trans.State (gets, modify)
|
import Control.Monad.Trans.State (gets, modify)
|
||||||
import Data.Char (isDigit, toUpper)
|
import Data.Char (isAlphaNum, isDigit, toUpper)
|
||||||
import Lens.Micro ((^.), (&), (.~), (?~), (%~))
|
import Lens.Micro ((^.), (&), (.~), (?~), (%~))
|
||||||
import Lens.Micro.Extras (view)
|
import Lens.Micro.Extras (view)
|
||||||
import Text.Read (readMaybe)
|
import Text.Read (readMaybe)
|
||||||
@@ -167,6 +168,22 @@ numPromptWithFallback pStr fallback act = Prompt
|
|||||||
, promptSpecialKey = const $ return ()
|
, promptSpecialKey = const $ return ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- | Prompts the user for a filename to save a backup of the database
|
||||||
|
-- to
|
||||||
|
newSeasonPrompt :: Prompt
|
||||||
|
newSeasonPrompt = prompt
|
||||||
|
{ promptProcessChar = \ch str -> if isAlphaNum ch
|
||||||
|
then str ++ [toUpper ch]
|
||||||
|
else str
|
||||||
|
}
|
||||||
|
where
|
||||||
|
prompt = strPrompt "Filename to save database: " $ \fn ->
|
||||||
|
if null fn
|
||||||
|
then modify backHome
|
||||||
|
else do
|
||||||
|
saveDatabase $ fn ++ ".json"
|
||||||
|
modify $ progMode .~ NewSeason True
|
||||||
|
|
||||||
-- | Builds a selection prompt
|
-- | Builds a selection prompt
|
||||||
selectPrompt :: SelectParams a -> Prompt
|
selectPrompt :: SelectParams a -> Prompt
|
||||||
selectPrompt params = Prompt
|
selectPrompt params = Prompt
|
||||||
|
|||||||
89
src/Mtlstats/Prompt/EditStandings.hs
Normal file
89
src/Mtlstats/Prompt/EditStandings.hs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{- |
|
||||||
|
|
||||||
|
mtlstats
|
||||||
|
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||||
|
<rheal.lamothe@gmail.com>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Mtlstats.Prompt.EditStandings
|
||||||
|
( editHomeWinsPrompt
|
||||||
|
, editHomeLossesPrompt
|
||||||
|
, editHomeOvertimePrompt
|
||||||
|
, editHomeGoalsForPrompt
|
||||||
|
, editHomeGoalsAgainstPrompt
|
||||||
|
, editAwayWinsPrompt
|
||||||
|
, editAwayLossesPrompt
|
||||||
|
, editAwayOvertimePrompt
|
||||||
|
, editAwayGoalsForPrompt
|
||||||
|
, editAwayGoalsAgainstPrompt
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Control.Monad.Trans.State (modify)
|
||||||
|
import Lens.Micro ((.~), (%~))
|
||||||
|
|
||||||
|
import Mtlstats.Prompt
|
||||||
|
import Mtlstats.Types
|
||||||
|
|
||||||
|
editHomeWinsPrompt :: Prompt
|
||||||
|
editHomeWinsPrompt =
|
||||||
|
mkPrompt "Home wins: " (dbHomeGameStats.gmsWins .~)
|
||||||
|
|
||||||
|
editHomeLossesPrompt :: Prompt
|
||||||
|
editHomeLossesPrompt =
|
||||||
|
mkPrompt "Home losses: " (dbHomeGameStats.gmsLosses .~)
|
||||||
|
|
||||||
|
editHomeOvertimePrompt :: Prompt
|
||||||
|
editHomeOvertimePrompt =
|
||||||
|
mkPrompt "Home overtime games: " (dbHomeGameStats.gmsOvertime .~)
|
||||||
|
|
||||||
|
editHomeGoalsForPrompt :: Prompt
|
||||||
|
editHomeGoalsForPrompt =
|
||||||
|
mkPrompt "Home goals for: " (dbHomeGameStats.gmsGoalsFor .~)
|
||||||
|
|
||||||
|
editHomeGoalsAgainstPrompt :: Prompt
|
||||||
|
editHomeGoalsAgainstPrompt =
|
||||||
|
mkPrompt "Home goals against: " (dbHomeGameStats.gmsGoalsAgainst .~)
|
||||||
|
|
||||||
|
editAwayWinsPrompt :: Prompt
|
||||||
|
editAwayWinsPrompt =
|
||||||
|
mkPrompt "Road wins: " (dbAwayGameStats.gmsWins .~)
|
||||||
|
|
||||||
|
editAwayLossesPrompt :: Prompt
|
||||||
|
editAwayLossesPrompt =
|
||||||
|
mkPrompt "Road losses: " (dbAwayGameStats.gmsLosses .~)
|
||||||
|
|
||||||
|
editAwayOvertimePrompt :: Prompt
|
||||||
|
editAwayOvertimePrompt =
|
||||||
|
mkPrompt "Road overtime games: " (dbAwayGameStats.gmsOvertime .~)
|
||||||
|
|
||||||
|
editAwayGoalsForPrompt :: Prompt
|
||||||
|
editAwayGoalsForPrompt =
|
||||||
|
mkPrompt "Road goals for: " (dbAwayGameStats.gmsGoalsFor .~)
|
||||||
|
|
||||||
|
editAwayGoalsAgainstPrompt :: Prompt
|
||||||
|
editAwayGoalsAgainstPrompt =
|
||||||
|
mkPrompt "Road goals against: " (dbAwayGameStats.gmsGoalsAgainst .~)
|
||||||
|
|
||||||
|
mkPrompt :: String -> (Int -> Database -> Database) -> Prompt
|
||||||
|
mkPrompt pStr f = numPromptWithFallback pStr
|
||||||
|
(modify subMenu)
|
||||||
|
(\n -> modify
|
||||||
|
$ (database %~ f n)
|
||||||
|
. subMenu)
|
||||||
|
|
||||||
|
subMenu :: ProgState -> ProgState
|
||||||
|
subMenu = progMode.editStandingsModeL.esmSubModeL .~ ESMSubMenu
|
||||||
@@ -35,6 +35,8 @@ module Mtlstats.Types (
|
|||||||
EditPlayerMode (..),
|
EditPlayerMode (..),
|
||||||
EditGoalieState (..),
|
EditGoalieState (..),
|
||||||
EditGoalieMode (..),
|
EditGoalieMode (..),
|
||||||
|
EditStandingsMode (..),
|
||||||
|
ESMSubMode (..),
|
||||||
Database (..),
|
Database (..),
|
||||||
Player (..),
|
Player (..),
|
||||||
PlayerStats (..),
|
PlayerStats (..),
|
||||||
@@ -56,6 +58,9 @@ module Mtlstats.Types (
|
|||||||
createGoalieStateL,
|
createGoalieStateL,
|
||||||
editPlayerStateL,
|
editPlayerStateL,
|
||||||
editGoalieStateL,
|
editGoalieStateL,
|
||||||
|
editStandingsModeL,
|
||||||
|
-- ** EditStandingsMode Lenses
|
||||||
|
esmSubModeL,
|
||||||
-- ** GameState Lenses
|
-- ** GameState Lenses
|
||||||
gameYear,
|
gameYear,
|
||||||
gameMonth,
|
gameMonth,
|
||||||
@@ -107,6 +112,7 @@ module Mtlstats.Types (
|
|||||||
pName,
|
pName,
|
||||||
pPosition,
|
pPosition,
|
||||||
pRookie,
|
pRookie,
|
||||||
|
pActive,
|
||||||
pYtd,
|
pYtd,
|
||||||
pLifetime,
|
pLifetime,
|
||||||
-- ** PlayerStats Lenses
|
-- ** PlayerStats Lenses
|
||||||
@@ -117,6 +123,7 @@ module Mtlstats.Types (
|
|||||||
gNumber,
|
gNumber,
|
||||||
gName,
|
gName,
|
||||||
gRookie,
|
gRookie,
|
||||||
|
gActive,
|
||||||
gYtd,
|
gYtd,
|
||||||
gLifetime,
|
gLifetime,
|
||||||
-- ** GoalieStats Lenses
|
-- ** GoalieStats Lenses
|
||||||
@@ -229,24 +236,28 @@ data ProgState = ProgState
|
|||||||
|
|
||||||
-- | The program mode
|
-- | The program mode
|
||||||
data ProgMode
|
data ProgMode
|
||||||
= MainMenu
|
= TitleScreen
|
||||||
| NewSeason
|
| MainMenu
|
||||||
|
| NewSeason Bool
|
||||||
| NewGame GameState
|
| NewGame GameState
|
||||||
| EditMenu
|
| EditMenu
|
||||||
| CreatePlayer CreatePlayerState
|
| CreatePlayer CreatePlayerState
|
||||||
| CreateGoalie CreateGoalieState
|
| CreateGoalie CreateGoalieState
|
||||||
| EditPlayer EditPlayerState
|
| EditPlayer EditPlayerState
|
||||||
| EditGoalie EditGoalieState
|
| EditGoalie EditGoalieState
|
||||||
|
| EditStandings EditStandingsMode
|
||||||
|
|
||||||
instance Show ProgMode where
|
instance Show ProgMode where
|
||||||
show MainMenu = "MainMenu"
|
show TitleScreen = "TitleScreen"
|
||||||
show NewSeason = "NewSeason"
|
show MainMenu = "MainMenu"
|
||||||
show (NewGame _) = "NewGame"
|
show (NewSeason _) = "NewSeason"
|
||||||
show EditMenu = "EditMenu"
|
show (NewGame _) = "NewGame"
|
||||||
show (CreatePlayer _) = "CreatePlayer"
|
show EditMenu = "EditMenu"
|
||||||
show (CreateGoalie _) = "CreateGoalie"
|
show (CreatePlayer _) = "CreatePlayer"
|
||||||
show (EditPlayer _) = "EditPlayer"
|
show (CreateGoalie _) = "CreateGoalie"
|
||||||
show (EditGoalie _) = "EditGoalie"
|
show (EditPlayer _) = "EditPlayer"
|
||||||
|
show (EditGoalie _) = "EditGoalie"
|
||||||
|
show (EditStandings _) = "EditStandings"
|
||||||
|
|
||||||
-- | The game state
|
-- | The game state
|
||||||
data GameState = GameState
|
data GameState = GameState
|
||||||
@@ -387,6 +398,23 @@ data EditGoalieMode
|
|||||||
| EGLtTies
|
| EGLtTies
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
-- | Represents the standings edit mode
|
||||||
|
data EditStandingsMode
|
||||||
|
= ESMMenu
|
||||||
|
| ESMHome ESMSubMode
|
||||||
|
| ESMAway ESMSubMode
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
-- | Represents the standings edit sub-mode
|
||||||
|
data ESMSubMode
|
||||||
|
= ESMSubMenu
|
||||||
|
| ESMEditWins
|
||||||
|
| ESMEditLosses
|
||||||
|
| ESMEditOvertime
|
||||||
|
| ESMEditGoalsFor
|
||||||
|
| ESMEditGoalsAgainst
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
-- | Represents the database
|
-- | Represents the database
|
||||||
data Database = Database
|
data Database = Database
|
||||||
{ _dbPlayers :: [Player]
|
{ _dbPlayers :: [Player]
|
||||||
@@ -411,6 +439,8 @@ data Player = Player
|
|||||||
-- ^ The player's position
|
-- ^ The player's position
|
||||||
, _pRookie :: Bool
|
, _pRookie :: Bool
|
||||||
-- ^ Indicates that the player is a rookie
|
-- ^ Indicates that the player is a rookie
|
||||||
|
, _pActive :: Bool
|
||||||
|
-- ^ Indicates that the player is active
|
||||||
, _pYtd :: PlayerStats
|
, _pYtd :: PlayerStats
|
||||||
-- ^ The Player's year-to-date stats
|
-- ^ The Player's year-to-date stats
|
||||||
, _pLifetime :: PlayerStats
|
, _pLifetime :: PlayerStats
|
||||||
@@ -435,6 +465,8 @@ data Goalie = Goalie
|
|||||||
-- ^ The goalie's name
|
-- ^ The goalie's name
|
||||||
, _gRookie :: Bool
|
, _gRookie :: Bool
|
||||||
-- ^ Indicates that the goalie is a rookie
|
-- ^ Indicates that the goalie is a rookie
|
||||||
|
, _gActive :: Bool
|
||||||
|
-- ^ Indicates that the goalie is active
|
||||||
, _gYtd :: GoalieStats
|
, _gYtd :: GoalieStats
|
||||||
-- ^ The goalie's year-to-date stats
|
-- ^ The goalie's year-to-date stats
|
||||||
, _gLifetime :: GoalieStats
|
, _gLifetime :: GoalieStats
|
||||||
@@ -555,23 +587,26 @@ instance FromJSON Player where
|
|||||||
<*> v .: "name"
|
<*> v .: "name"
|
||||||
<*> v .: "position"
|
<*> v .: "position"
|
||||||
<*> v .:? "rookie" .!= False
|
<*> v .:? "rookie" .!= False
|
||||||
|
<*> v .:? "active" .!= True
|
||||||
<*> v .:? "ytd" .!= newPlayerStats
|
<*> v .:? "ytd" .!= newPlayerStats
|
||||||
<*> v .:? "lifetime" .!= newPlayerStats
|
<*> v .:? "lifetime" .!= newPlayerStats
|
||||||
|
|
||||||
instance ToJSON Player where
|
instance ToJSON Player where
|
||||||
toJSON (Player num name pos rk ytd lt) = object
|
toJSON (Player num name pos rk act ytd lt) = object
|
||||||
[ "number" .= num
|
[ "number" .= num
|
||||||
, "name" .= name
|
, "name" .= name
|
||||||
, "position" .= pos
|
, "position" .= pos
|
||||||
, "rookie" .= rk
|
, "rookie" .= rk
|
||||||
|
, "active" .= act
|
||||||
, "ytd" .= ytd
|
, "ytd" .= ytd
|
||||||
, "lifetime" .= lt
|
, "lifetime" .= lt
|
||||||
]
|
]
|
||||||
toEncoding (Player num name pos rk ytd lt) = pairs $
|
toEncoding (Player num name pos rk act ytd lt) = pairs $
|
||||||
"number" .= num <>
|
"number" .= num <>
|
||||||
"name" .= name <>
|
"name" .= name <>
|
||||||
"position" .= pos <>
|
"position" .= pos <>
|
||||||
"rookie" .= rk <>
|
"rookie" .= rk <>
|
||||||
|
"active" .= act <>
|
||||||
"ytd" .= ytd <>
|
"ytd" .= ytd <>
|
||||||
"lifetime" .= lt
|
"lifetime" .= lt
|
||||||
|
|
||||||
@@ -597,21 +632,24 @@ instance FromJSON Goalie where
|
|||||||
<$> v .: "number"
|
<$> v .: "number"
|
||||||
<*> v .: "name"
|
<*> v .: "name"
|
||||||
<*> v .:? "rookie" .!= False
|
<*> v .:? "rookie" .!= False
|
||||||
|
<*> v .:? "active" .!= True
|
||||||
<*> v .:? "ytd" .!= newGoalieStats
|
<*> v .:? "ytd" .!= newGoalieStats
|
||||||
<*> v .:? "lifetime" .!= newGoalieStats
|
<*> v .:? "lifetime" .!= newGoalieStats
|
||||||
|
|
||||||
instance ToJSON Goalie where
|
instance ToJSON Goalie where
|
||||||
toJSON (Goalie num name rk ytd lt) = object
|
toJSON (Goalie num name rk act ytd lt) = object
|
||||||
[ "number" .= num
|
[ "number" .= num
|
||||||
, "name" .= name
|
, "name" .= name
|
||||||
, "ytd" .= ytd
|
, "ytd" .= ytd
|
||||||
, "rookie" .= rk
|
, "rookie" .= rk
|
||||||
|
, "active" .= act
|
||||||
, "lifetime" .= lt
|
, "lifetime" .= lt
|
||||||
]
|
]
|
||||||
toEncoding (Goalie num name rk ytd lt) = pairs $
|
toEncoding (Goalie num name rk act ytd lt) = pairs $
|
||||||
"number" .= num <>
|
"number" .= num <>
|
||||||
"name" .= name <>
|
"name" .= name <>
|
||||||
"rookie" .= rk <>
|
"rookie" .= rk <>
|
||||||
|
"active" .= act <>
|
||||||
"ytd" .= ytd <>
|
"ytd" .= ytd <>
|
||||||
"lifetime" .= lt
|
"lifetime" .= lt
|
||||||
|
|
||||||
@@ -702,11 +740,29 @@ editGoalieStateL = lens
|
|||||||
_ -> newEditGoalieState)
|
_ -> newEditGoalieState)
|
||||||
(\_ egs -> EditGoalie egs)
|
(\_ egs -> EditGoalie egs)
|
||||||
|
|
||||||
|
editStandingsModeL :: Lens' ProgMode EditStandingsMode
|
||||||
|
editStandingsModeL = lens
|
||||||
|
(\case
|
||||||
|
EditStandings esm -> esm
|
||||||
|
_ -> ESMMenu)
|
||||||
|
(\_ esm -> EditStandings esm)
|
||||||
|
|
||||||
|
esmSubModeL :: Lens' EditStandingsMode ESMSubMode
|
||||||
|
esmSubModeL = lens
|
||||||
|
(\case
|
||||||
|
ESMMenu -> ESMSubMenu
|
||||||
|
ESMHome m -> m
|
||||||
|
ESMAway m -> m)
|
||||||
|
(\mode subMode -> case mode of
|
||||||
|
ESMMenu -> ESMMenu
|
||||||
|
ESMHome _ -> ESMHome subMode
|
||||||
|
ESMAway _ -> ESMAway subMode)
|
||||||
|
|
||||||
-- | Constructor for a 'ProgState'
|
-- | Constructor for a 'ProgState'
|
||||||
newProgState :: ProgState
|
newProgState :: ProgState
|
||||||
newProgState = ProgState
|
newProgState = ProgState
|
||||||
{ _database = newDatabase
|
{ _database = newDatabase
|
||||||
, _progMode = MainMenu
|
, _progMode = TitleScreen
|
||||||
, _inputBuffer = ""
|
, _inputBuffer = ""
|
||||||
, _scrollOffset = 0
|
, _scrollOffset = 0
|
||||||
}
|
}
|
||||||
@@ -795,6 +851,7 @@ newPlayer num name pos = Player
|
|||||||
, _pName = name
|
, _pName = name
|
||||||
, _pPosition = pos
|
, _pPosition = pos
|
||||||
, _pRookie = True
|
, _pRookie = True
|
||||||
|
, _pActive = True
|
||||||
, _pYtd = newPlayerStats
|
, _pYtd = newPlayerStats
|
||||||
, _pLifetime = newPlayerStats
|
, _pLifetime = newPlayerStats
|
||||||
}
|
}
|
||||||
@@ -818,6 +875,7 @@ newGoalie num name = Goalie
|
|||||||
{ _gNumber = num
|
{ _gNumber = num
|
||||||
, _gName = name
|
, _gName = name
|
||||||
, _gRookie = True
|
, _gRookie = True
|
||||||
|
, _gActive = True
|
||||||
, _gYtd = newGoalieStats
|
, _gYtd = newGoalieStats
|
||||||
, _gLifetime = newGoalieStats
|
, _gLifetime = newGoalieStats
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ module Mtlstats.Types.Menu (
|
|||||||
import Lens.Micro ((^.))
|
import Lens.Micro ((^.))
|
||||||
import Lens.Micro.TH (makeLenses)
|
import Lens.Micro.TH (makeLenses)
|
||||||
|
|
||||||
|
import Mtlstats.Format
|
||||||
import Mtlstats.Types
|
import Mtlstats.Types
|
||||||
|
|
||||||
-- | Defines a menu
|
-- | Defines a menu
|
||||||
@@ -65,8 +66,15 @@ makeLenses ''Menu
|
|||||||
makeLenses ''MenuItem
|
makeLenses ''MenuItem
|
||||||
|
|
||||||
instance Show (Menu a) where
|
instance Show (Menu a) where
|
||||||
show m = m ^. menuTitle ++ "\n" ++ items
|
show m = unlines
|
||||||
where items = unlines $ map show $ m ^. menuItems
|
$ [ m^.menuTitle
|
||||||
|
, ""
|
||||||
|
]
|
||||||
|
++ body
|
||||||
|
where
|
||||||
|
body = map (left width) items
|
||||||
|
width = maximum $ map length items
|
||||||
|
items = map show $ m^.menuItems
|
||||||
|
|
||||||
instance Show (MenuItem a) where
|
instance Show (MenuItem a) where
|
||||||
show i = [i ^. miKey] ++ ") " ++ i ^. miDescription
|
show i = [i ^. miKey] ++ ": " ++ i ^. miDescription
|
||||||
|
|||||||
83
test/Actions/EditStandingsSpec.hs
Normal file
83
test/Actions/EditStandingsSpec.hs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
{-
|
||||||
|
|
||||||
|
mtlstats
|
||||||
|
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||||
|
<rheal.lamothe@gmail.com>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
|
||||||
|
module Actions.EditStandingsSpec (spec) where
|
||||||
|
|
||||||
|
import Lens.Micro ((^.), (&), (.~))
|
||||||
|
import Test.Hspec
|
||||||
|
( Spec
|
||||||
|
, context
|
||||||
|
, describe
|
||||||
|
, it
|
||||||
|
, shouldBe
|
||||||
|
, shouldSatisfy
|
||||||
|
)
|
||||||
|
|
||||||
|
import Mtlstats.Actions.EditStandings
|
||||||
|
import Mtlstats.Types
|
||||||
|
|
||||||
|
spec :: Spec
|
||||||
|
spec = describe "EditStandings" $ do
|
||||||
|
mapM_
|
||||||
|
(\(label, f, expected) -> describe label $ do
|
||||||
|
let
|
||||||
|
ps = newProgState
|
||||||
|
ps' = f ps
|
||||||
|
|
||||||
|
it "should set progMode to EditStandings" $
|
||||||
|
ps'^.progMode `shouldSatisfy` \case
|
||||||
|
(EditStandings _) -> True
|
||||||
|
_ -> False
|
||||||
|
|
||||||
|
it ("should set editStandingsMode to " ++ show expected) $
|
||||||
|
ps'^.progMode.editStandingsModeL `shouldBe` expected)
|
||||||
|
|
||||||
|
-- label, function, expected mode
|
||||||
|
[ ( "editStandings", editStandings, ESMMenu )
|
||||||
|
, ( "editHomeStandings", editHomeStandings, ESMHome ESMSubMenu )
|
||||||
|
, ( "editAwayStandings", editAwayStandings, ESMAway ESMSubMenu )
|
||||||
|
]
|
||||||
|
|
||||||
|
mapM_
|
||||||
|
(\(label, f, expected) -> describe label $ do
|
||||||
|
mapM_
|
||||||
|
(\prefix -> context ("mode: " ++ show (prefix ESMSubMenu)) $ let
|
||||||
|
ps = newProgState & progMode.editStandingsModeL .~ prefix ESMSubMenu
|
||||||
|
ps' = f ps
|
||||||
|
in it ("should set the mode to " ++ show expected) $
|
||||||
|
ps'^.progMode.editStandingsModeL `shouldBe` prefix expected)
|
||||||
|
[ESMHome, ESMAway]
|
||||||
|
|
||||||
|
context "mode: ESMMenu" $ let
|
||||||
|
ps = newProgState & progMode.editStandingsModeL .~ ESMMenu
|
||||||
|
ps' = f ps
|
||||||
|
in it "should not change the mode" $
|
||||||
|
ps'^.progMode.editStandingsModeL `shouldBe` ESMMenu)
|
||||||
|
|
||||||
|
-- label, function, expected
|
||||||
|
[ ( "editWins", editWins, ESMEditWins )
|
||||||
|
, ( "editLosses", editLosses, ESMEditLosses )
|
||||||
|
, ( "editOvertime", editOvertime, ESMEditOvertime )
|
||||||
|
, ( "editGoalsFor", editGoalsFor, ESMEditGoalsFor )
|
||||||
|
, ( "editGoalsAgainst", editGoalsAgainst, ESMEditGoalsAgainst )
|
||||||
|
]
|
||||||
@@ -24,7 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
module ActionsSpec (spec) where
|
module ActionsSpec (spec) where
|
||||||
|
|
||||||
import Control.Monad (replicateM)
|
import Control.Monad (replicateM)
|
||||||
import Lens.Micro ((^.), (&), (.~), (?~))
|
import Lens.Micro ((^.), (&), (.~), (?~), (%~))
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
( Spec
|
( Spec
|
||||||
, context
|
, context
|
||||||
@@ -39,6 +39,7 @@ import Mtlstats.Actions
|
|||||||
import Mtlstats.Types
|
import Mtlstats.Types
|
||||||
|
|
||||||
import qualified Actions.NewGameSpec as NewGame
|
import qualified Actions.NewGameSpec as NewGame
|
||||||
|
import qualified Actions.EditStandingsSpec as EditStandings
|
||||||
import qualified TypesSpec as TS
|
import qualified TypesSpec as TS
|
||||||
|
|
||||||
spec :: Spec
|
spec :: Spec
|
||||||
@@ -46,6 +47,7 @@ spec = describe "Mtlstats.Actions" $ do
|
|||||||
startNewSeasonSpec
|
startNewSeasonSpec
|
||||||
startNewGameSpec
|
startNewGameSpec
|
||||||
resetYtdSpec
|
resetYtdSpec
|
||||||
|
clearRookiesSpec
|
||||||
resetStandingsSpec
|
resetStandingsSpec
|
||||||
addCharSpec
|
addCharSpec
|
||||||
removeCharSpec
|
removeCharSpec
|
||||||
@@ -64,6 +66,7 @@ spec = describe "Mtlstats.Actions" $ do
|
|||||||
scrollUpSpec
|
scrollUpSpec
|
||||||
scrollDownSpec
|
scrollDownSpec
|
||||||
NewGame.spec
|
NewGame.spec
|
||||||
|
EditStandings.spec
|
||||||
|
|
||||||
startNewSeasonSpec :: Spec
|
startNewSeasonSpec :: Spec
|
||||||
startNewSeasonSpec = describe "startNewSeason" $ do
|
startNewSeasonSpec = describe "startNewSeason" $ do
|
||||||
@@ -129,6 +132,45 @@ resetYtdSpec = describe "resetYtd" $
|
|||||||
lt ^. gsTies `shouldNotBe` 0) $
|
lt ^. gsTies `shouldNotBe` 0) $
|
||||||
s ^. database . dbGoalies
|
s ^. database . dbGoalies
|
||||||
|
|
||||||
|
clearRookiesSpec :: Spec
|
||||||
|
clearRookiesSpec = describe "clearRookies" $ do
|
||||||
|
let
|
||||||
|
|
||||||
|
players =
|
||||||
|
[ newPlayer 1 "Joe" "centre" & pRookie .~ True
|
||||||
|
, newPlayer 2 "Bob" "centre" & pRookie .~ False
|
||||||
|
]
|
||||||
|
|
||||||
|
goalies =
|
||||||
|
[ newGoalie 3 "Bill" & gRookie .~ True
|
||||||
|
, newGoalie 4 "Doug" & gRookie .~ False
|
||||||
|
]
|
||||||
|
|
||||||
|
ps = newProgState
|
||||||
|
& database
|
||||||
|
%~ (dbPlayers .~ players)
|
||||||
|
. (dbGoalies .~ goalies)
|
||||||
|
|
||||||
|
ps' = clearRookies ps
|
||||||
|
|
||||||
|
context "Players" $ mapM_
|
||||||
|
(\p -> let
|
||||||
|
name = p^.pName
|
||||||
|
rFlag = p^.pRookie
|
||||||
|
in context name $
|
||||||
|
it "should not be a rookie" $
|
||||||
|
rFlag `shouldBe` False)
|
||||||
|
(ps'^.database.dbPlayers)
|
||||||
|
|
||||||
|
context "Goalies" $ mapM_
|
||||||
|
(\g -> let
|
||||||
|
name = g^.gName
|
||||||
|
rFlag = g^.gRookie
|
||||||
|
in context name $
|
||||||
|
it "should not be a rookie" $
|
||||||
|
rFlag `shouldBe` False)
|
||||||
|
(ps'^.database.dbGoalies)
|
||||||
|
|
||||||
resetStandingsSpec :: Spec
|
resetStandingsSpec :: Spec
|
||||||
resetStandingsSpec = describe "resetStandings" $ do
|
resetStandingsSpec = describe "resetStandings" $ do
|
||||||
let
|
let
|
||||||
|
|||||||
@@ -76,10 +76,16 @@ goalieNameSpec = describe "goalieName" $ mapM_
|
|||||||
it ("should be " ++ expected) $
|
it ("should be " ++ expected) $
|
||||||
goalieName g `shouldBe` expected)
|
goalieName g `shouldBe` expected)
|
||||||
|
|
||||||
-- label, goalie, expected
|
-- label, goalie, expected
|
||||||
[ ( "rookie", goalie True, "foo*" )
|
[ ( "rookie", rookie, "foo*" )
|
||||||
, ( "non-rookie", goalie False, "foo" )
|
, ( "non-rookie", active, "foo" )
|
||||||
|
, ( "retired", retired, "*foo" )
|
||||||
]
|
]
|
||||||
|
|
||||||
where
|
where
|
||||||
goalie r = newGoalie 1 "foo" & gRookie .~ r
|
rookie = goalie True True
|
||||||
|
active = goalie False True
|
||||||
|
retired = goalie False False
|
||||||
|
goalie r a = newGoalie 1 "foo"
|
||||||
|
& gRookie .~ r
|
||||||
|
& gActive .~ a
|
||||||
|
|||||||
@@ -71,9 +71,13 @@ playerNameSpec = describe "playerName" $ mapM_
|
|||||||
-- label, player, expected
|
-- label, player, expected
|
||||||
[ ( "rookie", rookie, "foo*" )
|
[ ( "rookie", rookie, "foo*" )
|
||||||
, ( "non-rookie", nonRookie, "foo" )
|
, ( "non-rookie", nonRookie, "foo" )
|
||||||
|
, ( "retired", retired, "*foo" )
|
||||||
]
|
]
|
||||||
|
|
||||||
where
|
where
|
||||||
rookie = player True
|
rookie = player True True
|
||||||
nonRookie = player False
|
nonRookie = player False True
|
||||||
player r = newPlayer 1 "foo" "centre" & pRookie .~ r
|
retired = player False False
|
||||||
|
player r a = newPlayer 1 "foo" "centre"
|
||||||
|
& pRookie .~ r
|
||||||
|
& pActive .~ a
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ showSpec :: Spec
|
|||||||
showSpec = describe "show" $
|
showSpec = describe "show" $
|
||||||
it "should display correctly" $ let
|
it "should display correctly" $ let
|
||||||
menu = Menu "Foo" ()
|
menu = Menu "Foo" ()
|
||||||
[ MenuItem '1' "Item 1" $ return ()
|
[ MenuItem '1' "foo" $ return ()
|
||||||
, MenuItem '2' "Item 2" $ return ()
|
, MenuItem '2' "bar baz" $ return ()
|
||||||
]
|
]
|
||||||
expected =
|
expected =
|
||||||
"Foo\n\
|
"Foo\n\n\
|
||||||
\1) Item 1\n\
|
\1: foo \n\
|
||||||
\2) Item 2\n"
|
\2: bar baz\n"
|
||||||
in show menu `shouldBe` expected
|
in show menu `shouldBe` expected
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ spec = describe "Mtlstats.Types" $ do
|
|||||||
createGoalieStateLSpec
|
createGoalieStateLSpec
|
||||||
editPlayerStateLSpec
|
editPlayerStateLSpec
|
||||||
editGoalieStateLSpec
|
editGoalieStateLSpec
|
||||||
|
editStandingsModeLSpec
|
||||||
|
esmSubModeLSpec
|
||||||
teamScoreSpec
|
teamScoreSpec
|
||||||
otherScoreSpec
|
otherScoreSpec
|
||||||
homeTeamSpec
|
homeTeamSpec
|
||||||
@@ -191,6 +193,47 @@ editGoalieStateLSpec = describe "editGoalieStateL" $
|
|||||||
egs2 = newEditGoalieState
|
egs2 = newEditGoalieState
|
||||||
& egsSelectedGoalie ?~ 2
|
& egsSelectedGoalie ?~ 2
|
||||||
|
|
||||||
|
editStandingsModeLSpec :: Spec
|
||||||
|
editStandingsModeLSpec = describe "editStandingsModeL" $
|
||||||
|
lensSpec editStandingsModeL
|
||||||
|
-- getters
|
||||||
|
[ ( "missing mode", MainMenu, menu )
|
||||||
|
, ( "with mode", EditStandings home, home )
|
||||||
|
]
|
||||||
|
-- setters
|
||||||
|
[ ( "set mode", MainMenu, home )
|
||||||
|
, ( "change mode", EditStandings home, away )
|
||||||
|
]
|
||||||
|
where
|
||||||
|
menu = ESMMenu
|
||||||
|
home = ESMHome ESMSubMenu
|
||||||
|
away = ESMAway ESMSubMenu
|
||||||
|
|
||||||
|
esmSubModeLSpec :: Spec
|
||||||
|
esmSubModeLSpec = describe "esmSubModeL" $ do
|
||||||
|
|
||||||
|
context "getters" $ mapM_
|
||||||
|
(\(label, mode, expected) -> context label $
|
||||||
|
it ("should be " ++ show expected) $
|
||||||
|
mode^.esmSubModeL `shouldBe` expected)
|
||||||
|
|
||||||
|
-- label, mode, expected
|
||||||
|
[ ( "no state", ESMMenu, ESMSubMenu )
|
||||||
|
, ( "with state", ESMHome ESMEditWins, ESMEditWins )
|
||||||
|
]
|
||||||
|
|
||||||
|
context "setters" $ mapM_
|
||||||
|
(\(label, mode, expected) -> context label $
|
||||||
|
it ("should be " ++ show expected) $ let
|
||||||
|
mode' = mode & esmSubModeL .~ ESMEditWins
|
||||||
|
in mode' `shouldBe` expected)
|
||||||
|
|
||||||
|
-- label, mode, expected
|
||||||
|
[ ( "no state", ESMMenu, ESMMenu )
|
||||||
|
, ( "home mode", ESMHome ESMSubMenu, ESMHome ESMEditWins )
|
||||||
|
, ( "away mode", ESMAway ESMSubMenu, ESMAway ESMEditWins )
|
||||||
|
]
|
||||||
|
|
||||||
teamScoreSpec :: Spec
|
teamScoreSpec :: Spec
|
||||||
teamScoreSpec = describe "teamScore" $ do
|
teamScoreSpec = describe "teamScore" $ do
|
||||||
let
|
let
|
||||||
@@ -281,6 +324,7 @@ playerJSON = Object $ HM.fromList
|
|||||||
, ( "name", toJSON ("Joe" :: String) )
|
, ( "name", toJSON ("Joe" :: String) )
|
||||||
, ( "position", toJSON ("centre" :: String) )
|
, ( "position", toJSON ("centre" :: String) )
|
||||||
, ( "rookie", toJSON False )
|
, ( "rookie", toJSON False )
|
||||||
|
, ( "active", toJSON True )
|
||||||
, ( "ytd", playerStatsJSON 1 )
|
, ( "ytd", playerStatsJSON 1 )
|
||||||
, ( "lifetime", playerStatsJSON 2 )
|
, ( "lifetime", playerStatsJSON 2 )
|
||||||
]
|
]
|
||||||
@@ -309,6 +353,7 @@ goalieJSON = Object $ HM.fromList
|
|||||||
[ ( "number", toJSON (1 :: Int) )
|
[ ( "number", toJSON (1 :: Int) )
|
||||||
, ( "name", toJSON ("Joe" :: String ) )
|
, ( "name", toJSON ("Joe" :: String ) )
|
||||||
, ( "rookie", toJSON False )
|
, ( "rookie", toJSON False )
|
||||||
|
, ( "active", toJSON True )
|
||||||
, ( "ytd", goalieStatsJSON 1 )
|
, ( "ytd", goalieStatsJSON 1 )
|
||||||
, ( "lifetime", goalieStatsJSON 2 )
|
, ( "lifetime", goalieStatsJSON 2 )
|
||||||
]
|
]
|
||||||
@@ -848,6 +893,7 @@ makePlayer = Player
|
|||||||
<*> makeName
|
<*> makeName
|
||||||
<*> makeName
|
<*> makeName
|
||||||
<*> makeBool
|
<*> makeBool
|
||||||
|
<*> makeBool
|
||||||
<*> makePlayerStats
|
<*> makePlayerStats
|
||||||
<*> makePlayerStats
|
<*> makePlayerStats
|
||||||
|
|
||||||
@@ -857,6 +903,7 @@ makeGoalie = Goalie
|
|||||||
<$> makeNum
|
<$> makeNum
|
||||||
<*> makeName
|
<*> makeName
|
||||||
<*> makeBool
|
<*> makeBool
|
||||||
|
<*> makeBool
|
||||||
<*> makeGoalieStats
|
<*> makeGoalieStats
|
||||||
<*> makeGoalieStats
|
<*> makeGoalieStats
|
||||||
|
|
||||||
@@ -953,3 +1000,8 @@ instance Comparable CreateGoalieState where
|
|||||||
describe "cgsName" $
|
describe "cgsName" $
|
||||||
it ("should be " ++ expected^.cgsName) $
|
it ("should be " ++ expected^.cgsName) $
|
||||||
actual^.cgsName `shouldBe` expected^.cgsName
|
actual^.cgsName `shouldBe` expected^.cgsName
|
||||||
|
|
||||||
|
instance Comparable EditStandingsMode where
|
||||||
|
compareTest actual expected =
|
||||||
|
it ("should be " ++ show expected) $
|
||||||
|
actual `shouldBe` expected
|
||||||
|
|||||||
Reference in New Issue
Block a user