diff options
author | Andrew Cady <d@jerkface.net> | 2022-10-24 20:34:28 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2022-10-24 20:34:28 -0400 |
commit | 895c117b266fd59440da6b6a8c340d64289b9ed1 (patch) | |
tree | 2efe6eef8cf95bb268d00fe2127a6f30787c0548 | |
parent | faed266557e4a91a1b21dbb6ca980103fcbbb02a (diff) |
better support for cycling through routines
-rw-r--r-- | package.yaml | 1 | ||||
-rwxr-xr-x | repgoal.hs | 35 |
2 files changed, 26 insertions, 10 deletions
diff --git a/package.yaml b/package.yaml index 441c46e..70a66fd 100644 --- a/package.yaml +++ b/package.yaml | |||
@@ -15,6 +15,7 @@ dependencies: | |||
15 | - text | 15 | - text |
16 | - generic-data | 16 | - generic-data |
17 | - pretty-simple | 17 | - pretty-simple |
18 | - nonempty-containers | ||
18 | 19 | ||
19 | executables: | 20 | executables: |
20 | repgoal: | 21 | repgoal: |
@@ -18,8 +18,10 @@ | |||
18 | import Rebase.Prelude hiding (toList, on, (<+>), Max) | 18 | import Rebase.Prelude hiding (toList, on, (<+>), Max) |
19 | import qualified Rebase.Prelude as Prelude | 19 | import qualified Rebase.Prelude as Prelude |
20 | import qualified Data.Set as Set | 20 | import qualified Data.Set as Set |
21 | import qualified Data.List.NonEmpty as NonEmpty | 21 | import qualified Data.Sequence as Seq |
22 | import Data.List.NonEmpty (NonEmpty) | 22 | import qualified Data.Sequence.NonEmpty as NESeq |
23 | import Data.Sequence (Seq(..)) | ||
24 | import Data.Sequence.NonEmpty (NESeq(..)) | ||
23 | import Control.Lens hiding ((<|)) | 25 | import Control.Lens hiding ((<|)) |
24 | import Data.Foldable (toList) | 26 | import Data.Foldable (toList) |
25 | import Data.Ratio | 27 | import Data.Ratio |
@@ -132,7 +134,8 @@ data WeekSelection = Week1 | Week2 | Week3 deriving (Enum, Bounded, Show, Eq) | |||
132 | data St = St { | 134 | data St = St { |
133 | _lifts :: [LiftRecord], | 135 | _lifts :: [LiftRecord], |
134 | _week :: WeekSelection, | 136 | _week :: WeekSelection, |
135 | _routines :: NonEmpty (Set Text) | 137 | _routines :: NESeq (Set Text), |
138 | _selectedRoutine :: Int | ||
136 | } | 139 | } |
137 | makeLenses ''St | 140 | makeLenses ''St |
138 | 141 | ||
@@ -166,10 +169,12 @@ annotatePosition :: [a] -> [(ListPosition, a)] | |||
166 | annotatePosition [] = undefined | 169 | annotatePosition [] = undefined |
167 | annotatePosition (x:xs) = (FirstInList, x) : map (NotFirstInList,) xs | 170 | annotatePosition (x:xs) = (FirstInList, x) : map (NotFirstInList,) xs |
168 | 171 | ||
172 | lookup' i seq = fromJust $ NESeq.lookup (i `mod` NESeq.length seq) seq | ||
173 | |||
169 | drawUI :: St -> [Widget ()] | 174 | drawUI :: St -> [Widget ()] |
170 | drawUI st = [vCenter $ vBox [hCenter oneRepMaxTable, header, withVScrollBarHandles $ withVScrollBars OnRight $ viewport () Vertical $ hCenter lastSetTable]] | 175 | drawUI st = [vCenter $ vBox [hCenter oneRepMaxTable, header, withVScrollBarHandles $ withVScrollBars OnRight $ viewport () Vertical $ hCenter lastSetTable]] |
171 | where | 176 | where |
172 | lifts' = filter ((flip Set.member $ view routines st & NonEmpty.head) . liftName) (view lifts st) | 177 | lifts' = filter ((flip Set.member $ view routines st & lookup' (view selectedRoutine st)) . liftName) (view lifts st) |
173 | lastSetTable = renderTable $ table $ map (padLeftRight 1 . str) ["Lift", "Set", "Goal", "Done", "Rest"] : concatMap (toLiftRows (view week st)) lifts' | 178 | lastSetTable = renderTable $ table $ map (padLeftRight 1 . str) ["Lift", "Set", "Goal", "Done", "Rest"] : concatMap (toLiftRows (view week st)) lifts' |
174 | header = str $ "Week " ++ case (view week st) of Week1 -> "1"; Week2 -> "2"; Week3 -> "3" | 179 | header = str $ "Week " ++ case (view week st) of Week1 -> "1"; Week2 -> "2"; Week3 -> "3" |
175 | oneRepMaxTable = renderTable $ table $ map (padLeftRight 1 . str) ["Lift", "Achieved Best", "Computed 1RM"] : map toRow lifts' | 180 | oneRepMaxTable = renderTable $ table $ map (padLeftRight 1 . str) ["Lift", "Achieved Best", "Computed 1RM"] : map toRow lifts' |
@@ -210,13 +215,22 @@ succ' :: (Enum a, Bounded a, Eq a) => a -> a | |||
210 | succ' x | x == maxBound = minBound | 215 | succ' x | x == maxBound = minBound |
211 | succ' x = succ x | 216 | succ' x = succ x |
212 | 217 | ||
218 | clipSelectedRoutine :: St -> St | ||
219 | clipSelectedRoutine st = st & selectedRoutine %~ maybeReset | ||
220 | where | ||
221 | len = view (routines . to NESeq.length) st | ||
222 | maybeReset n | n < 0 = len | ||
223 | maybeReset n | n < len = n | ||
224 | maybeReset _ | otherwise = 0 | ||
225 | |||
213 | handleEvent :: St -> BrickEvent () CustomEvent -> EventM () (Next St) | 226 | handleEvent :: St -> BrickEvent () CustomEvent -> EventM () (Next St) |
214 | handleEvent st e = case e of | 227 | handleEvent st e = case e of |
215 | VtyEvent (V.EvKey V.KEsc []) -> halt st | 228 | VtyEvent (V.EvKey V.KEsc []) -> halt st |
216 | VtyEvent (V.EvKey V.KDown _) -> M.vScrollBy (M.viewportScroll ()) 5 >> continue st | 229 | VtyEvent (V.EvKey V.KDown _) -> M.vScrollBy (M.viewportScroll ()) 5 >> continue st |
217 | VtyEvent (V.EvKey V.KUp _) -> M.vScrollBy (M.viewportScroll ()) (-5) >> continue st | 230 | VtyEvent (V.EvKey V.KUp _) -> M.vScrollBy (M.viewportScroll ()) (-5) >> continue st |
218 | VtyEvent (V.EvKey (V.KChar 'w') _) -> continue $ st & week %~ succ' | 231 | VtyEvent (V.EvKey (V.KChar 'w') _) -> continue $ st & week %~ succ' |
219 | VtyEvent (V.EvKey (V.KChar 'n') _) -> continue $ st & routines %~ (NonEmpty.fromList . NonEmpty.tail) | 232 | VtyEvent (V.EvKey (V.KChar 'n') _) -> continue $ st & selectedRoutine %~ (+1) & clipSelectedRoutine |
233 | VtyEvent (V.EvKey (V.KChar 'p') _) -> continue $ st & selectedRoutine %~ (subtract 1) & clipSelectedRoutine | ||
220 | VtyEvent _ -> continue st | 234 | VtyEvent _ -> continue st |
221 | AppEvent _ -> continue st | 235 | AppEvent _ -> continue st |
222 | _ -> continue st | 236 | _ -> continue st |
@@ -249,10 +263,11 @@ powerClean = clean * 80 / 100 | |||
249 | pushPress = press * 100 / 75 | 263 | pushPress = press * 100 / 75 |
250 | jerk = pushPress / 100 * 85 | 264 | jerk = pushPress / 100 * 85 |
251 | 265 | ||
252 | routine :: NonEmpty (Set Text) | 266 | routine :: NESeq (Set Text) |
253 | routine = NonEmpty.cycle $ | 267 | routine = |
254 | Set.fromList ["Deadlift", "Press"] :| | 268 | Set.fromList ["Deadlift", "Press"] :<|| |
255 | [Set.fromList ["Front Squat"] | 269 | Seq.fromList |
270 | [ Set.fromList ["Front Squat"] | ||
256 | , Set.fromList ["Left-Arm Snatch", "Right-Arm Snatch"] | 271 | , Set.fromList ["Left-Arm Snatch", "Right-Arm Snatch"] |
257 | , Set.fromList ["Squat", "Bench"] | 272 | , Set.fromList ["Squat", "Bench"] |
258 | , Set.fromList ["Push Press", "Power Clean"] | 273 | , Set.fromList ["Push Press", "Power Clean"] |
@@ -266,4 +281,4 @@ main = do | |||
266 | -- liftIO $ setMode (outputIface vty) Mouse True | 281 | -- liftIO $ setMode (outputIface vty) Mouse True |
267 | chan <- newBChan 10 | 282 | chan <- newBChan 10 |
268 | initial <- read <$> readFile "lifts.dat" :: IO [LiftRecord] | 283 | initial <- read <$> readFile "lifts.dat" :: IO [LiftRecord] |
269 | void $ customMain vty buildVty (Just chan) (theApp) (St initial Week1 routine) | 284 | void $ customMain vty buildVty (Just chan) (theApp) (St initial Week1 routine 0) |