playball 2.2.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.eslintrc.json +2 -2
  2. package/README.md +80 -4
  3. package/bin/playball.js +1 -1
  4. package/demo.cast +95 -0
  5. package/demo.gif +0 -0
  6. package/package.json +50 -28
  7. package/src/cli.js +46 -0
  8. package/src/components/AllPlays.jsx +97 -64
  9. package/src/components/App.jsx +40 -68
  10. package/src/components/AtBat.jsx +34 -36
  11. package/src/components/Bases.jsx +9 -13
  12. package/src/components/Count.jsx +11 -15
  13. package/src/components/FinishedGame.jsx +30 -41
  14. package/src/components/Game.jsx +54 -71
  15. package/src/components/GameList.jsx +129 -82
  16. package/src/components/Grid.jsx +91 -0
  17. package/src/components/HelpBar.jsx +15 -10
  18. package/src/components/InningDisplay.jsx +19 -0
  19. package/src/components/LineScore.jsx +27 -33
  20. package/src/components/LiveGame.jsx +13 -9
  21. package/src/components/LoadingSpinner.jsx +26 -60
  22. package/src/components/Matchup.jsx +26 -39
  23. package/src/components/PreviewGame.jsx +22 -37
  24. package/src/components/Standings.jsx +81 -0
  25. package/src/config.js +167 -0
  26. package/src/features/games.js +166 -0
  27. package/src/features/keys.js +39 -0
  28. package/src/features/schedule.js +60 -0
  29. package/src/features/standings.js +61 -0
  30. package/src/hooks/useKey.js +13 -0
  31. package/src/logger.js +4 -1
  32. package/src/main.js +20 -23
  33. package/src/package.js +7 -0
  34. package/src/screen.js +22 -0
  35. package/src/store/index.js +17 -7
  36. package/src/style/index.js +1 -1
  37. package/src/utils.js +10 -0
  38. package/dist/actions/game.js +0 -36
  39. package/dist/actions/schedule.js +0 -33
  40. package/dist/actions/types.js +0 -16
  41. package/dist/components/AllPlays.js +0 -132
  42. package/dist/components/App.js +0 -140
  43. package/dist/components/AtBat.js +0 -66
  44. package/dist/components/Bases.js +0 -47
  45. package/dist/components/Count.js +0 -47
  46. package/dist/components/FinishedGame.js +0 -139
  47. package/dist/components/Game.js +0 -145
  48. package/dist/components/GameList.js +0 -196
  49. package/dist/components/HelpBar.js +0 -23
  50. package/dist/components/LineScore.js +0 -118
  51. package/dist/components/LiveGame.js +0 -65
  52. package/dist/components/LoadingSpinner.js +0 -146
  53. package/dist/components/Matchup.js +0 -79
  54. package/dist/components/PreviewGame.js +0 -97
  55. package/dist/logger.js +0 -24
  56. package/dist/main.js +0 -38
  57. package/dist/reducers/game.js +0 -70
  58. package/dist/reducers/index.js +0 -21
  59. package/dist/reducers/schedule.js +0 -35
  60. package/dist/selectors/game.js +0 -82
  61. package/dist/selectors/schedule.js +0 -25
  62. package/dist/store/index.js +0 -18
  63. package/dist/style/index.js +0 -22
  64. package/src/actions/game.js +0 -25
  65. package/src/actions/schedule.js +0 -21
  66. package/src/actions/types.js +0 -5
  67. package/src/reducers/game.js +0 -56
  68. package/src/reducers/index.js +0 -9
  69. package/src/reducers/schedule.js +0 -28
  70. package/src/selectors/game.js +0 -93
  71. package/src/selectors/schedule.js +0 -18
package/.eslintrc.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "ecmaFeatures": {
12
12
  "jsx": true
13
13
  },
14
- "ecmaVersion": 2018,
14
+ "ecmaVersion": 2022,
15
15
  "sourceType": "module"
16
16
  },
17
17
  "plugins": [
@@ -27,7 +27,7 @@
27
27
  "settings": {
28
28
  "react": {
29
29
  "pragma": "React",
30
- "version": "16.5.0"
30
+ "version": "17.0.2"
31
31
  }
32
32
  }
33
33
  }
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ## Playball!
2
2
  Watch MLB games from the comfort of your own terminal
3
3
 
4
- ![screenshot](https://i.imgur.com/SdA4fWR.gif)
4
+ ![screenshot](./demo.gif)
5
5
 
6
6
  ### Why?
7
7
  [MLB Gameday](http://www.mlb.com/mlb/gameday/#) and [MLB.tv](http://mlb.tv) are
@@ -25,12 +25,88 @@ $ playball
25
25
  ```
26
26
 
27
27
  ### Keys
28
+ #### Global
28
29
  key | action
29
30
  ----|--------
30
31
  <kbd>q</kbd> | quit
31
- <kbd>&darr;</kbd> / <kbd>j</kbd>, <kbd>&uarr;</kbd> / <kbd>k</kbd> | change highlighted game in list; scroll list of plays in game
32
- <kbd>enter</kbd> | view highlighted game in list
33
- <kbd>l</kbd> | return to list of games
32
+ <kbd>c</kbd> | go to schedule view
33
+ <kbd>s</kbd> | go to standings view
34
+
35
+ #### Schedule View
36
+ key | action
37
+ ----|--------
38
+ <kbd>&darr;</kbd>/<kbd>j</kbd>, <kbd>&uarr;</kbd>/<kbd>k</kbd>, <kbd>&larr;</kbd>/<kbd>h</kbd>, <kbd>&rarr;</kbd>/<kbd>l</kbd> | change highlighted game
39
+ <kbd>enter</kbd> | view highlighted game
40
+ <kbd>p</kbd> | show previous day's schedule/results
41
+ <kbd>n</kbd> | show next day's schedule
42
+ <kbd>t</kbd> | return to today's schedule
43
+
44
+ #### Game View
45
+ key | action
46
+ ----|--------
47
+ <kbd>&darr;</kbd>/<kbd>j</kbd>, <kbd>&uarr;</kbd>/<kbd>k</kbd> | scroll list of all plays
48
+
49
+ ### Configuration
50
+
51
+ Playball can be configured using the `config` subcommand. To list the current configuration values run the subcommand with no additional arguments:
52
+
53
+ ```shell
54
+ playball config
55
+ ```
56
+
57
+ You should see output similar to:
58
+
59
+ ```
60
+ color.ball = green
61
+ color.favorite-star = yellow
62
+ color.in-play-no-out = blue
63
+ color.in-play-out = white
64
+ color.in-play-runs-bg = white
65
+ color.in-play-runs-fg = black
66
+ color.on-base = yellow
67
+ color.other-event = white
68
+ color.out = red
69
+ color.strike = red
70
+ color.strike-out = red
71
+ color.walk = green
72
+ favorites =
73
+ ```
74
+
75
+ To get the value of a single setting pass the key as an additional argument:
76
+
77
+ ```shell
78
+ playball config color.strike
79
+ ```
80
+
81
+ To change a setting pass the key and value as arguments:
82
+
83
+ ```shell
84
+ playball config color.strike blue
85
+ ```
86
+
87
+ To revert a setting to its default value provide the key and the `--unset` flag:
88
+
89
+ ```shell
90
+ playball config color.strike --unset
91
+ ```
92
+
93
+ This table summarizes the available settings:
94
+
95
+ key | description | default | allowed values
96
+ ----|-------------|---------|---------------
97
+ `color.ball` | Color of dots representing balls in top row of game view | green | One of the following: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `grey`. Any of those colors may be prefixed by `bright-` or `light-` (for example `bright-green`). The exact color used will depend on your terminal settings. The value `default` may be used to specify the default text color for your terminal. Finally hex colors (e.g `#FFA500`) can be specified. If your terminal does not support true color, the closest supported color may be used.
98
+ `color.favorite-star` | Color of star indiciating favorite team in schedule and standing views | yellow | _See above_
99
+ `color.in-play-no-out` | Color of result where ball was put in play and no out was made (single, double, etc) in list of plays in game view | blue | _See above_
100
+ `color.in-play-out` | Color of result where ball was put in play and an out was made (flyout, fielder's choice, etc) in list of plays in game view | white | _See above_
101
+ `color.in-play-runs-bg` | Background color for score update in list of plays in game view | white | _See above_
102
+ `color.in-play-runs-fg` | Foreground color for score update in list of plays in game view | black | _See above_
103
+ `color.on-base` | Color of diamonds representing runners on base in top row of game view | yellow | _See above_
104
+ `color.other-event` | Color of other events (mound visit, injury delay, etc) in list of plays in game view | white | _See above_
105
+ `color.out` | Color of dots representing outs in top row of game view | red | _See above_
106
+ `color.strike` | Color of dots representing strikes in top row of game view | red | _See above_
107
+ `color.strike-out` | Color of result where play ends on a strike (strike out) in list of plays in game view | red | _See above_
108
+ `color.walk` | Color of result where play ends on a ball (walk, hit by pitch) in list of plays in game view | green | _See above_
109
+ `favorites` | Teams to highlight in schedule and standings views | | Any one of the following: `ATL`, `AZ`, `BAL`, `BOS`, `CHC`, `CIN`, `CLE`, `COL`, `CWS`, `DET`, `HOU`, `KC`, `LAA`, `LAD`, `MIA`, `MIL`, `MIN`, `NYM`, `NYY`, `OAK`, `PHI`, `PIT`, `SD`, `SEA`, `SF`, `STL`, `TB`, `TEX`, `TOR`, `WSH`. Or a comma-separated list of multiple (e.g. `SEA,MIL`)
34
110
 
35
111
  ### Development
36
112
  ```
package/bin/playball.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- require('..');
2
+ import '../dist/cli.js';
package/demo.cast ADDED
@@ -0,0 +1,95 @@
1
+ {"version": 2, "width": 118, "height": 36, "timestamp": 1654987630, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
2
+ [0.159133, "o", "$ "]
3
+ [1.331166, "o", "p"]
4
+ [1.412778, "o", "l"]
5
+ [1.564842, "o", "a"]
6
+ [1.772299, "o", "y"]
7
+ [2.035449, "o", "b"]
8
+ [2.160659, "o", "a"]
9
+ [2.261186, "o", "l"]
10
+ [2.413437, "o", "l"]
11
+ [2.627466, "o", "\r\n"]
12
+ [3.043377, "o", "\u001b]0;Playball!\u0007\u001b[?1049h\u001b[?1h\u001b=\u001b[1;36r\u001b[?25l\u001b[1;1H\u001b[H\u001b[2J\u001b[?1002h\u001b[?1003h\u001b[?1006h"]
13
+ [3.068237, "o", "\u001b7\u001b[1;1H\u001b[47;30m Saturday, June 11th, 2022 \u001b[m\u001b[19;1H\u001b[54CLoading...\u001b[36;1H\u001b[36;1H⠙\u001b[2C\u001b[7mQ\u001b[m:Quit\u001b[2C\u001b[7mC\u001b[m:Schedule\u001b[2C\u001b[7mS\u001b[m:Standings\u001b[2C\u001b[7mP\u001b[m:Prev\u001b[1CDay\u001b[2C\u001b[7mN\u001b[m:Next\u001b[1CDay\u001b[2C\u001b[7mT\u001b[m:Today\u001b8"]
14
+ [3.117385, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠹\u001b8"]
15
+ [3.167954, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠸\u001b8"]
16
+ [3.215288, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠼\u001b8"]
17
+ [3.297623, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠴\u001b8"]
18
+ [3.31866, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠦\u001b8"]
19
+ [3.40441, "o", "\u001b7\u001b[3;1H\u001b[3;1H\u001b(0lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk\u001b[4;1H\u001b[4;1Hx\u001b[1C\u001b(BTop\u001b[1C9th\u001b[14CH\u001b[2CR\u001b[2CE\u001b[8C\u001b(0x\u001b[2C\u001b(BTop\u001b[1C9th\u001b[14CH\u001b[2CR\u001b[2CE\u001b[11CBottom\u001b[1C8th\u001b[11CH\u001b[2CR\u001b[2CE\u001b[5;1H\u001b[5;1H\u001b(0x\u001b[1C\u001b(BRockies\u001b[1C(25-33)\u001b[6C1\u001b[2C8\u001b[2C0\u001b[8C\u001b(0x\u001b[2C\u001b(BPirates\u001b[1C(24-32)\u001b[6C4\u001b[2C6\u001b[2C2\u001b[11CD-backs\u001b[1C(28-32)\u001b[6C0\u001b[2C4\u001b[2C1\u001b[6;1H\u001b[6;1H\u001b(0x\u001b[1C\u001b(BPadres\u001b[1C(36-22)\u001b[7C1\u001b[2C3\u001b[2C0\u001b[8C\u001b(0x\u001b[2C\u001b(BBraves\u001b[1C(32-27)\u001b[6C10\u001b[2C8\u001b[2C0\u001b[11CPhillies\u001b[1C(29-29)\u001b[5C4\u001b[2C9\u001b[2C0\u001b[7;1H\u001b[7;1H\u001b(0mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj\u001b[9;1H\u001b[9;3H\u001b(BTop\u001b[1C8th\u001b[14CH\u001b[2CR\u001b[2CE\u001b[11CBottom\u001b[1C8th\u001b[11CH\u001b[2CR\u001b[2CE\u001b[11CTop\u001b[1C8th\u001b[14CH\u001b[2CR\u001b[2CE\u001b[10;1H\u001b[10;3HBrewers\u001b[1C(33-27)\u001b[6C4\u001b[2C9\u001b[2C1\u001b[11COrioles\u001b[1C(24-35)\u001b[6C6\u001b[1C10\u001b[2C0\u001b[11CAthletics\u001b[1C(20-40)\u001b[4C8\u001b[1C11\u001b[2C1\u001b[11;1H\u001b[11;3HNationals\u001b[1C(22-38)\u001b[4C8\u001b[2C9\u001b[2C1\u001b[11CRoyals\u001b[1C(20-37)\u001b[7C3\u001b[2C6\u001b[2C1\u001b[11CGuardians\u001b[1C(28-26)\u001b[4C5\u001b[2C8\u001b[2C1\u001b[14;1H\u001b[14;3HBottom\u001b[1C8th\u001b[11CH\u001b[2CR\u001b[2CE\u001b[11CTop\u001b[1C8th\u001b[14CH\u001b[2CR\u001b[2CE\u001b[11C7:10\u001b[1CPM\u001b[15;1H\u001b[15;3HBlue\u001b[1CJays\u001b[1C(34-23)\u001b[4C0\u001b[2C7\u001b[2C1\u001b[11CMarl"]
20
+ [3.404479, "o", "ins\u001b[1C(26-30)\u001b[6C4\u001b[2C4\u001b[2C2\u001b[11CRockies\u001b[1C(25-33)\u001b[16;1H\u001b[16;3HTigers\u001b[1C(23-34)\u001b[7C3\u001b[2C8\u001b[2C1\u001b[11CAstros\u001b[1C(36-22)\u001b[7C1\u001b[2C7\u001b[2C1\u001b[11CPadres\u001b[1C(36-22)\u001b[19;1H\u001b[19;3H4:15\u001b[1CPM\u001b[32C4:15\u001b[1CPM\u001b[6C \u001b[16C7:07\u001b[1CPM\u001b[20;1H\u001b[20;3HDodgers\u001b[1C(37-21)\u001b[24CCubs\u001b[1C(23-34)\u001b[27CMets\u001b[1C(39-21)\u001b[21;1H\u001b[21;3HGiants\u001b[1C(31-26)\u001b[25CYankees\u001b[1C(42-16)\u001b[24CAngels\u001b[1C(28-32)\u001b[24;1H\u001b[24;3H7:10\u001b[1CPM\u001b[32CFinal\u001b[16CH\u001b[2CR\u001b[2CE\u001b[11CFinal/10\u001b[13CH\u001b[2CR\u001b[2CE\u001b[25;1H\u001b[25;3HRed\u001b[1CSox\u001b[1C(31-28)\u001b[24CRays\u001b[1C(34-25)\u001b[9C5\u001b[1C13\u001b[2C0\u001b[11C\u001b[1mRangers (27-31) 11 15 1\u001b[m\u001b[26;1H\u001b[26;3HMariners\u001b[1C(26-32)\u001b[23C\u001b[1mTwins (35-26) 6 11 2\u001b[11C\u001b[mWhite\u001b[1CSox\u001b[1C(27-30)\u001b[4C9\u001b[1C15\u001b[2C2\u001b[29;1H\u001b[29;3HFinal\u001b[16CH\u001b[2CR\u001b[2CE\u001b[30;1H\u001b[30;3HReds\u001b[1C(20-39)\u001b[9C4\u001b[1C12\u001b[2C2\u001b[31;1H\u001b[31;3H\u001b[1mCardinals (34-26) 5 7 0\u001b[m\u001b[36;1H\u001b[36;1H⠧\u001b8"]
21
+ [3.441761, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠇\u001b8"]
22
+ [3.513144, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠏\u001b8"]
23
+ [3.545197, "o", "\u001b7\u001b[36;1H\u001b[36;1H \u001b8"]
24
+ [5.677285, "o", "\u001b7\u001b[3;1H\u001b[3;1H \u001b(0lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk\u001b[4;1H\u001b[4;1H\u001b(B \u001b[37C \u001b(0x\u001b[37Cx\u001b[5;1H\u001b[5;1H\u001b(B \u001b[37C \u001b(0x\u001b[37Cx\u001b[6;1H\u001b[6;1H\u001b(B \u001b[37C \u001b(0x\u001b[37Cx\u001b[7;1H\u001b[7;1H\u001b(B \u001b(0mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj\u001b(B\u001b8"]
25
+ [5.845659, "o", "\u001b7\u001b[3;1H\u001b[3;40H \u001b(0lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk\u001b[4;1H\u001b[4;40H\u001b(B \u001b[37C \u001b(0x\u001b[37Cx\u001b[5;1H\u001b[5;40H\u001b(B \u001b[37C \u001b(0x\u001b[37Cx\u001b[6;1H\u001b[6;40H\u001b(B \u001b[37C \u001b(0x\u001b[37Cx\u001b[7;1H\u001b[7;40H\u001b(B \u001b(0mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj\u001b(B\u001b8"]
26
+ [7.016135, "o", "\u001b7\u001b[1;1H \u001b[3;1H\u001b[78C \u001b[4;1H\u001b[4;3H \u001b[1C \u001b[14C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[14C \u001b[2C \u001b[2C \u001b[9C \u001b[1C \u001b[1C \u001b[11C \u001b[2C \u001b[2C \u001b[8C \u001b[5;1H\u001b[5;3H \u001b[1C \u001b[6C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[6C \u001b[2C \u001b[2C \u001b[9C \u001b[1C \u001b[1C \u001b[6C \u001b[2C \u001b[2C \u001b[8C \u001b[6;1H\u001b[6;3H \u001b[1C \u001b[7C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[6C \u001b[2C \u001b[2C \u001b[9C \u001b[1C \u001b[1C \u001b[5C \u001b[2C \u001b[2C \u001b[8C \u001b[7;1H\u001b[7;79H \u001b[9;1H\u001b[9;3H \u001b[1C \u001b[14C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[11C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[14C \u001b[2C \u001b[2C \u001b[10;1H\u001b[10;3H \u001b[1C \u001b[6C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[6C \u001b[1C \u001b[2C \u001b[11C \u001b[1C \u001b[4C \u001b[1C \u001b[2C \u001b[11;1H\u001b[11;3H \u001b[1C \u001b[4C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[7C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[4C \u001b[2C \u001b[2C \u001b[14;1H\u001b[14;3H \u001b[1C \u001b[11C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[14C \u001b[2C"]
27
+ [7.016312, "o", " \u001b[2C \u001b[11C \u001b[1C \u001b[15;1H\u001b[15;3H \u001b[1C \u001b[1C \u001b[4C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[6C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[16;1H\u001b[16;3H \u001b[1C \u001b[7C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[7C \u001b[2C \u001b[2C \u001b[11C \u001b[1C \u001b[19;1H\u001b[19;3H \u001b[1C \u001b[32C \u001b[1C \u001b[32C \u001b[1C \u001b[20;1H\u001b[20;3H \u001b[1C \u001b[24C \u001b[1C \u001b[27C \u001b[1C \u001b[21;1H\u001b[21;3H \u001b[1C \u001b[25C \u001b[1C \u001b[24C \u001b[1C \u001b[24;1H\u001b[24;3H \u001b[1C \u001b[32C \u001b[16C \u001b[2C \u001b[2C \u001b[11C \u001b[13C \u001b[2C \u001b[2C \u001b[25;1H\u001b[25;3H \u001b[1C \u001b[1C \u001b[24C \u001b[1C \u001b[9C \u001b[1C \u001b[2C \u001b[11C \u001b[26;1H\u001b[26;3H \u001b[1C \u001b[23C \u001b[11C \u001b[1C \u001b[1C \u001b[4C \u001b[1C \u001b[2C \u001b[29;1H\u001b[29;3H \u001b[16C \u001b[2C \u001b[2C \u001b[30;1H\u001b[30;3H \u001b[1C \u001b[9C \u001b[1C \u001b[2C \u001b[31;1H\u001b[31;3H \u001b[36;1H\u001b[36;1H⠙\u001b[35C \u001b[1C \u001b[2C \u001b[1C \u001b[2C \u001b8"]
28
+ [7.069271, "o", "\u001b7\u001b[36;1H⠹\u001b8"]
29
+ [7.120474, "o", "\u001b7\u001b[36;1H⠸\u001b8"]
30
+ [7.169237, "o", "\u001b7\u001b[36;1H⠼\u001b8"]
31
+ [7.220735, "o", "\u001b7\u001b[36;1H⠴\u001b8"]
32
+ [7.270481, "o", "\u001b7\u001b[36;1H⠦\u001b8"]
33
+ [7.320113, "o", "\u001b7\u001b[36;1H⠧\u001b8"]
34
+ [7.370402, "o", "\u001b7\u001b[36;1H⠇\u001b8"]
35
+ [7.419372, "o", "\u001b7\u001b[36;1H⠏\u001b8"]
36
+ [7.469781, "o", "\u001b7\u001b[36;1H⠋\u001b8"]
37
+ [7.520863, "o", "\u001b7\u001b[36;1H⠙\u001b8"]
38
+ [7.571275, "o", "\u001b7\u001b[36;1H⠹\u001b8"]
39
+ [7.626738, "o", "\u001b7\u001b[36;1H⠸\u001b8"]
40
+ [7.669718, "o", "\u001b7\u001b[36;1H⠼\u001b8"]
41
+ [7.721801, "o", "\u001b7\u001b[36;1H⠴\u001b8"]
42
+ [7.7709, "o", "\u001b7\u001b[36;1H⠦\u001b8"]
43
+ [7.821713, "o", "\u001b7\u001b[36;1H⠧\u001b8"]
44
+ [7.873451, "o", "\u001b7\u001b[36;1H⠇\u001b8"]
45
+ [7.922679, "o", "\u001b7\u001b[36;1H⠏\u001b8"]
46
+ [7.972914, "o", "\u001b7\u001b[36;1H⠋\u001b8"]
47
+ [8.022984, "o", "\u001b7\u001b[36;1H⠙\u001b8"]
48
+ [8.072782, "o", "\u001b7\u001b[36;1H⠹\u001b8"]
49
+ [8.122838, "o", "\u001b7\u001b[36;1H⠸\u001b8"]
50
+ [8.17296, "o", "\u001b7\u001b[36;1H⠼\u001b8"]
51
+ [8.222793, "o", "\u001b7\u001b[36;1H⠴\u001b8"]
52
+ [8.272494, "o", "\u001b7\u001b[36;1H⠦\u001b8"]
53
+ [8.324117, "o", "\u001b7\u001b[36;1H⠧\u001b8"]
54
+ [8.375222, "o", "\u001b7\u001b[36;1H⠇\u001b8"]
55
+ [8.423489, "o", "\u001b7\u001b[36;1H⠏\u001b8"]
56
+ [8.471642, "o", "\u001b7\u001b[36;1H⠋\u001b8"]
57
+ [8.522495, "o", "\u001b7\u001b[36;1H⠙\u001b8"]
58
+ [8.572956, "o", "\u001b7\u001b[36;1H⠹\u001b8"]
59
+ [8.62592, "o", "\u001b7\u001b[36;1H⠸\u001b8"]
60
+ [8.675946, "o", "\u001b7\u001b[36;1H⠼\u001b8"]
61
+ [8.726318, "o", "\u001b7\u001b[36;1H⠴\u001b8"]
62
+ [8.863595, "o", "\u001b7\u001b[1;1H\u001b[6CB:\u001b[1C\u001b[32m● ○ ○ ○ \u001b[16C\u001b[m\u001b[33m\u001b(0`\u001b[31C\u001b[m\u001b(B1\u001b[2C2\u001b[2C3\u001b[2C4\u001b[2C5\u001b[2C6\u001b[2C7\u001b[2C8\u001b[2C9\u001b[3C\u001b[1mR\u001b[2C\u001b[mH\u001b[2CE\u001b[2;1H\u001b[2;3H8\u001b[3CS:\u001b[1C\u001b[31m● ○ ○ \u001b[16C\u001b[m◇\u001b[3C◇\u001b[25CARI\u001b[1C0\u001b[2C0\u001b[2C0\u001b[2C0\u001b[2C0\u001b[2C0\u001b[2C0\u001b[2C0\u001b[4C\u001b[1m 0\u001b[2C\u001b[m4\u001b[2C1\u001b[3;1H\u001b[3;3H▼\u001b[3CO:\u001b[1C\u001b[31m○ ○ ○ \u001b[46C\u001b[mPHI\u001b[1C1\u001b[2C2\u001b[2C0\u001b[2C0\u001b[2C0\u001b[2C0\u001b[2C0\u001b[2C1\u001b[4C\u001b[1m 4\u001b[2C\u001b[m9\u001b[2C0\u001b[4;1H\u001b[4;1H\u001b(0qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\u001b[5;1H\u001b[1C\u001b(BARI\u001b[1CPitching:\u001b[1C\u001b[1mCaleb Smith\u001b[1C\u001b[m1.0\u001b[1CIP,\u001b[1C17\u001b[1CP,\u001b[1C5.81\u001b[1CERA\u001b[10C\u001b(0x\u001b[1C\u001b[1m\u001b(B[BOTTOM 8]\u001b[45C\u001b[m\u001b[7;37m \u001b[m\u001b[6;1H\u001b[6;2HPHI\u001b[1CAt\u001b[1CBat:\u001b[3C\u001b[1mJ.T. Realmuto\u001b[1C\u001b[m0-2,\u001b[1C.239\u001b[1CAVG,\u001b[1C3\u001b[1CHR\u001b[11C\u001b(0x\u001b[1C\u001b[34m\u001b(B[Double]\u001b[1C\u001b[mNick\u001b[1CCastellanos\u001b[1Cdoubles\u001b[1C(14)\u001b[1Con\u001b[1Ca\u001b[1Cline\u001b[1Cdrive\u001b[7;1H\u001b[7;60H\u001b(0x\u001b[1C\u001b(Bto\u001b[1Cright\u001b[1Cfielder\u001b[1CJordan\u001b[1CLuplow.\u001b[3CBryce\u001b[1CHarper\u001b[1Cscores.\u001b[8;1H\u001b[8;2H[Ball]\u001b[1C92.3\u001b[1CMPH\u001b[1CFour-Seam\u001b[1CFastball\u001b[20C1-1\u001b[1C\u001b(0x\u001b[1C\u001b[1;47;3"]
63
+ [8.863739, "o", "0m\u001b(B ARI 0 - PHI 4 \u001b[m\u001b[9;1H\u001b[9;2H[Swinging\u001b[1CStrike]\u001b[1C82.9\u001b[1CMPH\u001b[1CChangeup\u001b[19C0-1\u001b[1C\u001b(0x\u001b[1C\u001b[34m\u001b(B[Single]\u001b[1C\u001b[mBryce\u001b[1CHarper\u001b[1Csingles\u001b[1Con\u001b[1Ca\u001b[1Cground\u001b[1Cball\u001b[1Cto\u001b[10;1H\u001b[10;60H\u001b(0x\u001b[1C\u001b(Bcenter\u001b[1Cfielder\u001b[1CAlek\u001b[1CThomas.\u001b[11;1H\u001b[11;60H\u001b(0x\u001b[1C\u001b(B[Defensive\u001b[1CSwitch]\u001b[1CCarson\u001b[1CKelly\u001b[1Cremains\u001b[1Cin\u001b[1Cthe\u001b[1Cgame\u001b[1Cas\u001b[12;1H\u001b[12;60H\u001b(0x\u001b[1C\u001b(Bthe\u001b[1Ccatcher.\u001b[13;1H\u001b[13;60H\u001b(0x\u001b[1C\u001b(B[Defensive\u001b[1CSwitch]\u001b[1CJordan\u001b[1CLuplow\u001b[1Cremains\u001b[1Cin\u001b[1Cthe\u001b[1Cgame\u001b[14;1H\u001b[14;60H\u001b(0x\u001b[1C\u001b(Bas\u001b[1Cthe\u001b[1Cright\u001b[1Cfielder.\u001b[15;1H\u001b[15;60H\u001b(0x\u001b[16;1H\u001b[16;60Hx\u001b[1C\u001b[1m\u001b(B[TOP 8]\u001b[m\u001b[17;1H\u001b[17;60H\u001b(0x\u001b[1C\u001b[37m\u001b(B[Pop Out]\u001b[1C\u001b[mJordan\u001b[1CLuplow\u001b[1Cpops\u001b[1Cout\u001b[1Cto\u001b[1Ccatcher\u001b[1CJ.\u001b[2CT.\u001b[18;1H\u001b[18;60H\u001b(0x\u001b[1C\u001b(BRealmuto\u001b[1Cin\u001b[1Cfoul\u001b[1Cterritory.\u001b[1C\u001b[1m3 out\u001b[m\u001b[19;1H\u001b[19;60H\u001b(0x\u001b[1C\u001b(B[Offensive\u001b[1CSubstitution]\u001b[1COffensive\u001b[1CSubstitution:\u001b[20;1H\u001b[20;60H\u001b(0x\u001b[1C\u001b(BPinch-hitter\u001b[1CJordan\u001b[1CLuplow\u001b[1Creplaces\u001b[1CPavin\u001b[1CSmith.\u001b[21;1H\u001b[21;60H\u001b(0x\u001b[1C\u001b[31m\u001b(B[Strikeout]\u001b[1C\u001b[mDaulton\u001b[1CVar"]
64
+ [8.863817, "o", "sho\u001b[1Ccalled\u001b[1Cout\u001b[1Con\u001b[1Cstrikes.\u001b[1C\u001b[1m2 \u001b[m\u001b[22;1H\u001b[22;60H\u001b(0x\u001b[1C\u001b[1m\u001b(Bout\u001b[m\u001b[23;1H\u001b[23;60H\u001b(0x\u001b[1C\u001b[37m\u001b(B[Flyout]\u001b[1C\u001b[mCarson\u001b[1CKelly\u001b[1Cflies\u001b[1Cout\u001b[1Cto\u001b[1Cright\u001b[1Cfielder\u001b[1CNick\u001b[24;1H\u001b[24;60H\u001b(0x\u001b[1C\u001b(BCastellanos.\u001b[1C\u001b[1m1 out\u001b[m\u001b[25;1H\u001b[25;60H\u001b(0x\u001b[1C\u001b(B[Offensive\u001b[1CSubstitution]\u001b[1COffensive\u001b[1CSubstitution:\u001b[26;1H\u001b[26;60H\u001b(0x\u001b[1C\u001b(BPinch-hitter\u001b[1CCarson\u001b[1CKelly\u001b[1Creplaces\u001b[1CJose\u001b[1CHerrera.\u001b[27;1H\u001b[27;60H\u001b(0x\u001b[1C\u001b(B[Pitching\u001b[1CSubstitution]\u001b[1CPitching\u001b[1CChange:\u001b[1CBrad\u001b[1CHand\u001b[28;1H\u001b[28;60H\u001b(0x\u001b[1C\u001b(Breplaces\u001b[1CAndrew\u001b[1CBellatti.\u001b[29;1H\u001b[29;60H\u001b(0x\u001b[30;1H\u001b[30;60Hx\u001b[1C\u001b[1m\u001b(B[BOTTOM 7]\u001b[m\u001b[31;1H\u001b[31;60H\u001b(0x\u001b[1C\u001b[37m\u001b(B[Flyout]\u001b[1C\u001b[mRhys\u001b[1CHoskins\u001b[1Cflies\u001b[1Cout\u001b[1Cto\u001b[1Cleft\u001b[1Cfielder\u001b[1CDavid\u001b[32;1H\u001b[32;60H\u001b(0x\u001b[1C\u001b(BPeralta.\u001b[1C\u001b[1m3 out\u001b[m\u001b[33;1H\u001b[33;60H\u001b(0x\u001b[1C\u001b[37m\u001b(B[Flyout]\u001b[1C\u001b[mKyle\u001b[1CSchwarber\u001b[1Cflies\u001b[1Cout\u001b[1Cto\u001b[1Cleft\u001b[1Cfielder\u001b[34;1H\u001b[34;60H\u001b(0x\u001b[1C\u001b(BDavid\u001b[1CPeralta.\u001b[1C\u001b[1m2 out\u001b[m\u001b[35;1H\u001b[35;60H\u001b(0x\u001b[1C\u001b[37m\u001b(B[Flyout]\u001b[1C\u001b[mBryson\u001b[1CStott\u001b[1C"]
65
+ [8.863918, "o", "flies\u001b[1Cout\u001b[1Cto\u001b[1Cleft\u001b[1Cfielder\u001b[1CDavid\u001b[36;1H\u001b[36;1H⠧\u001b8"]
66
+ [8.924124, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠇\u001b8"]
67
+ [8.9612, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠏\u001b8"]
68
+ [9.007753, "o", "\u001b7\u001b[36;1H\u001b[36;1H \u001b8"]
69
+ [12.88646, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠙\u001b8"]
70
+ [12.926627, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠹\u001b8"]
71
+ [12.963286, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠸\u001b8"]
72
+ [13.012915, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠼\u001b8"]
73
+ [13.067279, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠴\u001b8"]
74
+ [13.120957, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠦\u001b8"]
75
+ [13.166379, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠧\u001b8"]
76
+ [13.218225, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠇\u001b8"]
77
+ [13.26743, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠏\u001b8"]
78
+ [13.315387, "o", "\u001b7\u001b[36;1H\u001b[36;1H \u001b8"]
79
+ [15.120313, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠙\u001b8"]
80
+ [15.166934, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠹\u001b8"]
81
+ [15.219901, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠸\u001b8"]
82
+ [15.28849, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠼\u001b8"]
83
+ [15.319905, "o", "\u001b7\u001b[2;1H\u001b[2;12H\u001b[31m●\u001b[m\u001b[5;1H\u001b[5;37H8\u001b[8;1H\u001b[8;3HFou\u001b[3C83\u001b[1C8\u001b[5CChangeup \u001b[1C \u001b[22C2\u001b[9;1H\u001b[9;3HBall] 92.3 MPH Four-Seam Fastball \u001b[19C1\u001b[10;1H\u001b[10;2H[Swinging\u001b[1CStrike]\u001b[1C82.9\u001b[1CMPH\u001b[1CChangeup\u001b[19C0-1\u001b[36;1H\u001b[36;1H⠴\u001b8"]
84
+ [15.366276, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠦\u001b8"]
85
+ [15.410643, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠧\u001b8"]
86
+ [15.468101, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠇\u001b8"]
87
+ [15.52299, "o", "\u001b7\u001b[36;1H\u001b[36;1H⠏\u001b8"]
88
+ [15.568221, "o", "\u001b7\u001b[36;1H\u001b[36;1H \u001b8"]
89
+ [19.074182, "o", "\u001b[?1l\u001b>"]
90
+ [19.074493, "o", "\u001b[?12l\u001b[?25h"]
91
+ [19.078092, "o", "\u001b[H\u001b[2J"]
92
+ [19.078282, "o", "\u001b[?1002l\u001b[?1003l\u001b[?1006l"]
93
+ [19.078387, "o", "\u001b[?1049l"]
94
+ [19.093955, "o", "$ "]
95
+ [19.677325, "o", "exit\r\n"]
package/demo.gif ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playball",
3
- "version": "2.2.2",
3
+ "version": "3.1.0",
4
4
  "description": "Watch MLB games from the comfort of your terminal",
5
5
  "keywords": [
6
6
  "MLB",
@@ -13,11 +13,11 @@
13
13
  "build": "npm run lint && npm run clean && npm run compile",
14
14
  "clean": "rimraf ./dist",
15
15
  "compile": "babel src --out-dir dist",
16
- "lint": "eslint src",
17
- "start": "babel-node ./src/main.js",
18
- "prepublishOnly": "npm run build"
16
+ "lint": "eslint --ext .jsx,.js src",
17
+ "start": "babel src --out-dir dist --watch",
18
+ "prepublishOnly": "npm run build",
19
+ "react-devtools": "react-devtools"
19
20
  },
20
- "main": "dist/main.js",
21
21
  "bin": {
22
22
  "playball": "./bin/playball.js"
23
23
  },
@@ -33,37 +33,59 @@
33
33
  "preferGlobal": true,
34
34
  "license": "MIT",
35
35
  "dependencies": {
36
- "axios": "^0.19.2",
36
+ "@reduxjs/toolkit": "^1.8.0",
37
+ "axios": "^0.26.1",
37
38
  "blessed": "^0.1.81",
38
- "immutable": "^3.8.2",
39
+ "commander": "^11.0.0",
40
+ "conf": "^11.0.1",
41
+ "date-fns": "^2.28.0",
39
42
  "json-patch": "^0.7.0",
40
- "moment": "^2.24.0",
41
- "prop-types": "^15.6.2",
42
- "react": "^16.8.6",
43
- "react-blessed": "^0.5.0",
44
- "react-devtools-core": "^3.6.1",
45
- "react-redux": "^5.0.7",
46
- "redux": "^4.0.0",
47
- "redux-actions": "^2.6.1",
48
- "redux-thunk": "^2.3.0",
49
- "reselect": "^3.0.1",
50
- "winston": "^3.3.3",
51
- "ws": "^6.2.1"
43
+ "prop-types": "^15.8.1",
44
+ "raf": "^3.4.1",
45
+ "react": "^17.0.2",
46
+ "react-blessed": "^0.7.2",
47
+ "react-devtools-core": "^4.24.7",
48
+ "react-redux": "^7.2.6",
49
+ "redux": "^4.1.2",
50
+ "update-notifier": "^6.0.2",
51
+ "winston": "^3.7.2"
52
52
  },
53
53
  "devDependencies": {
54
- "@babel/cli": "^7.10.5",
55
- "@babel/core": "^7.11.1",
56
- "@babel/node": "^7.10.5",
57
- "@babel/preset-env": "^7.11.0",
58
- "@babel/preset-react": "^7.10.4",
59
- "eslint": "^7.6.0",
60
- "eslint-plugin-react": "^7.20.5",
61
- "rimraf": "^2.6.3"
54
+ "@babel/cli": "^7.17.10",
55
+ "@babel/core": "^7.18.2",
56
+ "@babel/node": "^7.17.10",
57
+ "@babel/preset-env": "^7.18.2",
58
+ "@babel/preset-react": "^7.17.12",
59
+ "babel-plugin-module-resolver": "^4.1.0",
60
+ "eslint": "^8.12.0",
61
+ "eslint-plugin-react": "^7.29.4",
62
+ "react-devtools": "^4.24.7",
63
+ "rimraf": "^2.6.3",
64
+ "ws": "^8.5.0"
62
65
  },
66
+ "type": "module",
63
67
  "babel": {
64
68
  "presets": [
65
- "@babel/preset-env",
69
+ [
70
+ "@babel/preset-env",
71
+ {
72
+ "targets": {
73
+ "node": "14"
74
+ },
75
+ "modules": false
76
+ }
77
+ ],
66
78
  "@babel/preset-react"
79
+ ],
80
+ "plugins": [
81
+ [
82
+ "module-resolver",
83
+ {
84
+ "alias": {
85
+ "react-redux": "react-redux/lib/alternate-renderers.js"
86
+ }
87
+ }
88
+ ]
67
89
  ]
68
90
  }
69
91
  }
package/src/cli.js ADDED
@@ -0,0 +1,46 @@
1
+ /* eslint no-console: 0 */
2
+ import { Command } from 'commander';
3
+ import updateNotifier from 'update-notifier';
4
+
5
+ import * as config from './config.js';
6
+ import main from './main.js';
7
+ import pkg from './package.js';
8
+
9
+ const program = new Command();
10
+ const notifier = updateNotifier({
11
+ pkg,
12
+ updateCheckInterval: 1000 * 60 * 60 * 24 * 7 // 1 week
13
+ });
14
+
15
+ program
16
+ .name(pkg.name)
17
+ .description(pkg.description)
18
+ .version(pkg.version)
19
+ .action(main)
20
+ .hook('postAction', () => notifier.notify({
21
+ isGlobal: true,
22
+ }));
23
+
24
+ program.command('config')
25
+ .description('Set or get configration values')
26
+ .argument('[key]')
27
+ .argument('[value]')
28
+ .option('--unset', 'Unset configuration value')
29
+ .action((key, value, options) => {
30
+ if (options.unset) {
31
+ config.unset(key);
32
+ return;
33
+ }
34
+ if (!key) {
35
+ for (const [key, value] of Object.entries(config.getAll())) {
36
+ console.log(`${key} = ${value}`);
37
+ }
38
+ } else if (!value) {
39
+ console.log(config.get(key));
40
+ } else {
41
+ config.set(key, value);
42
+ }
43
+ });
44
+
45
+
46
+ program.parse();
@@ -1,75 +1,108 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { connect } from 'react-redux';
4
- import { selectAllPlays, selectTeams } from '../selectors/game';
2
+ import { useSelector } from 'react-redux';
3
+ import { selectAllPlays, selectTeams } from '../features/games.js';
5
4
 
6
- import style from '../style';
5
+ import { get } from '../config.js';
6
+ import style from '../style/index.js';
7
7
 
8
- class AllPlays extends React.Component {
9
- render() {
10
- const { plays, teams } = this.props;
11
- let inning = '';
12
- const lines = [];
13
- plays && plays.reverse().forEach(play => {
14
- const playInning = play.getIn(['about', 'halfInning']) + ' ' + play.getIn(['about', 'inning']);
15
- if (playInning !== inning) {
16
- inning = playInning;
17
- lines.push(`{yellow-fg}[${inning.toUpperCase()}]{/yellow-fg}`);
8
+
9
+ function getPlayResultColor(play) {
10
+ const lastPlay = play.playEvents[play.playEvents.length - 1]?.details;
11
+ if (!lastPlay) {
12
+ return get('color.other-event');
13
+ } else if (lastPlay.isBall) {
14
+ return get('color.walk');
15
+ } else if (lastPlay.isStrike) {
16
+ return get('color.strike-out');
17
+ } else if (lastPlay.isInPlay && !play.about.hasOut) {
18
+ return get('color.in-play-no-out');
19
+ } else {
20
+ return get('color.in-play-out');
21
+ }
22
+ }
23
+
24
+ function formatOut(out) {
25
+ return ` {bold}${out} out{/}`;
26
+ }
27
+
28
+
29
+ function AllPlays() {
30
+ const plays = useSelector(selectAllPlays);
31
+ const teams = useSelector(selectTeams);
32
+
33
+ const formatScoreDetail = (scoreObj) => (
34
+ ` {bold}{${get('color.in-play-runs-bg')}-bg}{${get('color.in-play-runs-fg')}-fg} ` +
35
+ `${teams.away.abbreviation} ${scoreObj.awayScore} - ` +
36
+ `${teams.home.abbreviation} ${scoreObj.homeScore}` +
37
+ ' {/}'
38
+ );
39
+
40
+ let inning = '';
41
+ const lines = [];
42
+ plays && plays.slice().reverse().forEach((play, playIdx, plays) => {
43
+ let lastPlay;
44
+ if (playIdx < plays.length - 1) {
45
+ lastPlay = plays[playIdx + 1];
46
+ }
47
+ const playInning = play.about.halfInning + ' ' + play.about.inning;
48
+ if (playInning !== inning) {
49
+ inning = playInning;
50
+ if (lines.length > 0) {
51
+ lines.push('');
52
+ }
53
+ lines.push(`{bold}[${inning.toUpperCase()}]{/}`);
54
+ }
55
+
56
+ if (play.about.isComplete) {
57
+ const color = getPlayResultColor(play);
58
+ let line = `{${color}-fg}[${play.result.event}]{/} ${play.result.description}`;
59
+ if (play.about.hasOut) {
60
+ const lastOut = play.playEvents[play.playEvents.length - 1].count.outs;
61
+ if (lastOut !== play.count.outs) {
62
+ line += formatOut(play.count.outs);
63
+ }
64
+ }
65
+ if (play.about.isScoringPlay) {
66
+ line += formatScoreDetail(play.result);
18
67
  }
19
- if (play.getIn(['about', 'isComplete'])) {
20
- let line = `[${play.getIn(['result', 'event'])}] ${play.getIn(['result', 'description'])}`;
21
- if (play.getIn(['about', 'hasOut'])) {
22
- line += `{bold}${play.getIn(['count', 'outs'])} out{/bold}`;
68
+ lines.push(line);
69
+ }
70
+
71
+ play.playEvents && play.playEvents.slice().reverse().forEach((event, eventIdx, events) => {
72
+ if (event.type === 'action') {
73
+ let line = '';
74
+ if (event.details.event) {
75
+ line += `{${get('color.other-event')}-fg}[${event.details.event}]{/} `;
76
+ }
77
+ line += event.details.description;
78
+ if (event.isScoringPlay || event.details.isScoringPlay) {
79
+ line += formatScoreDetail(event.details);
23
80
  }
24
- if (play.getIn(['about', 'isScoringPlay'])) {
25
- line += '{bold}{white-bg}{black-fg} ' +
26
- `${teams.getIn(['away', 'abbreviation'])} ${play.getIn(['result', 'awayScore'])} - ` +
27
- `${teams.getIn(['home', 'abbreviation'])} ${play.getIn(['result', 'homeScore'])}` +
28
- ' {/black-fg}{/white-bg}{/bold}';
81
+ const currentOut = event.count?.outs;
82
+ let prevOut = lastPlay ? lastPlay.count.outs : 0;
83
+ if (eventIdx < events.length - 1) {
84
+ prevOut = events[eventIdx + 1].count?.outs;
85
+ }
86
+ if (currentOut > prevOut) {
87
+ line += formatOut(currentOut);
29
88
  }
30
89
  lines.push(line);
31
90
  }
32
- play.get('playEvents') && play.get('playEvents').reverse().forEach(event => {
33
- if (event.get('type') === 'action') {
34
- let line = '';
35
- if (event.getIn(['details', 'event'])) {
36
- line += `[${event.getIn(['details', 'event'])}] `;
37
- }
38
- line += event.getIn(['details', 'description']);
39
- if (event.get('isScoringPlay')) {
40
- line += '{white-bg}{black-fg}{bold}' +
41
- `${teams.getIn(['away', 'abbreviation'])} ${event.getIn(['details', 'awayScore'])} - ` +
42
- `${teams.getIn(['home', 'abbreviation'])} ${event.getIn(['details', 'homeScore'])}` +
43
- '{/bold}{/black-fg}{/white-bg}';
44
- }
45
- lines.push(line);
46
- }
47
- });
48
91
  });
49
- return (
50
- <box
51
- content={lines.join('\n')}
52
- focused
53
- mouse
54
- keys
55
- vi
56
- scrollable
57
- scrollbar={style.scrollbar}
58
- alwaysScroll
59
- tags
60
- />
61
- );
62
- }
92
+ });
93
+ return (
94
+ <box
95
+ content={lines.join('\n')}
96
+ focused
97
+ mouse
98
+ keys
99
+ vi
100
+ scrollable
101
+ scrollbar={style.scrollbar}
102
+ alwaysScroll
103
+ tags
104
+ />
105
+ );
63
106
  }
64
107
 
65
- AllPlays.propTypes = {
66
- plays: PropTypes.object,
67
- teams: PropTypes.object,
68
- };
69
-
70
- const mapStateToProps = state => ({
71
- plays: selectAllPlays(state),
72
- teams: selectTeams(state),
73
- });
74
-
75
- export default connect(mapStateToProps)(AllPlays);
108
+ export default AllPlays;