diff --git a/CHANGELOG.md b/CHANGELOG.md
index 75bf11859..06592c552 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file.
+## [1.2.17] - 2022-04-13
+
+### Fixed
+
+- Brackets now account for two week per round leagues [issue #97](https://github.com/nmelhado/league-page/issues/97)
+
## [1.2.16] - 2022-01-06
### Fixed
diff --git a/package-lock.json b/package-lock.json
index 0cb96dd87..89b99606c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,11 @@
{
"name": "league-page",
- "version": "1.2.16",
+ "version": "1.2.17",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "league-page",
- "version": "1.2.16",
+ "version": "1.2.17",
"license": "MIT",
"dependencies": {
"@smui/button": "6.0.0-beta.13",
diff --git a/package.json b/package.json
index 4dceb6282..0cefc8550 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "league-page",
- "version": "1.2.16",
+ "version": "1.2.17",
"homepage": "https://github.com/nmelhado/league-page",
"repository": {
"type": "git",
diff --git a/src/lib/Matchups/Brackets.svelte b/src/lib/Matchups/Brackets.svelte
index 30cc7447f..3779a097b 100644
--- a/src/lib/Matchups/Brackets.svelte
+++ b/src/lib/Matchups/Brackets.svelte
@@ -1,6 +1,7 @@
@@ -84,6 +91,13 @@
padding: 2em 0;
margin-bottom: 2em;
}
+
+ .buttonHolder {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin: 3em 0;
+ }
@@ -104,6 +118,20 @@
{#if matchup}
-
+ {#if matchup[0].starters[2] }
+
+
+
+
+
+
+
+
+ {/if}
+
{/if}
\ No newline at end of file
diff --git a/src/lib/Matchups/BracketsColumn.svelte b/src/lib/Matchups/BracketsColumn.svelte
index ba7b207c7..ffb1753ab 100644
--- a/src/lib/Matchups/BracketsColumn.svelte
+++ b/src/lib/Matchups/BracketsColumn.svelte
@@ -101,20 +101,30 @@
return '';
}
- const calculatePoints = (points) => {
- if(!points) return 0;
+ const calculatePoints = (allPoints) => {
let totalPoints = 0;
- for(const point of points) {
- totalPoints += point;
+ for(const k in allPoints) {
+ const points = allPoints[k];
+ if(!points) break;
+ for(const point of points) {
+ totalPoints += point;
+ }
}
return round(totalPoints)
}
- const calculatePotentialPoints = (starters, ix, p) => {
- if(!starters) return 0;
+ const calculatePotentialPoints = (startersWeeks, ix, p) => {
+ if(!startersWeeks) return 0;
let totalPoints = 0;
- for(const starter of starters) {
- totalPoints += parseFloat(players[starter]?.wi && players[starter].wi[playoffsStart - ix]?.p ? players[starter].wi[playoffsStart - ix].p : 0);
+
+ for(const k in startersWeeks) {
+ const starters = startersWeeks[k];
+ if(!starters) break;
+
+ const i = ix + k -1;
+ for(const starter of starters) {
+ totalPoints += parseFloat(players[starter]?.wi && players[starter].wi[playoffsStart - i]?.p ? players[starter].wi[playoffsStart - i].p : 0);
+ }
}
return round(totalPoints);
}
@@ -242,13 +252,13 @@
line-height: 1.1em;
font-size: 0.85em;
padding-left: 1em;
- color: #333;
+ color: var(--g333);
text-align: right;
}
.projectedPoints {
font-size: 0.8em;
- color: #888;
+ color: var(--g999);
}
/* SVG styling */
diff --git a/src/lib/Matchups/Matchup.svelte b/src/lib/Matchups/Matchup.svelte
index 62e7c08fa..37d24f302 100644
--- a/src/lib/Matchups/Matchup.svelte
+++ b/src/lib/Matchups/Matchup.svelte
@@ -1,7 +1,7 @@
diff --git a/src/lib/utils/helperFunctions/leagueBrackets.js b/src/lib/utils/helperFunctions/leagueBrackets.js
index cece15110..75305297c 100644
--- a/src/lib/utils/helperFunctions/leagueBrackets.js
+++ b/src/lib/utils/helperFunctions/leagueBrackets.js
@@ -7,29 +7,51 @@ import { get } from 'svelte/store';
import {brackets} from '$lib/stores';
export const getBrackets = async () => {
- if(get(brackets).champs) {
- return get(brackets);
- }
+ if(get(brackets).champs) {
+ return get(brackets);
+ }
// get roster, user, and league data
- const [rosterRes, users, leagueData] = await waitForAll(
- getLeagueRosters(),
- getLeagueUsers(),
- getLeagueData(),
- ).catch((err) => { console.error(err); });
+ const [rosterRes, users, leagueData] = await waitForAll(
+ getLeagueRosters(),
+ getLeagueUsers(),
+ getLeagueData(),
+ ).catch((err) => { console.error(err); });
- const rosters = rosterRes.rosters;
+ const rosters = rosterRes.rosters;
// Number of rosters (in order to determine the number of places, i.e. 1st - 12th)
const numRosters = rosters.length;
// get bracket data for winners and losers
- const bracketsAndMatchupFetches = [
+ const bracketsAndMatchupFetches = [
fetch(`https://api.sleeper.app/v1/league/${leagueID}/winners_bracket`, {compress: true}),
fetch(`https://api.sleeper.app/v1/league/${leagueID}/losers_bracket`, {compress: true}),
]
- const playoffsStart = leagueData.settings.playoff_week_start;
+ // variables for playoff records
+ // let numPOTeams = parseInt(leagueData.settings.playoff_teams);
+ let playoffType;
+ const year = parseInt(leagueData.season);
+ // let playoffCase; // for determining relevant (ie. PO bracket) matches
+ const playoffsStart = parseInt(leagueData.settings.playoff_week_start);
+
+ // before 2020, 1 week/round was only option; in 2020, 2 weeks/rounds added; in 2021, 1 week/round + 2 champ
+ // 0: 1 week per round
+ // 1: 1 week per round + 2 champ
+ // 2: 2 weeks per round
+ if(year > 2019) {
+ playoffType = parseInt(leagueData.settings.playoff_round_type);
+ } else {
+ playoffType = 0;
+ }
+
+ // in 2020 type 1 was 2 weeks per round, this was later changed to type 2
+ if(year == 2020) {
+ if(playoffType == 1) playoffType++;
+ }
+
+ // const playoffLength = getPlayoffLength(playoffType, numPOTeams)
// add each week after the regular season to the fetch array
for(let i = playoffsStart; i < 19; i++) {
@@ -57,18 +79,17 @@ export const getBrackets = async () => {
// The second element above was the winners bracket, so remove that, the remaining items are matchup weeks
const losersData = playoffMatchups.shift();
-
// determine the length of the playoffs by looking at the last bracket
- const playoffRounds = winnersData[winnersData.length - 1].r;
- const loserRounds = losersData[losersData.length - 1].r;
+ const playoffRounds = winnersData[winnersData.length - 1].r;
+ const loserRounds = losersData[losersData.length - 1].r;
// champBracket is an object where the key will be the round number
// the value at each key will be an array of matchups
- const champs = evaluateBracket(winnersData, playoffRounds, playoffMatchups, rosters, users);
+ const champs = evaluateBracket(winnersData, playoffRounds, playoffMatchups, rosters, users, playoffType);
// champBracket is an object where the key will be the round number
// the value at each key will be an array of matchups
- let losers = evaluateBracket(losersData, loserRounds, playoffMatchups, rosters, users);
+ let losers = evaluateBracket(losersData, loserRounds, playoffMatchups, rosters, users, playoffType);
const finalBrackets = {
numRosters,
@@ -79,18 +100,20 @@ export const getBrackets = async () => {
losers,
}
- brackets.update(() => finalBrackets);
+ brackets.update(() => finalBrackets);
- return finalBrackets;
+ return finalBrackets;
}
-const evaluateBracket = (contestants, rounds, playoffMatchups, rosters, users) => {
+const evaluateBracket = (contestants, rounds, playoffMatchups, rosters, users, playoffType) => {
let bracket = [];
let consolations = [];
// which matches in the previous round were consolation matches
let consolationMs = [];
// which matches in the previous round came from matches where they were winners
let fromWs = [];
+ // teams seen
+ let teamsSeen = {};
for(let i = 1; i <= rounds; i++) {
const playoffBrackets = contestants.filter(m => m.r == i);
const roundMatchups = [];
@@ -99,9 +122,9 @@ const evaluateBracket = (contestants, rounds, playoffMatchups, rosters, users) =
const localConsolationMs = [];
let localFromWs = [];
for(const playoffBracket of playoffBrackets) {
- if(!playoffBracket.t1_from && playoffBracket.t2_from) {
+ if((!playoffBracket.t1_from && playoffBracket.t2_from) || (!teamsSeen[playoffBracket.t1] && teamsSeen[playoffBracket.t2])) {
// this was from a team that got a bye
- let byeMatchup = processPlayoffMatchup(playoffBracket, playoffMatchups[i - 2], rosters, users, consolationMs, fromWs);
+ let byeMatchup = processPlayoffMatchup({playoffBracket, playoffMatchups, i: i - 2, rosters, users, consolationMs, fromWs, playoffType, teamsSeen});
byeMatchup.bye = true;
byeMatchup[0].m = null;
byeMatchup[1].m = null;
@@ -116,7 +139,9 @@ const evaluateBracket = (contestants, rounds, playoffMatchups, rosters, users) =
bracket[i - 2].push(byeMatchup);
}
}
- const roundMatchup = processPlayoffMatchup(playoffBracket, playoffMatchups[i - 1], rosters, users, consolationMs, fromWs);
+ teamsSeen[playoffBracket.t1] = playoffBracket.m;
+ teamsSeen[playoffBracket.t2] = playoffBracket.m;
+ const roundMatchup = processPlayoffMatchup({playoffBracket, playoffMatchups, i: i - 1, rosters, users, consolationMs, fromWs, playoffType, teamsSeen});
if(roundMatchup[0].winners) {
// This matchup came from winners
localFromWs.push(roundMatchup[0].m)
@@ -134,7 +159,7 @@ const evaluateBracket = (contestants, rounds, playoffMatchups, rosters, users) =
for(const consolation of consolations) {
for(const consolationMatchup of consolationMatchups) {
// if this matchup originated from winners, then it is a continuation of a previous consolation match
- if(consolationMatchup[0].winners && consolation[i-2] && consolationMatchup[0].t1From == consolation[i-2][0][0].m) {
+ if(consolationMatchup[0].winners && consolation[i-2] && consolation[i-2] && consolationMatchup[0].t1From == consolation[i-2][0][0].m) {
consolation[i-1] = [consolationMatchup];
}
}
@@ -154,124 +179,99 @@ const evaluateBracket = (contestants, rounds, playoffMatchups, rosters, users) =
}
const newConsolation = (consolationMatchups, rounds, i) => {
- const newConsolation = new Array(rounds).fill([]);
- newConsolation[i - 1] = consolationMatchups;
- return newConsolation;
+ const newCons = new Array(rounds).fill([]);
+ newCons[i - 1] = consolationMatchups;
+ return newCons;
}
-const processPlayoffMatchup = (bracket, matchups, rosters, users, consolationMs, fromWs) => {
+const processPlayoffMatchup = ({playoffBracket, playoffMatchups, i, rosters, users, consolationMs, fromWs, playoffType, teamsSeen}) => {
const matchup = [];
- const m = bracket.m;
- const r = bracket.r;
- const t1From = bracket.t1_from?.w ? bracket.t1_from?.w : bracket.t1_from?.l;
- const t2From = bracket.t2_from?.w ? bracket.t2_from?.w : bracket.t2_from?.l;
- const winners = bracket.t1_from?.w && bracket.t2_from?.w ? true : false;
+ const m = playoffBracket.m;
+ const r = playoffBracket.r;
+ const p = playoffBracket.p;
+ const t1From = teamsSeen[playoffBracket.t1];
+ const t2From = teamsSeen[playoffBracket.t2];
+ const winners = playoffBracket.t1_from?.w && playoffBracket.t2_from?.w ? true : false;
const fromWinners = fromWs.indexOf(t2From || -999) > -1 ? true : false;
let consolation = false;
- if((bracket.t1_from?.l && bracket.t2_from?.l) || consolationMs.indexOf(t1From) > -1 || consolationMs.indexOf(t2From) > -1) {
+ if((p && p != 1) || (playoffBracket.t1_from?.l && playoffBracket.t2_from?.l) || consolationMs.indexOf(t1From) > -1 || consolationMs.indexOf(t2From) > -1) {
consolation = true;
}
// first team in matchup
- const t1 = bracket.t1;
- if(t1) {
- const t1user = users[rosters[t1 - 1].owner_id];
- const t1Matchup = matchups.filter(m => m.roster_id == t1)[0]
-
- if(t1user) {
- matchup.push({
- manager: {
- name: t1user.metadata.team_name ? t1user.metadata.team_name : t1user.display_name,
- avatar: `https://sleepercdn.com/avatars/thumbs/${t1user.avatar}`,
- },
- starters: t1Matchup?.starters,
- points: t1Matchup?.starters_points,
- t1From,
- m,
- r,
- winners,
- fromWinners,
- consolation
- })
- } else {
- matchup.push({
- manager: {
- name: 'Unknown Manager',
- avatar: `https://sleepercdn.com/images/v2/icons/player_default.webp`,
- },
- starters: t1Matchup?.starters,
- points: t1Matchup?.starters_points,
- t1From,
- m,
- r,
- winners,
- fromWinners,
- consolation
- })
- }
-
- } else {
- matchup.push({
- manager: null,
- consolation,
- t1From,
- m,
- r,
- winners,
- fromWinners,
- });
- }
+ const t1 = playoffBracket.t1;
+ matchup.push(generateMatchupData(t1, t1From, {m, r, playoffMatchups, i, rosters, users, playoffType, winners, fromWinners, consolation, p}));
// second team in matchup
- const t2 = bracket.t2;
- if(t2) {
- const t2user = users[rosters[t2 - 1].owner_id];
- const t2Matchup = matchups.filter(m => m.roster_id == t2)[0]
-
- if(t2user) {
- matchup.push({
- manager: {
- name: t2user.metadata.team_name ? t2user.metadata.team_name : t2user.display_name,
- avatar: `https://sleepercdn.com/avatars/thumbs/${t2user.avatar}`,
- },
- starters: t2Matchup?.starters,
- points: t2Matchup?.starters_points,
- t2From,
- m,
- r,
- winners,
- fromWinners,
- consolation
- })
- } else {
- matchup.push({
- manager: {
- name: 'Unknown Manager',
- avatar: `https://sleepercdn.com/images/v2/icons/player_default.webp`,
- },
- starters: t2Matchup?.starters,
- points: t2Matchup?.starters_points,
- t2From,
- m,
- r,
- winners,
- fromWinners,
- consolation
- })
- }
+ const t2 = playoffBracket.t2;
+ matchup.push(generateMatchupData(t2, t2From, {m, r, playoffMatchups, i, rosters, users, playoffType, winners, fromWinners, consolation, p}));
- } else {
- matchup.push({
- manager: null,
- consolation,
- t2From,
- winners,
- fromWinners,
- r,
- m,
- });
+ return matchup;
+}
+
+const generateMatchupData = (t, tFrom, {m, r, playoffMatchups, i, rosters, users, playoffType, winners, fromWinners, consolation, p}) => {
+ let matchup = {
+ manager: null,
+ points: undefined,
+ starters: undefined,
+ consolation,
+ tFrom,
+ m,
+ r,
+ winners,
+ fromWinners,
}
- return matchup;
-}
\ No newline at end of file
+
+ if(t) {
+ const tuser = users[rosters[t - 1].owner_id];
+ const tMatchup = playoffMatchups[i].filter(ma => ma.roster_id == t)[0];
+ let tMatchupStarters = {}
+ tMatchupStarters[1] = tMatchup?.starters;
+ const tMatchupStartersPoints = {};
+ tMatchupStartersPoints[1] = tMatchup?.starters_points;
+ // playoffType 2: 2 weeks per round
+ // playoffType 1: 1 weeks per round, 2 in championship round
+ if(playoffType == 2 || (p && p == 1 && playoffType == 1)) {
+ const secondWeek = playoffMatchups[i+1].filter(ma => ma.roster_id == t)[0];
+ tMatchupStarters[2] = secondWeek?.starters;
+ tMatchupStartersPoints[2] = secondWeek?.starters_points;
+ }
+
+ matchup.starters = tMatchupStarters;
+ matchup.points = tMatchupStartersPoints;
+
+ if(tuser) {
+ matchup.manager = {
+ name: tuser.metadata.team_name ? tuser.metadata.team_name : tuser.display_name,
+ avatar: `https://sleepercdn.com/avatars/thumbs/${tuser.avatar}`,
+ };
+ } else {
+ matchup.manager = {
+ name: 'Unknown Manager',
+ avatar: `https://sleepercdn.com/images/v2/icons/player_default.webp`,
+ };
+ }
+ }
+
+ return matchup;
+}
+
+const getPlayoffLength = (playoffType, numPOTeams) => {
+ let playoffLength = 3;
+
+ if(numPOTeams == 4) {
+ return playoffLength--;
+ }
+
+ if(playoffType == 1) {
+ return playoffLength++;
+ }
+
+ if(playoffType == 2) {
+ return playoffLength *= 2;
+ }
+
+ return playoffLength
+}
diff --git a/src/lib/version.js b/src/lib/version.js
index 840f41ca6..323e9adc1 100644
--- a/src/lib/version.js
+++ b/src/lib/version.js
@@ -5,4 +5,4 @@ available for your copy of League Page
*/
// Keep in sync with package.json
-export const version = "1.2.16";
+export const version = "1.2.17";
diff --git a/src/theme/_smui-theme.scss b/src/theme/_smui-theme.scss
index 3a1715d21..e4e623357 100644
--- a/src/theme/_smui-theme.scss
+++ b/src/theme/_smui-theme.scss
@@ -58,7 +58,7 @@
--draftSwapped: #f8fcff;
--waiverAdd: #e9fff1;
--waiverDrop: #ffe9e9;
- --bracketMatch: #f7fdff;
+ --bracketMatch: #fafeff;
--matchupSelected: #fff;
--fadeOne: rgba(255, 255, 255, 0) 0%;
--fadeTwo: rgba(255, 255, 255, 0.7) 50%;
diff --git a/src/theme/dark/_smui-theme.scss b/src/theme/dark/_smui-theme.scss
index 96ba7ca47..b15b635e6 100644
--- a/src/theme/dark/_smui-theme.scss
+++ b/src/theme/dark/_smui-theme.scss
@@ -58,7 +58,7 @@
--draftSwapped: #202025;
--waiverAdd: #3e4741;
--waiverDrop: #423a3a;
- --bracketMatch: #0b0b0c;
+ --bracketMatch: #010102;
--matchupSelected: #2f2f35;
--fadeOne: rgba(0, 0, 0, 0) 0%;
--fadeTwo: rgba(0, 0, 0, 0.7) 50%;