Skip to content

Commit a3506b4

Browse files
authored
Merge pull request #34 from AlecM33/savant-multiple-results
Savant multiple results
2 parents bc107c6 + e6dc6aa commit a3506b4

File tree

3 files changed

+170
-98
lines changed

3 files changed

+170
-98
lines changed

config/globals.js

+88-58
Original file line numberDiff line numberDiff line change
@@ -102,182 +102,212 @@ module.exports = {
102102
{
103103
"id": 133,
104104
"name": "Athletics",
105-
primaryColor: "#003831",
106-
secondaryColor: "#EFB21E"
105+
"primaryColor": "#003831",
106+
"secondaryColor": "#EFB21E",
107+
"abbreviation": "OAK"
107108
},
108109
{
109110
"id": 134,
110111
"name": "Pirates",
111-
primaryColor: "#FDB827",
112-
secondaryColor: "#27251F"
112+
"primaryColor": "#FDB827",
113+
"secondaryColor": "#27251F",
114+
"abbreviation": "PIT"
113115
},
114116
{
115117
"id": 135,
116118
"name": "Padres",
117-
primaryColor: "#2F241D",
118-
secondaryColor: "#FFC425"
119+
"primaryColor": "#2F241D",
120+
"secondaryColor": "#FFC425",
121+
"abbreviation": "SD"
119122
},
120123
{
121124
"id": 136,
122125
"name": "Mariners",
123-
primaryColor: "#005C5C",
124-
secondaryColor: "#0C2C56"
126+
"primaryColor": "#005C5C",
127+
"secondaryColor": "#0C2C56",
128+
"abbreviation": "SEA"
125129
},
126130
{
127131
"id": 137,
128132
"name": "Giants",
129-
primaryColor: "#FD5A1E",
130-
secondaryColor: "#27251F"
133+
"primaryColor": "#FD5A1E",
134+
"secondaryColor": "#27251F",
135+
"abbreviation": "SF"
131136
},
132137
{
133138
"id": 138,
134139
"name": "Cardinals",
135-
primaryColor: "#C41E3A",
136-
secondaryColor: "#0C2340"
140+
"primaryColor": "#C41E3A",
141+
"secondaryColor": "#0C2340",
142+
"abbreviation": "STL"
137143
},
138144
{
139145
"id": 139,
140146
"name": "Rays",
141-
primaryColor: "#8FBCE6",
142-
secondaryColor: "#092C5C"
147+
"primaryColor": "#8FBCE6",
148+
"secondaryColor": "#092C5C",
149+
"abbreviation": "TB"
143150
},
144151
{
145152
"id": 140,
146153
"name": "Rangers",
147-
primaryColor: "#003278",
148-
secondaryColor: "#C0111F"
154+
"primaryColor": "#003278",
155+
"secondaryColor": "#C0111F",
156+
"abbreviation": "TEX"
149157
},
150158
{
151159
"id": 141,
152160
"name": "Blue Jays",
153-
primaryColor: "#134A8E",
154-
secondaryColor: "#1D2D5C"
161+
"primaryColor": "#134A8E",
162+
"secondaryColor": "#1D2D5C",
163+
"abbreviation": "TOR"
155164
},
156165
{
157166
"id": 142,
158167
"name": "Twins",
159-
primaryColor: "#002B5C",
160-
secondaryColor: "#D31145"
168+
"primaryColor": "#002B5C",
169+
"secondaryColor": "#D31145",
170+
"abbreviation": "MIN"
161171
},
162172
{
163173
"id": 143,
164174
"name": "Phillies",
165-
primaryColor: "#E81828",
166-
secondaryColor: "#002D72"
175+
"primaryColor": "#E81828",
176+
"secondaryColor": "#002D72",
177+
"abbreviation": "PHI"
167178
},
168179
{
169180
"id": 144,
170181
"name": "Braves",
171182
"primaryColor": "#CE1141",
172-
secondaryColor: "#13274F"
183+
"secondaryColor": "#13274F",
184+
"abbreviation": "ATL"
173185
},
174186
{
175187
"id": 145,
176188
"name": "White Sox",
177-
primaryColor: "#27251F",
178-
secondaryColor: "#C4CED4"
189+
"primaryColor": "#27251F",
190+
"secondaryColor": "#C4CED4",
191+
"abbreviation": "CWS"
179192
},
180193
{
181194
"id": 146,
182195
"name": "Marlins",
183-
primaryColor: "#00A3E0",
184-
secondaryColor: "#EF3340",
196+
"primaryColor": "#00A3E0",
197+
"secondaryColor": "#EF3340",
198+
"abbreviation": "MIA"
185199
},
186200
{
187201
"id": 147,
188202
"name": "Yankees",
189-
primaryColor: "#C4CED3",
190-
secondaryColor: "#0C2340"
203+
"primaryColor": "#C4CED3",
204+
"secondaryColor": "#0C2340",
205+
"abbreviation": "NYY"
191206
},
192207
{
193208
"id": 158,
194209
"name": "Brewers",
195-
primaryColor: "#FFC52F",
196-
secondaryColor: "#12284B"
210+
"primaryColor": "#FFC52F",
211+
"secondaryColor": "#12284B",
212+
"abbreviation": "MIL"
197213
},
198214
{
199215
"id": 108,
200216
"name": "Angels",
201-
primaryColor: "#BA0021",
202-
secondaryColor: "#003263"
217+
"primaryColor": "#BA0021",
218+
"secondaryColor": "#003263",
219+
"abbreviation": "LAA"
203220
},
204221
{
205222
"id": 109,
206223
"name": "D-backs",
207224
"primaryColor": "#A71930",
208-
"secondaryColor": "#E3D4AD"
225+
"secondaryColor": "#E3D4AD",
226+
"abbreviation": "AZ"
209227
},
210228
{
211229
"id": 110,
212230
"name": "Orioles",
213-
primaryColor: "#DF4601",
214-
secondaryColor: "#000000"
231+
"primaryColor": "#DF4601",
232+
"secondaryColor": "#000000",
233+
"abbreviation": "BAL"
215234
},
216235
{
217236
"id": 111,
218237
"name": "Red Sox",
219-
primaryColor: "#BD3039",
220-
secondaryColor: "#0C2340"
238+
"primaryColor": "#BD3039",
239+
"secondaryColor": "#0C2340",
240+
"abbreviation": "BOS"
221241
},
222242
{
223243
"id": 112,
224244
"name": "Cubs",
225-
primaryColor: "#0E3386",
226-
secondaryColor: "#CC3433"
245+
"primaryColor": "#0E3386",
246+
"secondaryColor": "#CC3433",
247+
"abbreviation": "CHC"
227248
},
228249
{
229250
"id": 113,
230251
"name": "Reds",
231-
primaryColor: "#C6011F",
232-
secondaryColor: "#000000"
252+
"primaryColor": "#C6011F",
253+
"secondaryColor": "#000000",
254+
"abbreviation": "CIN"
233255
},
234256
{
235257
"id": 114,
236258
"name": "Guardians",
237-
primaryColor: "#E50022",
238-
secondaryColor: "#00385D"
259+
"primaryColor": "#E50022",
260+
"secondaryColor": "#00385D",
261+
"abbreviation": "CLE"
239262
},
240263
{
241264
"id": 115,
242265
"name": "Rockies",
243-
primaryColor: "#333366",
244-
secondaryColor: "#C4CED4"
266+
"primaryColor": "#333366",
267+
"secondaryColor": "#C4CED4",
268+
"abbreviation": "COL"
245269
},
246270
{
247271
"id": 116,
248272
"name": "Tigers",
249-
primaryColor: "#0C2340",
250-
secondaryColor: "#FA4616"
273+
"primaryColor": "#0C2340",
274+
"secondaryColor": "#FA4616",
275+
"abbreviation": "DET"
251276
},
252277
{
253278
"id": 117,
254279
"name": "Astros",
255-
primaryColor: "#002D62",
256-
secondaryColor: "#EB6E1F"
280+
"primaryColor": "#002D62",
281+
"secondaryColor": "#EB6E1F",
282+
"abbreviation": "HOU"
257283
},
258284
{
259285
"id": 118,
260286
"name": "Royals",
261-
primaryColor: "#004687",
262-
secondaryColor: "#BD9B60"
287+
"primaryColor": "#004687",
288+
"secondaryColor": "#BD9B60",
289+
"abbreviation": "KC"
263290
},
264291
{
265292
"id": 119,
266293
"name": "Dodgers",
267-
primaryColor: "#005A9C",
268-
secondaryColor: "#EF3E42"
294+
"primaryColor": "#005A9C",
295+
"secondaryColor": "#EF3E42",
296+
"abbreviation": "LAD"
269297
},
270298
{
271299
"id": 120,
272300
"name": "Nationals",
273-
primaryColor: "#AB0003",
274-
secondaryColor: "#14225A"
301+
"primaryColor": "#AB0003",
302+
"secondaryColor": "#14225A",
303+
"abbreviation": "WSH"
275304
},
276305
{
277306
"id": 121,
278307
"name": "Mets",
279-
primaryColor: "#002D72",
280-
secondaryColor: "#FF5910"
308+
"primaryColor": "#002D72",
309+
"secondaryColor": "#FF5910",
310+
"abbreviation": "NYM"
281311
}
282312
],
283313
HELP_MESSAGE: '`/starters` - examine the starting pitching matchup for the upcoming game.\n'

modules/command-util.js

+58-24
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,29 @@ module.exports = {
562562
}
563563
},
564564

565+
resolvePlayerSelection: async (players, interaction) => {
566+
const buttons = players.map(player =>
567+
new ButtonBuilder()
568+
.setCustomId(player.id.toString())
569+
.setLabel(`${player.fullName} (${globals.TEAMS.find(team => team.id === player.currentTeam.id)?.abbreviation})`)
570+
.setStyle(ButtonStyle.Primary)
571+
);
572+
const response = await interaction.followUp({
573+
content: 'I found multiple matches. Which one?',
574+
components: [new ActionRowBuilder().addComponents(buttons)]
575+
});
576+
const collectorFilter = i => i.user.id === interaction.user.id;
577+
try {
578+
LOGGER.trace('awaiting');
579+
return await response.awaitMessageComponent({ filter: collectorFilter, time: 20_000 });
580+
} catch (e) {
581+
await interaction.editReply({
582+
content: 'Player selection not received within 20 seconds - request was canceled.',
583+
components: []
584+
});
585+
}
586+
},
587+
565588
giveFinalCommandResponse: async (toHandle, options) => {
566589
await (globalCache.values.game.isDoubleHeader
567590
? toHandle.update(options)
@@ -671,28 +694,32 @@ module.exports = {
671694
liveFeed.gameData.teams.home.abbreviation + ' ' + homeScore + '**');
672695
},
673696

674-
getClosestPlayer: async (playerName, type) => {
697+
getClosestPlayers: async (playerName, type) => {
675698
const startTime = performance.now();
676699
const allPlayers = await mlbAPIUtil.players();
677700
const removeDiacritics = (str) => str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
678701
const normalizedPlayerName = removeDiacritics(playerName.toLowerCase());
679-
let matchingPlayer;
702+
let matchingPlayers = [];
680703
let smallestDistance = Infinity;
681704
allPlayers.people.forEach(p => {
682705
const currentName = removeDiacritics(`${p.fullName}`.toLowerCase());
683706
const distance = levenshtein(currentName, normalizedPlayerName);
684-
if (distance < smallestDistance
707+
if (distance <= smallestDistance
685708
&& (
686709
(type === 'Pitcher' && p.primaryPosition.name === 'Pitcher')
687710
|| (type === 'Batter' && p.primaryPosition.name !== 'Pitcher')
688711
)) {
689-
matchingPlayer = p;
690-
smallestDistance = distance;
712+
if (distance < smallestDistance) {
713+
matchingPlayers = [p];
714+
smallestDistance = distance;
715+
} else {
716+
matchingPlayers.push(p);
717+
}
691718
}
692719
});
693720
const endTime = performance.now();
694721
LOGGER.trace(`Savant command - getting closest player took ${endTime - startTime} milliseconds.`);
695-
return matchingPlayer;
722+
return matchingPlayers;
696723
},
697724

698725
getPitcherEmbed: (pitcher, pitcherInfo, isLiveGame, description, savantMode = false) => {
@@ -791,32 +818,39 @@ module.exports = {
791818
}
792819
},
793820

794-
getBatterFromUserInputOrLiveFeed: async (playerName) => {
795-
let batter, currentLiveFeed;
821+
getPlayerFromUserInputOrLiveFeed: async (playerName, interaction, type) => {
822+
let player, currentLiveFeed, shouldEditReply, pendingChoice;
796823
if (playerName) {
797-
batter = await module.exports.getClosestPlayer(playerName, 'Batter');
798-
} else {
799-
currentLiveFeed = globalCache.values.game.currentLiveFeed;
800-
if (currentLiveFeed && currentLiveFeed.gameData.status.abstractGameState === 'Live') {
801-
batter = currentLiveFeed.liveData.plays.currentPlay.matchup.batter;
824+
const players = await module.exports.getClosestPlayers(playerName, type);
825+
if (players.length > 1) {
826+
pendingChoice = await module.exports.resolvePlayerSelection(players.slice(0, 5), interaction);
827+
const idString = pendingChoice?.customId;
828+
if (idString) {
829+
player = players.find(player => player.id === parseInt(idString));
830+
await pendingChoice.deferUpdate(); // This function says it takes reply options, but it doesn't work?? So I've resorted to editing on the next line.
831+
await interaction.editReply({
832+
content: `Getting stats for ${player.fullName} (${globals.TEAMS.find(team => team.id === player.currentTeam.id)?.abbreviation}). Please wait...`,
833+
components: []
834+
});
835+
shouldEditReply = true;
836+
}
837+
} else {
838+
player = players[0];
802839
}
803-
}
804-
805-
return batter;
806-
},
807-
808-
getPitcherFromUserInputOrLiveFeed: async (playerName) => {
809-
let batter, currentLiveFeed;
810-
if (playerName) {
811-
batter = await module.exports.getClosestPlayer(playerName, 'Pitcher');
812840
} else {
813841
currentLiveFeed = globalCache.values.game.currentLiveFeed;
814842
if (currentLiveFeed && currentLiveFeed.gameData.status.abstractGameState === 'Live') {
815-
batter = currentLiveFeed.liveData.plays.currentPlay.matchup.pitcher;
843+
player = type === 'Pitcher'
844+
? currentLiveFeed.liveData.plays.currentPlay.matchup.pitcher
845+
: currentLiveFeed.liveData.plays.currentPlay.matchup.batter;
816846
}
817847
}
818848

819-
return batter;
849+
return {
850+
player,
851+
pendingChoice,
852+
shouldEditReply
853+
};
820854
}
821855
};
822856

0 commit comments

Comments
 (0)