playball 3.0.0 → 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.
- package/.eslintrc.json +1 -1
- package/README.md +62 -0
- package/bin/playball.js +1 -1
- package/package.json +10 -6
- package/src/cli.js +46 -0
- package/src/components/AllPlays.jsx +14 -13
- package/src/components/App.jsx +6 -6
- package/src/components/AtBat.jsx +1 -1
- package/src/components/Bases.jsx +3 -2
- package/src/components/Count.jsx +5 -4
- package/src/components/FinishedGame.jsx +2 -2
- package/src/components/Game.jsx +5 -5
- package/src/components/GameList.jsx +8 -5
- package/src/components/Grid.jsx +1 -1
- package/src/components/HelpBar.jsx +1 -1
- package/src/components/InningDisplay.jsx +1 -1
- package/src/components/LineScore.jsx +1 -1
- package/src/components/LiveGame.jsx +7 -7
- package/src/components/LoadingSpinner.jsx +2 -2
- package/src/components/Matchup.jsx +1 -1
- package/src/components/PreviewGame.jsx +1 -1
- package/src/components/Standings.jsx +6 -3
- package/src/config.js +167 -0
- package/src/features/games.js +2 -1
- package/src/features/keys.js +5 -4
- package/src/features/schedule.js +2 -1
- package/src/features/standings.js +2 -1
- package/src/hooks/useKey.js +1 -1
- package/src/logger.js +4 -1
- package/src/main.js +19 -15
- package/src/package.js +7 -0
- package/src/screen.js +18 -10
- package/src/store/index.js +6 -5
- package/src/utils.js +10 -0
- package/dist/components/AllPlays.js +0 -133
- package/dist/components/App.js +0 -68
- package/dist/components/AtBat.js +0 -67
- package/dist/components/Bases.js +0 -38
- package/dist/components/Count.js +0 -36
- package/dist/components/FinishedGame.js +0 -124
- package/dist/components/Game.js +0 -82
- package/dist/components/GameList.js +0 -222
- package/dist/components/Grid.js +0 -115
- package/dist/components/HelpBar.js +0 -30
- package/dist/components/InningDisplay.js +0 -26
- package/dist/components/LineScore.js +0 -60
- package/dist/components/LiveGame.js +0 -70
- package/dist/components/LoadingSpinner.js +0 -55
- package/dist/components/Matchup.js +0 -58
- package/dist/components/PreviewGame.js +0 -76
- package/dist/components/Standings.js +0 -91
- package/dist/features/games.js +0 -135
- package/dist/features/keys.js +0 -63
- package/dist/features/schedule.js +0 -58
- package/dist/features/standings.js +0 -57
- package/dist/hooks/useKey.js +0 -23
- package/dist/logger.js +0 -22
- package/dist/main.js +0 -28
- package/dist/screen.js +0 -22
- package/dist/store/index.js +0 -32
- package/dist/style/index.js +0 -22
package/.eslintrc.json
CHANGED
package/README.md
CHANGED
|
@@ -46,6 +46,68 @@ key | action
|
|
|
46
46
|
----|--------
|
|
47
47
|
<kbd>↓</kbd>/<kbd>j</kbd>, <kbd>↑</kbd>/<kbd>k</kbd> | scroll list of all plays
|
|
48
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`)
|
|
110
|
+
|
|
49
111
|
### Development
|
|
50
112
|
```
|
|
51
113
|
git clone https://github.com/paaatrick/playball.git
|
package/bin/playball.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import '../dist/cli.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playball",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Watch MLB games from the comfort of your terminal",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MLB",
|
|
@@ -14,11 +14,10 @@
|
|
|
14
14
|
"clean": "rimraf ./dist",
|
|
15
15
|
"compile": "babel src --out-dir dist",
|
|
16
16
|
"lint": "eslint --ext .jsx,.js src",
|
|
17
|
-
"start": "babel-
|
|
17
|
+
"start": "babel src --out-dir dist --watch",
|
|
18
18
|
"prepublishOnly": "npm run build",
|
|
19
19
|
"react-devtools": "react-devtools"
|
|
20
20
|
},
|
|
21
|
-
"main": "dist/main.js",
|
|
22
21
|
"bin": {
|
|
23
22
|
"playball": "./bin/playball.js"
|
|
24
23
|
},
|
|
@@ -37,6 +36,8 @@
|
|
|
37
36
|
"@reduxjs/toolkit": "^1.8.0",
|
|
38
37
|
"axios": "^0.26.1",
|
|
39
38
|
"blessed": "^0.1.81",
|
|
39
|
+
"commander": "^11.0.0",
|
|
40
|
+
"conf": "^11.0.1",
|
|
40
41
|
"date-fns": "^2.28.0",
|
|
41
42
|
"json-patch": "^0.7.0",
|
|
42
43
|
"prop-types": "^15.8.1",
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"react-devtools-core": "^4.24.7",
|
|
47
48
|
"react-redux": "^7.2.6",
|
|
48
49
|
"redux": "^4.1.2",
|
|
50
|
+
"update-notifier": "^6.0.2",
|
|
49
51
|
"winston": "^3.7.2"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
@@ -61,14 +63,16 @@
|
|
|
61
63
|
"rimraf": "^2.6.3",
|
|
62
64
|
"ws": "^8.5.0"
|
|
63
65
|
},
|
|
66
|
+
"type": "module",
|
|
64
67
|
"babel": {
|
|
65
68
|
"presets": [
|
|
66
69
|
[
|
|
67
70
|
"@babel/preset-env",
|
|
68
71
|
{
|
|
69
72
|
"targets": {
|
|
70
|
-
"node": "
|
|
71
|
-
}
|
|
73
|
+
"node": "14"
|
|
74
|
+
},
|
|
75
|
+
"modules": false
|
|
72
76
|
}
|
|
73
77
|
],
|
|
74
78
|
"@babel/preset-react"
|
|
@@ -78,7 +82,7 @@
|
|
|
78
82
|
"module-resolver",
|
|
79
83
|
{
|
|
80
84
|
"alias": {
|
|
81
|
-
"react-redux": "react-redux/lib/alternate-renderers"
|
|
85
|
+
"react-redux": "react-redux/lib/alternate-renderers.js"
|
|
82
86
|
}
|
|
83
87
|
}
|
|
84
88
|
]
|
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,27 +1,28 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
|
-
import { selectAllPlays, selectTeams } from '../features/games';
|
|
3
|
+
import { selectAllPlays, selectTeams } from '../features/games.js';
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import { get } from '../config.js';
|
|
6
|
+
import style from '../style/index.js';
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
function getPlayResultColor(play) {
|
|
9
10
|
const lastPlay = play.playEvents[play.playEvents.length - 1]?.details;
|
|
10
11
|
if (!lastPlay) {
|
|
11
|
-
return '
|
|
12
|
+
return get('color.other-event');
|
|
12
13
|
} else if (lastPlay.isBall) {
|
|
13
|
-
return '
|
|
14
|
+
return get('color.walk');
|
|
14
15
|
} else if (lastPlay.isStrike) {
|
|
15
|
-
return '
|
|
16
|
+
return get('color.strike-out');
|
|
16
17
|
} else if (lastPlay.isInPlay && !play.about.hasOut) {
|
|
17
|
-
return '
|
|
18
|
+
return get('color.in-play-no-out');
|
|
18
19
|
} else {
|
|
19
|
-
return '
|
|
20
|
+
return get('color.in-play-out');
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
function formatOut(out) {
|
|
24
|
-
return ` {bold}${out} out{/
|
|
25
|
+
return ` {bold}${out} out{/}`;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
|
|
@@ -30,10 +31,10 @@ function AllPlays() {
|
|
|
30
31
|
const teams = useSelector(selectTeams);
|
|
31
32
|
|
|
32
33
|
const formatScoreDetail = (scoreObj) => (
|
|
33
|
-
|
|
34
|
+
` {bold}{${get('color.in-play-runs-bg')}-bg}{${get('color.in-play-runs-fg')}-fg} ` +
|
|
34
35
|
`${teams.away.abbreviation} ${scoreObj.awayScore} - ` +
|
|
35
36
|
`${teams.home.abbreviation} ${scoreObj.homeScore}` +
|
|
36
|
-
' {/
|
|
37
|
+
' {/}'
|
|
37
38
|
);
|
|
38
39
|
|
|
39
40
|
let inning = '';
|
|
@@ -49,12 +50,12 @@ function AllPlays() {
|
|
|
49
50
|
if (lines.length > 0) {
|
|
50
51
|
lines.push('');
|
|
51
52
|
}
|
|
52
|
-
lines.push(`{bold}[${inning.toUpperCase()}]{/
|
|
53
|
+
lines.push(`{bold}[${inning.toUpperCase()}]{/}`);
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
if (play.about.isComplete) {
|
|
56
57
|
const color = getPlayResultColor(play);
|
|
57
|
-
let line = `{${color}-fg}[${play.result.event}]{
|
|
58
|
+
let line = `{${color}-fg}[${play.result.event}]{/} ${play.result.description}`;
|
|
58
59
|
if (play.about.hasOut) {
|
|
59
60
|
const lastOut = play.playEvents[play.playEvents.length - 1].count.outs;
|
|
60
61
|
if (lastOut !== play.count.outs) {
|
|
@@ -71,7 +72,7 @@ function AllPlays() {
|
|
|
71
72
|
if (event.type === 'action') {
|
|
72
73
|
let line = '';
|
|
73
74
|
if (event.details.event) {
|
|
74
|
-
line += `[${event.details.event}] `;
|
|
75
|
+
line += `{${get('color.other-event')}-fg}[${event.details.event}]{/} `;
|
|
75
76
|
}
|
|
76
77
|
line += event.details.description;
|
|
77
78
|
if (event.isScoringPlay || event.details.isScoringPlay) {
|
package/src/components/App.jsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { useDispatch } from 'react-redux';
|
|
3
|
-
import GameList from './GameList';
|
|
4
|
-
import HelpBar from './HelpBar';
|
|
5
|
-
import { setSelectedId } from '../features/games';
|
|
6
|
-
import Game from './Game';
|
|
7
|
-
import useKey from '../hooks/useKey';
|
|
8
|
-
import Standings from './Standings';
|
|
3
|
+
import GameList from './GameList.js';
|
|
4
|
+
import HelpBar from './HelpBar.js';
|
|
5
|
+
import { setSelectedId } from '../features/games.js';
|
|
6
|
+
import Game from './Game.js';
|
|
7
|
+
import useKey from '../hooks/useKey.js';
|
|
8
|
+
import Standings from './Standings.js';
|
|
9
9
|
|
|
10
10
|
const SCHEDULE = 'schedule';
|
|
11
11
|
const STANDINGS = 'standings';
|
package/src/components/AtBat.jsx
CHANGED
package/src/components/Bases.jsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
|
-
import {
|
|
4
|
+
import { get } from '../config.js';
|
|
5
|
+
import { selectLineScore } from '../features/games.js';
|
|
5
6
|
|
|
6
|
-
const formatBase = (offense, base) => (base in offense) ? '
|
|
7
|
+
const formatBase = (offense, base) => (base in offense) ? `{${get('color.on-base')}-fg}◆{/}` : '◇';
|
|
7
8
|
|
|
8
9
|
function Bases({align}) {
|
|
9
10
|
const { offense } = useSelector(selectLineScore);
|
package/src/components/Count.jsx
CHANGED
|
@@ -2,16 +2,17 @@ import React from 'react';
|
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { get } from '../config.js';
|
|
6
|
+
import { selectLineScore } from '../features/games.js';
|
|
6
7
|
|
|
7
8
|
const formatCount = (count, total) => '● '.repeat(count) + '○ '.repeat(total - count);
|
|
8
9
|
|
|
9
10
|
function Count({align}) {
|
|
10
11
|
const linescore = useSelector(selectLineScore);
|
|
11
12
|
const content =
|
|
12
|
-
`B: {
|
|
13
|
-
`S: {
|
|
14
|
-
`O: {
|
|
13
|
+
`B: {${get('color.ball')}-fg}${formatCount(linescore.balls, 4)}{/}\n` +
|
|
14
|
+
`S: {${get('color.strike')}-fg}${formatCount(linescore.strikes, 3)}{/}\n` +
|
|
15
|
+
`O: {${get('color.out')}-fg}${formatCount(linescore.outs, 3)}{/}`;
|
|
15
16
|
return (
|
|
16
17
|
<box align={align} content={content} tags />
|
|
17
18
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
|
-
import { selectLineScore, selectTeams, selectDecisions, selectBoxscore, selectGameStatus } from '../features/games';
|
|
4
|
-
import LineScore from './LineScore';
|
|
3
|
+
import { selectLineScore, selectTeams, selectDecisions, selectBoxscore, selectGameStatus } from '../features/games.js';
|
|
4
|
+
import LineScore from './LineScore.js';
|
|
5
5
|
|
|
6
6
|
const getPlayer = (id, boxscore) => {
|
|
7
7
|
const homePlayer = boxscore.home?.players?.['ID' + id];
|
package/src/components/Game.jsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { useDispatch, useSelector } from 'react-redux';
|
|
3
3
|
|
|
4
|
-
import { fetchGame, selectGame, selectSelectedId, selectFullUpdateRequired } from '../features/games';
|
|
4
|
+
import { fetchGame, selectGame, selectSelectedId, selectFullUpdateRequired } from '../features/games.js';
|
|
5
5
|
|
|
6
|
-
import PreviewGame from './PreviewGame';
|
|
7
|
-
import LiveGame from './LiveGame';
|
|
8
|
-
import FinishedGame from './FinishedGame';
|
|
6
|
+
import PreviewGame from './PreviewGame.js';
|
|
7
|
+
import LiveGame from './LiveGame.js';
|
|
8
|
+
import FinishedGame from './FinishedGame.js';
|
|
9
9
|
|
|
10
|
-
import log from '../logger';
|
|
10
|
+
import log from '../logger.js';
|
|
11
11
|
|
|
12
12
|
function Game() {
|
|
13
13
|
const dispatch = useDispatch();
|
|
@@ -2,17 +2,20 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import { useDispatch, useSelector } from 'react-redux';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { add, format } from 'date-fns';
|
|
5
|
-
import { fetchSchedule, selectData, selectLoading } from '../features/schedule';
|
|
6
|
-
|
|
7
|
-
import Grid from './Grid';
|
|
8
|
-
import useKey from '../hooks/useKey';
|
|
5
|
+
import { fetchSchedule, selectData, selectLoading } from '../features/schedule.js';
|
|
6
|
+
import { teamFavoriteStar } from '../utils.js';
|
|
7
|
+
import Grid from './Grid.js';
|
|
8
|
+
import useKey from '../hooks/useKey.js';
|
|
9
9
|
|
|
10
10
|
const formatGame = game => {
|
|
11
11
|
const startTime = format(new Date(game.gameDate), 'p');
|
|
12
12
|
const start = (game.doubleHeader === 'Y' && game.gameNumber > 1) ?
|
|
13
13
|
'Game ' + game.gameNumber :
|
|
14
14
|
startTime;
|
|
15
|
-
const teamName = (team) =>
|
|
15
|
+
const teamName = (team) => {
|
|
16
|
+
const star = teamFavoriteStar(team.team);
|
|
17
|
+
return star + `${team.team.teamName} (${team.leagueRecord.wins}-${team.leagueRecord.losses})`.padEnd(star ? 18 : 20);
|
|
18
|
+
};
|
|
16
19
|
let content = [start, teamName(game.teams.away), teamName(game.teams.home)];
|
|
17
20
|
const gameState = game.status.abstractGameCode;
|
|
18
21
|
const detailedState = game.status.detailedState;
|
package/src/components/Grid.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import useKey from '../hooks/useKey';
|
|
3
|
+
import useKey from '../hooks/useKey.js';
|
|
4
4
|
|
|
5
5
|
function Grid({ items, itemHeight, itemMinWidth, onSelect }) {
|
|
6
6
|
const containerRef = useRef();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
3
|
|
|
4
|
-
import { selectLineScore } from '../features/games';
|
|
4
|
+
import { selectLineScore } from '../features/games.js';
|
|
5
5
|
|
|
6
6
|
function InningDisplay() {
|
|
7
7
|
const linescore = useSelector(selectLineScore);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { useSelector } from 'react-redux';
|
|
4
|
-
import { selectLineScore, selectTeams } from '../features/games';
|
|
4
|
+
import { selectLineScore, selectTeams } from '../features/games.js';
|
|
5
5
|
|
|
6
6
|
const getRuns = (inning, homeAway, isFinal) => {
|
|
7
7
|
const runs = inning[homeAway].runs;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import Count from './Count';
|
|
4
|
-
import Bases from './Bases';
|
|
5
|
-
import LineScore from './LineScore';
|
|
6
|
-
import Matchup from './Matchup';
|
|
7
|
-
import AtBat from './AtBat';
|
|
8
|
-
import AllPlays from './AllPlays';
|
|
9
|
-
import InningDisplay from './InningDisplay';
|
|
3
|
+
import Count from './Count.js';
|
|
4
|
+
import Bases from './Bases.js';
|
|
5
|
+
import LineScore from './LineScore.js';
|
|
6
|
+
import Matchup from './Matchup.js';
|
|
7
|
+
import AtBat from './AtBat.js';
|
|
8
|
+
import AllPlays from './AllPlays.js';
|
|
9
|
+
import InningDisplay from './InningDisplay.js';
|
|
10
10
|
|
|
11
11
|
function LiveGame() {
|
|
12
12
|
return (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
|
-
import { selectLoading as selectScheduleLoading } from '../features/schedule';
|
|
4
|
-
import { selectLoading as gamesLoading } from '../features/games';
|
|
3
|
+
import { selectLoading as selectScheduleLoading } from '../features/schedule.js';
|
|
4
|
+
import { selectLoading as gamesLoading } from '../features/games.js';
|
|
5
5
|
|
|
6
6
|
const frames = [
|
|
7
7
|
'⠋',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
|
-
import { selectCurrentPlay, selectBoxscore, selectTeams } from '../features/games';
|
|
3
|
+
import { selectCurrentPlay, selectBoxscore, selectTeams } from '../features/games.js';
|
|
4
4
|
|
|
5
5
|
const getPlayerStats = (boxscore, teams, id) => {
|
|
6
6
|
const key = 'ID' + id;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
3
|
import { format } from 'date-fns';
|
|
4
|
-
import { selectTeams, selectVenue, selectStartTime, selectBoxscore, selectProbablePitchers, selectGameStatus } from '../features/games';
|
|
4
|
+
import { selectTeams, selectVenue, selectStartTime, selectBoxscore, selectProbablePitchers, selectGameStatus } from '../features/games.js';
|
|
5
5
|
|
|
6
6
|
const formatPitcherName = (pitcher) => {
|
|
7
7
|
let display = pitcher.person.fullName;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React, { useEffect } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { useDispatch, useSelector } from 'react-redux';
|
|
4
|
-
import { fetchStandings, selectData } from '../features/standings';
|
|
4
|
+
import { fetchStandings, selectData } from '../features/standings.js';
|
|
5
|
+
import { teamFavoriteStar } from '../utils.js';
|
|
5
6
|
|
|
6
7
|
function formatHeaderRow(record) {
|
|
7
8
|
return record.division.nameShort.padEnd(15) +
|
|
@@ -16,7 +17,9 @@ function formatHeaderRow(record) {
|
|
|
16
17
|
|
|
17
18
|
function formatTeamRow(record) {
|
|
18
19
|
const lastTen = record.records.splitRecords.find(o => o.type === 'lastTen');
|
|
19
|
-
|
|
20
|
+
const star = teamFavoriteStar(record.team);
|
|
21
|
+
return star +
|
|
22
|
+
record.team.teamName.padEnd(star ? 13 : 15) +
|
|
20
23
|
record.wins.toString().padStart(5) +
|
|
21
24
|
record.losses.toString().padStart(5) +
|
|
22
25
|
record.winningPercentage.padStart(7) +
|
|
@@ -30,7 +33,7 @@ function Division({record, top, left, width}) {
|
|
|
30
33
|
return (
|
|
31
34
|
<box top={top} left={left} height={6} width={width}>
|
|
32
35
|
<box top={0} left={0} height={1} fg='black' bg='white' content={formatHeaderRow(record)} wrap={false} />
|
|
33
|
-
<box top={1} left={0} height={5} content={record.teamRecords.map(formatTeamRow).join('\n')} wrap={false} />
|
|
36
|
+
<box top={1} left={0} height={5} content={record.teamRecords.map(formatTeamRow).join('\n')} wrap={false} tags />
|
|
34
37
|
</box>
|
|
35
38
|
);
|
|
36
39
|
}
|