Skip to content

Commit b52329d

Browse files
committed
Fix #18
1 parent 9eabde7 commit b52329d

File tree

5 files changed

+61
-42
lines changed

5 files changed

+61
-42
lines changed

src/dom.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ParticipantResult } from 'brackets-model';
22
import { rankingHeader } from './helpers';
33
import { abbreviations } from './lang';
4-
import { Connection, FinalType, Placement, Ranking } from './types';
4+
import { Connection, FinalType, MatchLocation, Placement, Ranking } from './types';
55

66
/**
77
* Creates the title of the viewer.
@@ -237,8 +237,8 @@ export function addTeamOrigin(nameContainer: HTMLElement, text: string, placemen
237237
* @param inLowerBracket Whether the round is in lower bracket.
238238
* @param connectFinal Whether to connect to the final.
239239
*/
240-
export function getBracketConnection(roundNumber: number, roundCount: number, inLowerBracket?: boolean, connectFinal?: boolean): Connection {
241-
if (inLowerBracket) {
240+
export function getBracketConnection(roundNumber: number, roundCount: number, matchLocation?: MatchLocation, connectFinal?: boolean): Connection {
241+
if (matchLocation === 'lower-bracket') {
242242
return {
243243
connectPrevious: roundNumber > 1 && (roundNumber % 2 === 1 ? 'square' : 'straight'),
244244
connectNext: roundNumber < roundCount && (roundNumber % 2 === 0 ? 'square' : 'straight'),

src/helpers.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Match, ParticipantResult } from 'brackets-model';
2-
import { headers } from './lang';
2+
import { headers, abbreviations } from './lang';
33
import { RankingHeader, Ranking, RankingFormula, RankingItem, RankingMap } from './types';
44

55
/**
@@ -21,6 +21,16 @@ export function splitBy<T>(array: T[], key: keyof T): T[][] {
2121
return Object.values(obj);
2222
}
2323

24+
export function getOriginAbbreviation(matchLocation: string, skipFirstRound: boolean, roundNumber?: number) {
25+
if (skipFirstRound && matchLocation === 'lower-bracket' && roundNumber === 1)
26+
return abbreviations.seed;
27+
28+
if (matchLocation === 'lower-bracket' || matchLocation === 'final-group')
29+
return abbreviations.position;
30+
31+
return abbreviations.seed;
32+
}
33+
2434
/**
2535
* Indicates whether a round is major.
2636
*

src/lang.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Status } from 'brackets-model';
22
import { isMajorRound } from './helpers';
3-
import { FinalType, OriginHint, RankingHeaders } from './types';
3+
import { FinalType, MatchLocation, OriginHint, RankingHeaders } from './types';
44

55
/**
66
* Returns an origin hint function based on rounds information.
@@ -9,11 +9,11 @@ import { FinalType, OriginHint, RankingHeaders } from './types';
99
* @param roundCount Count of rounds.
1010
* @param inLowerBracket Whether the round is in lower bracket.
1111
*/
12-
export function getOriginHint(roundNumber: number, roundCount: number, inLowerBracket?: boolean): OriginHint {
13-
if (!inLowerBracket && roundNumber === 1)
12+
export function getOriginHint(roundNumber: number, roundCount: number, matchLocation?: MatchLocation): OriginHint {
13+
if (matchLocation !== 'lower-bracket' && roundNumber === 1)
1414
return (position: number) => `Seed ${position}`;
1515

16-
if (inLowerBracket && isMajorRound(roundNumber)) {
16+
if (matchLocation === 'lower-bracket' && isMajorRound(roundNumber)) {
1717
const roundNumberWB = Math.ceil((roundNumber + 1) / 2);
1818

1919
let hint = (position: number) => `Loser of WB ${roundNumberWB}.${position}`;
@@ -38,26 +38,24 @@ export function getOriginHint(roundNumber: number, roundCount: number, inLowerBr
3838
* @param roundCount Count of rounds.
3939
* @param inLowerBracket Whether the round is in lower bracket.
4040
*/
41-
export function getMatchLabel(matchNumber: number, roundNumber: number, roundCount: number, inLowerBracket?: boolean): string {
41+
export function getMatchLabel(matchNumber: number, roundNumber: number, roundCount: number, matchLocation?: MatchLocation): string {
4242
let matchPrefix = 'M';
4343

44-
if (inLowerBracket)
45-
matchPrefix = 'LB';
46-
else if (inLowerBracket === false)
44+
if (matchLocation === 'upper-bracket')
4745
matchPrefix = 'WB';
46+
else if (matchLocation === 'lower-bracket')
47+
matchPrefix = 'LB';
4848

4949
const semiFinalRound = roundNumber === roundCount - 1;
5050
const finalRound = roundNumber === roundCount;
5151

52-
let matchLabel = `${matchPrefix} ${roundNumber}.${matchNumber}`;
53-
54-
if (!inLowerBracket && semiFinalRound)
55-
matchLabel = `Semi ${matchNumber}`;
52+
if (matchLocation === 'upper-bracket' && semiFinalRound)
53+
return `${matchPrefix} Semi ${matchNumber}`;
5654

5755
if (finalRound)
58-
matchLabel = 'Final';
56+
return `${matchPrefix} Final`;
5957

60-
return matchLabel;
58+
return `${matchPrefix} ${roundNumber}.${matchNumber}`;
6159
}
6260

6361
/**

src/main.ts

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import './style.scss';
22
import { Participant, Match, MatchResults, ParticipantResult, StageType } from 'brackets-model';
3-
import { splitBy, getRanking } from './helpers';
3+
import { splitBy, getRanking, getOriginAbbreviation } from './helpers';
44
import * as dom from './dom';
55
import * as lang from './lang';
6-
import { Config, Connection, FinalType, OriginHint, RankingItem, RoundName, ViewerData } from './types';
6+
import { Config, Connection, FinalType, MatchLocation, OriginHint, RankingItem, RoundName, ViewerData } from './types';
77

88
export class BracketsViewer {
99

1010
readonly teamRefsDOM: { [participantId: number]: HTMLElement[] } = {};
1111
private participants!: Participant[];
1212
private config!: Config;
13+
private skipFirstRound!: boolean;
1314

1415
/**
1516
* Renders a stage (round-robin, single or double elimination).
@@ -29,6 +30,8 @@ export class BracketsViewer {
2930
highlightParticipantOnHover: config && config.highlightParticipantOnHover !== undefined ? config.highlightParticipantOnHover : true,
3031
};
3132

33+
this.skipFirstRound = data.stage.settings.skipFirstRound || false;
34+
3235
this.participants = data.participants;
3336
data.participants.forEach(participant => this.teamRefsDOM[participant.id] = []);
3437

@@ -141,6 +144,7 @@ export class BracketsViewer {
141144
* @param connectFinal Whether to connect the last match of the bracket to the final.
142145
*/
143146
private renderBracket(root: HTMLElement, matchesByRound: Match[][], roundName: RoundName, inLowerBracket?: boolean, connectFinal?: boolean): void {
147+
const matchLocation = inLowerBracket ? 'lower-bracket' : 'upper-bracket';
144148
const bracketContainer = dom.createBracketContainer();
145149
const roundCount = matchesByRound.length;
146150

@@ -150,7 +154,7 @@ export class BracketsViewer {
150154
const roundContainer = dom.createRoundContainer(roundName(roundNumber, roundCount));
151155

152156
for (const match of matches)
153-
roundContainer.append(this.createBracketMatch(roundNumber, roundCount, match, inLowerBracket, connectFinal));
157+
roundContainer.append(this.createBracketMatch(roundNumber, roundCount, match, matchLocation, connectFinal));
154158

155159
bracketContainer.append(roundContainer);
156160
roundNumber++;
@@ -233,14 +237,13 @@ export class BracketsViewer {
233237
* @param roundNumber Number of the round.
234238
* @param roundCount Count of rounds.
235239
* @param match Information about the match.
236-
* @param inLowerBracket Whether the match is in lower bracket.
237240
* @param connectFinal Whether to connect this match to the final if it happens to be the last one of the bracket.
238241
*/
239-
private createBracketMatch(roundNumber: number, roundCount: number, match: Match, inLowerBracket?: boolean, connectFinal?: boolean): HTMLElement {
240-
const connection = dom.getBracketConnection(roundNumber, roundCount, inLowerBracket, connectFinal);
241-
const matchLabel = lang.getMatchLabel(match.number, roundNumber, roundCount, inLowerBracket);
242-
const originHint = lang.getOriginHint(roundNumber, roundCount, inLowerBracket);
243-
return this.createMatch(match, connection, matchLabel, originHint, inLowerBracket);
242+
private createBracketMatch(roundNumber: number, roundCount: number, match: Match, matchLocation?: MatchLocation, connectFinal?: boolean): HTMLElement {
243+
const connection = dom.getBracketConnection(roundNumber, roundCount, matchLocation, connectFinal);
244+
const matchLabel = lang.getMatchLabel(match.number, roundNumber, roundCount, matchLocation);
245+
const originHint = lang.getOriginHint(roundNumber, roundCount, matchLocation);
246+
return this.createMatch(match, connection, matchLabel, originHint, matchLocation, roundNumber);
244247
}
245248

246249
/**
@@ -256,7 +259,7 @@ export class BracketsViewer {
256259
const connection = dom.getFinalConnection(type, roundNumber, matches.length);
257260
const matchLabel = lang.getFinalMatchLabel(type, roundNumber, roundCount);
258261
const originHint = lang.getFinalOriginHint(type, roundNumber);
259-
return this.createMatch(matches[roundIndex], connection, matchLabel, originHint);
262+
return this.createMatch(matches[roundIndex], connection, matchLabel, originHint, 'final-group');
260263
}
261264

262265
/**
@@ -268,14 +271,14 @@ export class BracketsViewer {
268271
* @param originHint Origin hint for the match.
269272
* @param inLowerBracket Whether the match is in lower bracket.
270273
*/
271-
private createMatch(results: MatchResults, connection?: Connection, label?: string, originHint?: OriginHint, inLowerBracket?: boolean): HTMLElement {
272-
inLowerBracket = inLowerBracket || false;
274+
private createMatch(results: MatchResults, connection?: Connection, label?: string, originHint?: OriginHint, matchLocation?: MatchLocation, roundNumber?: number): HTMLElement {
275+
matchLocation = matchLocation || 'upper-bracket';
273276

274277
const match = dom.createMatchContainer();
275278
const opponents = dom.createOpponentsContainer();
276279

277-
const team1 = this.createTeam(results.opponent1, originHint, inLowerBracket);
278-
const team2 = this.createTeam(results.opponent2, originHint, inLowerBracket);
280+
const team1 = this.createTeam(results.opponent1, originHint, matchLocation, roundNumber);
281+
const team2 = this.createTeam(results.opponent2, originHint, matchLocation, roundNumber);
279282

280283
if (label)
281284
opponents.append(dom.createMatchLabel(label, lang.getMatchStatus(results.status)));
@@ -298,15 +301,15 @@ export class BracketsViewer {
298301
* @param originHint Origin hint for the match.
299302
* @param inLowerBracket Whether the match is in lower bracket.
300303
*/
301-
private createTeam(participant: ParticipantResult | null, originHint: OriginHint, inLowerBracket: boolean): HTMLElement {
304+
private createTeam(participant: ParticipantResult | null, originHint: OriginHint, matchLocation: MatchLocation, roundNumber?: number): HTMLElement {
302305
const participantContainer = dom.createParticipantContainer();
303306
const nameContainer = dom.createNameContainer();
304307
const resultContainer = dom.createResultContainer();
305308

306309
if (participant === null)
307310
nameContainer.innerText = 'BYE';
308311
else
309-
this.renderParticipant(participantContainer, nameContainer, resultContainer, participant, originHint, inLowerBracket);
312+
this.renderParticipant(participantContainer, nameContainer, resultContainer, participant, originHint, matchLocation, roundNumber);
310313

311314
participantContainer.append(nameContainer, resultContainer);
312315

@@ -316,6 +319,8 @@ export class BracketsViewer {
316319
return participantContainer;
317320
}
318321

322+
// TODO: group containers into an object
323+
319324
/**
320325
* Renders a participant.
321326
*
@@ -326,14 +331,14 @@ export class BracketsViewer {
326331
* @param originHint Origin hint for the match.
327332
* @param inLowerBracket Whether the match is in lower bracket.
328333
*/
329-
private renderParticipant(participantContainer: HTMLElement, nameContainer: HTMLElement, resultContainer: HTMLElement, participant: ParticipantResult, originHint: OriginHint, inLowerBracket: boolean): void {
334+
private renderParticipant(participantContainer: HTMLElement, nameContainer: HTMLElement, resultContainer: HTMLElement, participant: ParticipantResult, originHint: OriginHint, matchLocation: MatchLocation, roundNumber?: number): void {
330335
const found = this.participants.find(item => item.id === participant.id);
331336

332337
if (found) {
333338
nameContainer.innerText = found.name;
334-
this.renderTeamOrigin(nameContainer, participant, inLowerBracket);
339+
this.renderTeamOrigin(nameContainer, participant, matchLocation, roundNumber);
335340
} else
336-
this.renderHint(nameContainer, participant, originHint, inLowerBracket);
341+
this.renderHint(nameContainer, participant, originHint, matchLocation);
337342

338343
resultContainer.innerText = `${participant.score || '-'}`;
339344

@@ -349,10 +354,10 @@ export class BracketsViewer {
349354
* @param originHint Origin hint for the participant.
350355
* @param inLowerBracket Whether the match is in lower bracket.
351356
*/
352-
private renderHint(nameContainer: HTMLElement, participant: ParticipantResult, originHint: OriginHint, inLowerBracket: boolean): void {
357+
private renderHint(nameContainer: HTMLElement, participant: ParticipantResult, originHint: OriginHint, matchLocation: MatchLocation): void {
353358
if (originHint === undefined || participant.position === undefined) return;
354359
if (!this.config.showSlotsOrigin) return;
355-
if (!this.config.showLowerBracketSlotsOrigin && inLowerBracket) return;
360+
if (!this.config.showLowerBracketSlotsOrigin && matchLocation === 'lower-bracket') return;
356361

357362
dom.setupHint(nameContainer, originHint(participant.position));
358363
}
@@ -364,13 +369,14 @@ export class BracketsViewer {
364369
* @param participant The participant result.
365370
* @param inLowerBracket Whether the match is in lower bracket.
366371
*/
367-
private renderTeamOrigin(nameContainer: HTMLElement, participant: ParticipantResult, inLowerBracket: boolean): void {
372+
private renderTeamOrigin(nameContainer: HTMLElement, participant: ParticipantResult, matchLocation: MatchLocation, roundNumber?: number): void {
368373
if (participant.position === undefined) return;
369374
if (this.config.participantOriginPlacement === 'none') return;
370375
if (!this.config.showSlotsOrigin) return;
371-
if (!this.config.showLowerBracketSlotsOrigin && inLowerBracket) return;
376+
if (!this.config.showLowerBracketSlotsOrigin && matchLocation === 'lower-bracket') return;
372377

373-
const origin = (inLowerBracket ? lang.abbreviations.position : lang.abbreviations.seed) + participant.position;
378+
const abbreviation = getOriginAbbreviation(matchLocation, this.skipFirstRound, roundNumber);
379+
const origin = abbreviation + participant.position;
374380
dom.addTeamOrigin(nameContainer, origin, this.config.participantOriginPlacement);
375381
}
376382

src/types.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ export type ConnectionType = 'square' | 'straight' | false;
6767
*/
6868
export type FinalType = 'consolation_final' | 'grand_final';
6969

70+
/**
71+
* The possible locations of a match.
72+
*/
73+
export type MatchLocation = 'upper-bracket' | 'lower-bracket' | 'final-group';
74+
7075
/**
7176
* A function returning an origin hint based on a participant's position.
7277
*/

0 commit comments

Comments
 (0)