mirror of
https://github.com/artemkorsakov/project-euler-stats.git
synced 2026-07-22 05:42:55 +00:00
Add compact view
This commit is contained in:
parent
656dd7b506
commit
a2c77e59d5
8 changed files with 155 additions and 88 deletions
|
|
@ -30,7 +30,7 @@ function createAwardTableRow(award: AwardData): HTMLElement {
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAwardTable(awardData: AwardBlockData): HTMLElement {
|
function createAwardTable(awardData: AwardBlockData, useShortFormat: boolean): HTMLElement {
|
||||||
const table = document.createElement('table');
|
const table = document.createElement('table');
|
||||||
const tableBody = document.createElement('tbody');
|
const tableBody = document.createElement('tbody');
|
||||||
|
|
||||||
|
|
@ -42,17 +42,30 @@ function createAwardTable(awardData: AwardBlockData): HTMLElement {
|
||||||
});
|
});
|
||||||
tableBody.appendChild(headerRow);
|
tableBody.appendChild(headerRow);
|
||||||
|
|
||||||
awardData.awards.forEach(award => {
|
const sortedAwards =
|
||||||
if (!award.isCompleted) {
|
awardData.awards
|
||||||
|
.filter(award => !award.isCompleted)
|
||||||
|
.map(award => ({
|
||||||
|
award,
|
||||||
|
members: parseInt(award.members.replace(/\D/g, '')) || 0
|
||||||
|
}))
|
||||||
|
.sort((a, b) => b.members - a.members)
|
||||||
|
|
||||||
|
if (useShortFormat) {
|
||||||
|
sortedAwards.slice(0, 3).forEach(({ award }) => {
|
||||||
tableBody.appendChild(createAwardTableRow(award));
|
tableBody.appendChild(createAwardTableRow(award));
|
||||||
}
|
});
|
||||||
});
|
} else {
|
||||||
|
sortedAwards.forEach(({ award }) => {
|
||||||
|
tableBody.appendChild(createAwardTableRow(award));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
table.appendChild(tableBody);
|
table.appendChild(tableBody);
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAwardBlock(awardData: AwardBlockData): HTMLElement {
|
function createAwardBlock(awardData: AwardBlockData, useShortFormat: boolean): HTMLElement {
|
||||||
const awardBlock = document.createElement('div');
|
const awardBlock = document.createElement('div');
|
||||||
|
|
||||||
const awardName = document.createElement('h3');
|
const awardName = document.createElement('h3');
|
||||||
|
|
@ -62,15 +75,17 @@ function createAwardBlock(awardData: AwardBlockData): HTMLElement {
|
||||||
const completed = awardData.getCompletedCount();
|
const completed = awardData.getCompletedCount();
|
||||||
const total = awardData.awards.length;
|
const total = awardData.awards.length;
|
||||||
|
|
||||||
const completedStatus = document.createElement('h4');
|
if (!useShortFormat) {
|
||||||
completedStatus.textContent = `Status: Won ${completed} out of ${total}`;
|
const completedStatus = document.createElement('h4');
|
||||||
awardBlock.appendChild(completedStatus);
|
completedStatus.textContent = `Status: Won ${completed} out of ${total}`;
|
||||||
|
awardBlock.appendChild(completedStatus);
|
||||||
|
|
||||||
const uncompletedStatus = document.createElement('h4');
|
const uncompletedStatus = document.createElement('h4');
|
||||||
uncompletedStatus.textContent = `Uncompleted awards: ${total - completed}`;
|
uncompletedStatus.textContent = `Uncompleted awards: ${total - completed}`;
|
||||||
awardBlock.appendChild(uncompletedStatus);
|
awardBlock.appendChild(uncompletedStatus);
|
||||||
|
}
|
||||||
|
|
||||||
awardBlock.appendChild(createAwardTable(awardData));
|
awardBlock.appendChild(createAwardTable(awardData, useShortFormat));
|
||||||
|
|
||||||
return awardBlock;
|
return awardBlock;
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +95,7 @@ function createAwardBlock(awardData: AwardBlockData): HTMLElement {
|
||||||
* @param awardsData - The awards data.
|
* @param awardsData - The awards data.
|
||||||
* @returns The generated HTMLElement (awards table container).
|
* @returns The generated HTMLElement (awards table container).
|
||||||
*/
|
*/
|
||||||
export function generateAwardsTableHTML(awardsData: AwardBlockData[]): HTMLElement {
|
export function generateAwardsTableHTML(awardsData: AwardBlockData[], useShortFormat: boolean): HTMLElement {
|
||||||
const awardsContainer = document.createElement('div');
|
const awardsContainer = document.createElement('div');
|
||||||
|
|
||||||
const awardsHeader = document.createElement('h2');
|
const awardsHeader = document.createElement('h2');
|
||||||
|
|
@ -88,7 +103,7 @@ export function generateAwardsTableHTML(awardsData: AwardBlockData[]): HTMLEleme
|
||||||
awardsContainer.appendChild(awardsHeader);
|
awardsContainer.appendChild(awardsHeader);
|
||||||
|
|
||||||
awardsData.forEach(awardData => {
|
awardsData.forEach(awardData => {
|
||||||
awardsContainer.appendChild(createAwardBlock(awardData));
|
awardsContainer.appendChild(createAwardBlock(awardData, useShortFormat));
|
||||||
});
|
});
|
||||||
|
|
||||||
return awardsContainer;
|
return awardsContainer;
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,14 @@ const keepAliveName = 'keep_alive';
|
||||||
* @param source - The source data for generating HTML.
|
* @param source - The source data for generating HTML.
|
||||||
* @returns A Promise that resolves to an HTMLElement.
|
* @returns A Promise that resolves to an HTMLElement.
|
||||||
*/
|
*/
|
||||||
export async function fetchProgress(session: string, keep_alive: string, source: Source): Promise<HTMLElement> {
|
export async function fetchProgress(session: string, keep_alive: string, source: Source, useShortFormat: boolean): Promise<HTMLElement> {
|
||||||
// Attempt to load cached data from the file
|
// Attempt to load cached data from the file
|
||||||
const filePath = await getFilePath();
|
const filePath = await getFilePath();
|
||||||
const savedData = await loadDataFromFile(filePath);
|
const savedData = await loadDataFromFile(filePath);
|
||||||
|
|
||||||
// If cached data exists, generate and return HTML from it
|
// If cached data exists, generate and return HTML from it
|
||||||
if (savedData) {
|
if (savedData) {
|
||||||
return generateHTML(savedData, source);
|
return generateHTML(savedData, source, useShortFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no cached data is available, try to fetch fresh data from the server
|
// If no cached data is available, try to fetch fresh data from the server
|
||||||
|
|
@ -54,7 +54,7 @@ export async function fetchProgress(session: string, keep_alive: string, source:
|
||||||
|
|
||||||
// If fetching fresh data is successful, generate and return HTML from it
|
// If fetching fresh data is successful, generate and return HTML from it
|
||||||
if (fetchedData) {
|
if (fetchedData) {
|
||||||
return generateHTML(fetchedData, source);
|
return generateHTML(fetchedData, source, useShortFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If neither cached nor fresh data is available, create an error message
|
// If neither cached nor fresh data is available, create an error message
|
||||||
|
|
@ -137,34 +137,36 @@ async function fetchAwardsData(cookies: string): Promise<AwardBlockData[]> {
|
||||||
return parseAwardsData(myAwardsHtml, awardsHtml);
|
return parseAwardsData(myAwardsHtml, awardsHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateHTML(cache: CacheData, source: Source): HTMLElement {
|
function generateHTML(cache: CacheData, source: Source, useShortFormat: boolean): HTMLElement {
|
||||||
const container = document.createElement('div');
|
const container = document.createElement('div');
|
||||||
|
|
||||||
const profileElement = generateProfileHTML(cache.accountData, cache.progressData);
|
const profileElement = generateProfileHTML(cache.accountData, cache.progressData, useShortFormat);
|
||||||
container.appendChild(profileElement);
|
container.appendChild(profileElement);
|
||||||
|
|
||||||
const imageElement = generateImageHTML(cache.accountData.account);
|
if (!useShortFormat) {
|
||||||
container.appendChild(imageElement);
|
const imageElement = generateImageHTML(cache.accountData.account);
|
||||||
|
container.appendChild(imageElement);
|
||||||
|
}
|
||||||
|
|
||||||
const progressElement = generateProgressTableHTML(cache);
|
const progressElement = generateProgressTableHTML(cache, useShortFormat);
|
||||||
container.appendChild(progressElement);
|
container.appendChild(progressElement);
|
||||||
|
|
||||||
const tasksElement = generateTasksTableHTML(cache, source);
|
const tasksElement = generateTasksTableHTML(cache, source);
|
||||||
container.appendChild(tasksElement);
|
container.appendChild(tasksElement);
|
||||||
|
|
||||||
const locationRatingElement = generateRatingTableHTML(cache.locationUrl, cache.accountData.location, cache.progressData.solved, cache.locationRating);
|
const locationRatingElement = generateRatingTableHTML(cache.locationUrl, cache.accountData.location, cache.progressData.solved, cache.locationRating, useShortFormat);
|
||||||
container.appendChild(locationRatingElement);
|
container.appendChild(locationRatingElement);
|
||||||
|
|
||||||
const languageRatingElement = generateRatingTableHTML(cache.languageUrl, cache.accountData.language, cache.progressData.solved, cache.languageRating);
|
const languageRatingElement = generateRatingTableHTML(cache.languageUrl, cache.accountData.language, cache.progressData.solved, cache.languageRating, useShortFormat);
|
||||||
container.appendChild(languageRatingElement);
|
container.appendChild(languageRatingElement);
|
||||||
|
|
||||||
const levelsElement = generateLevelsTableHTML(cache.progressData, cache.levelDataArray);
|
const levelsElement = generateLevelsTableHTML(cache.progressData, cache.levelDataArray, useShortFormat);
|
||||||
container.appendChild(levelsElement);
|
container.appendChild(levelsElement);
|
||||||
|
|
||||||
const awardsElement = generateAwardsTableHTML(cache.awardsData);
|
const awardsElement = generateAwardsTableHTML(cache.awardsData, useShortFormat);
|
||||||
container.appendChild(awardsElement);
|
container.appendChild(awardsElement);
|
||||||
|
|
||||||
const friendsElement = generateFriendsHTML(cache.friends, cache.accountData);
|
const friendsElement = generateFriendsHTML(cache.friends, cache.accountData, useShortFormat);
|
||||||
container.appendChild(friendsElement);
|
container.appendChild(friendsElement);
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ function createFriendTableRow(friend: FriendData, myAccount: FriendData, account
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createFriendsTable(friends: FriendData[], myAccount: FriendData, accountData: AccountData): HTMLElement {
|
function createFriendsTable(friends: FriendData[], myAccount: FriendData, accountData: AccountData, useShortFormat: boolean): HTMLElement {
|
||||||
const table = document.createElement('table');
|
const table = document.createElement('table');
|
||||||
const tableBody = document.createElement('tbody');
|
const tableBody = document.createElement('tbody');
|
||||||
|
|
||||||
|
|
@ -64,9 +64,15 @@ function createFriendsTable(friends: FriendData[], myAccount: FriendData, accoun
|
||||||
});
|
});
|
||||||
tableBody.appendChild(headerRow);
|
tableBody.appendChild(headerRow);
|
||||||
|
|
||||||
friends.forEach(friend => {
|
if (useShortFormat) {
|
||||||
tableBody.appendChild(createFriendTableRow(friend, myAccount, accountData));
|
friends.slice(0, 3).forEach(friend => {
|
||||||
});
|
tableBody.appendChild(createFriendTableRow(friend, myAccount, accountData));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
friends.forEach(friend => {
|
||||||
|
tableBody.appendChild(createFriendTableRow(friend, myAccount, accountData));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
table.appendChild(tableBody);
|
table.appendChild(tableBody);
|
||||||
return table;
|
return table;
|
||||||
|
|
@ -78,11 +84,11 @@ function createFriendsTable(friends: FriendData[], myAccount: FriendData, accoun
|
||||||
* @param accountData - The account data.
|
* @param accountData - The account data.
|
||||||
* @returns The generated HTMLElement (friends table container).
|
* @returns The generated HTMLElement (friends table container).
|
||||||
*/
|
*/
|
||||||
export function generateFriendsHTML(friends: FriendData[], accountData: AccountData): HTMLElement {
|
export function generateFriendsHTML(friends: FriendData[], accountData: AccountData, useShortFormat: boolean): HTMLElement {
|
||||||
const friendsContainer = document.createElement('div');
|
const friendsContainer = document.createElement('div');
|
||||||
friendsContainer.appendChild(createSectionHeader('Friends'));
|
friendsContainer.appendChild(createSectionHeader('Friends'));
|
||||||
const myAccount = friends.find(friend => friend.username === accountData.alias) ?? new FriendData('-', accountData.alias, 0, 0, 0);
|
const myAccount = friends.find(friend => friend.username === accountData.alias) ?? new FriendData('-', accountData.alias, 0, 0, 0);
|
||||||
friendsContainer.appendChild(createFriendsTable(friends, myAccount, accountData));
|
friendsContainer.appendChild(createFriendsTable(friends, myAccount, accountData, useShortFormat));
|
||||||
|
|
||||||
return friendsContainer;
|
return friendsContainer;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ function createLevelTableRow(levelData: LevelData, progressData: ProgressData):
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLevelsTable(progressData: ProgressData, levelDataArray: LevelData[]): HTMLElement {
|
function createLevelsTable(progressData: ProgressData, levelDataArray: LevelData[], useShortFormat: boolean): HTMLElement {
|
||||||
const table = document.createElement('table');
|
const table = document.createElement('table');
|
||||||
const tableBody = document.createElement('tbody');
|
const tableBody = document.createElement('tbody');
|
||||||
|
|
||||||
|
|
@ -41,9 +41,15 @@ function createLevelsTable(progressData: ProgressData, levelDataArray: LevelData
|
||||||
});
|
});
|
||||||
tableBody.appendChild(headerRow);
|
tableBody.appendChild(headerRow);
|
||||||
|
|
||||||
levelDataArray.forEach(levelData => {
|
if (useShortFormat) {
|
||||||
tableBody.appendChild(createLevelTableRow(levelData, progressData));
|
levelDataArray.slice(0, 3).forEach(levelData => {
|
||||||
});
|
tableBody.appendChild(createLevelTableRow(levelData, progressData));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
levelDataArray.forEach(levelData => {
|
||||||
|
tableBody.appendChild(createLevelTableRow(levelData, progressData));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
table.appendChild(tableBody);
|
table.appendChild(tableBody);
|
||||||
return table;
|
return table;
|
||||||
|
|
@ -62,7 +68,7 @@ function calculateTotalMembers(levelDataArray: LevelData[]): number {
|
||||||
* @param levelDataArray - The array of level data.
|
* @param levelDataArray - The array of level data.
|
||||||
* @returns The generated HTMLElement (levels table container).
|
* @returns The generated HTMLElement (levels table container).
|
||||||
*/
|
*/
|
||||||
export function generateLevelsTableHTML(progressData: ProgressData, levelDataArray: LevelData[]): HTMLElement {
|
export function generateLevelsTableHTML(progressData: ProgressData, levelDataArray: LevelData[], useShortFormat: boolean): HTMLElement {
|
||||||
const level = stringToNumber(progressData.level);
|
const level = stringToNumber(progressData.level);
|
||||||
|
|
||||||
const levelsContainer = document.createElement('div');
|
const levelsContainer = document.createElement('div');
|
||||||
|
|
@ -75,12 +81,15 @@ export function generateLevelsTableHTML(progressData: ProgressData, levelDataArr
|
||||||
|
|
||||||
const slicedArray = levelDataArray.slice(level - 1);
|
const slicedArray = levelDataArray.slice(level - 1);
|
||||||
levelsContainer.appendChild(createSectionHeader('Level progress'));
|
levelsContainer.appendChild(createSectionHeader('Level progress'));
|
||||||
levelsContainer.appendChild(createSectionHeader(`Current level: ${progressData.level}`, 'h4'));
|
|
||||||
levelsContainer.appendChild(createSectionHeader(`Solved problems: ${progressData.solved}`, 'h5'));
|
|
||||||
const allMembers = calculateTotalMembers(slicedArray);
|
|
||||||
levelsContainer.appendChild(createSectionHeader(`Status: ${allMembers} members have made it this far.`, 'h5'));
|
|
||||||
|
|
||||||
levelsContainer.appendChild(createLevelsTable(progressData, slicedArray));
|
if (!useShortFormat) {
|
||||||
|
levelsContainer.appendChild(createSectionHeader(`Current level: ${progressData.level}`, 'h4'));
|
||||||
|
levelsContainer.appendChild(createSectionHeader(`Solved problems: ${progressData.solved}`, 'h5'));
|
||||||
|
const allMembers = calculateTotalMembers(slicedArray);
|
||||||
|
levelsContainer.appendChild(createSectionHeader(`Status: ${allMembers} members have made it this far.`, 'h5'));
|
||||||
|
}
|
||||||
|
|
||||||
|
levelsContainer.appendChild(createLevelsTable(progressData, slicedArray, useShortFormat));
|
||||||
|
|
||||||
return levelsContainer;
|
return levelsContainer;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,40 @@ import { AccountData, ProgressData } from './types';
|
||||||
* @param progressData - The progress data.
|
* @param progressData - The progress data.
|
||||||
* @returns The generated HTMLElement.
|
* @returns The generated HTMLElement.
|
||||||
*/
|
*/
|
||||||
export function generateProfileHTML(accountData: AccountData, progressData: ProgressData): HTMLElement {
|
export function generateProfileHTML(accountData: AccountData, progressData: ProgressData, useShortFormat: boolean): HTMLElement {
|
||||||
const profileContainer = document.createElement('div');
|
const profileContainer = document.createElement('div');
|
||||||
|
|
||||||
const profileHeader = document.createElement('h2');
|
const profileHeader = document.createElement('h2');
|
||||||
profileHeader.textContent = 'Profile';
|
profileHeader.textContent = 'Profile';
|
||||||
profileContainer.appendChild(profileHeader);
|
profileContainer.appendChild(profileHeader);
|
||||||
|
|
||||||
|
if (useShortFormat) {
|
||||||
|
const profileTable = generateCompactProfileBlock(accountData, progressData);
|
||||||
|
profileContainer.appendChild(profileTable);
|
||||||
|
} else {
|
||||||
|
const profileTable = generateProfileTable(accountData, progressData);
|
||||||
|
profileContainer.appendChild(profileTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return profileContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates HTML for the profile image.
|
||||||
|
* @param account - The account name.
|
||||||
|
* @returns The generated HTMLElement (img element).
|
||||||
|
*/
|
||||||
|
export function generateImageHTML(account: string): HTMLElement {
|
||||||
|
const imageElement = document.createElement('img');
|
||||||
|
|
||||||
|
imageElement.src = `https://projecteuler.net/profile/${account}.png`;
|
||||||
|
imageElement.alt = `Profile ${account}`;
|
||||||
|
imageElement.title = account;
|
||||||
|
|
||||||
|
return imageElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateProfileTable(accountData: AccountData, progressData: ProgressData): HTMLElement {
|
||||||
const profileTable = document.createElement('table');
|
const profileTable = document.createElement('table');
|
||||||
profileTable.className = 'profile-table';
|
profileTable.className = 'profile-table';
|
||||||
|
|
||||||
|
|
@ -39,22 +66,12 @@ export function generateProfileHTML(accountData: AccountData, progressData: Prog
|
||||||
addRow('Solved', progressData.solved);
|
addRow('Solved', progressData.solved);
|
||||||
|
|
||||||
profileTable.appendChild(tableBody);
|
profileTable.appendChild(tableBody);
|
||||||
profileContainer.appendChild(profileTable);
|
|
||||||
|
|
||||||
return profileContainer;
|
return profileTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function generateCompactProfileBlock(accountData: AccountData, progressData: ProgressData): HTMLElement {
|
||||||
* Generates HTML for the profile image.
|
const profileBlock = document.createElement('div');
|
||||||
* @param account - The account name.
|
profileBlock.textContent = `${accountData.alias} (${accountData.account}), ${accountData.location}, ${accountData.language}, ${progressData.level}, ${progressData.solved} solved`;
|
||||||
* @returns The generated HTMLElement (img element).
|
return profileBlock;
|
||||||
*/
|
|
||||||
export function generateImageHTML(account: string): HTMLElement {
|
|
||||||
const imageElement = document.createElement('img');
|
|
||||||
|
|
||||||
imageElement.src = `https://projecteuler.net/profile/${account}.png`;
|
|
||||||
imageElement.alt = `Profile ${account}`;
|
|
||||||
imageElement.title = account;
|
|
||||||
|
|
||||||
return imageElement;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,10 +99,12 @@ function createProgressTable(
|
||||||
* @param cache - The cache data.
|
* @param cache - The cache data.
|
||||||
* @returns The generated HTMLElement (progress table container).
|
* @returns The generated HTMLElement (progress table container).
|
||||||
*/
|
*/
|
||||||
export function generateProgressTableHTML(cache: CacheData): HTMLElement {
|
export function generateProgressTableHTML(cache: CacheData, useShortFormat: boolean): HTMLElement {
|
||||||
const progressContainer = document.createElement('div');
|
const progressContainer = document.createElement('div');
|
||||||
progressContainer.appendChild(createSectionHeader('Progress'));
|
progressContainer.appendChild(createSectionHeader('Progress'));
|
||||||
progressContainer.appendChild(createProgressBar(cache.progressData.percentage));
|
if (!useShortFormat) {
|
||||||
|
progressContainer.appendChild(createProgressBar(cache.progressData.percentage));
|
||||||
|
}
|
||||||
progressContainer.appendChild(createProgressTable(
|
progressContainer.appendChild(createProgressTable(
|
||||||
cache.progressData,
|
cache.progressData,
|
||||||
cache.euleriansPlace,
|
cache.euleriansPlace,
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,11 @@ function createTableRow(label: string, solvedCount: number, remaining: number):
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRatingTable(solved: number, rating: RatingData): HTMLElement {
|
function createRatingTable(solved: number, rating: RatingData, useShortFormat: boolean): HTMLElement {
|
||||||
const table = document.createElement('table');
|
const table = document.createElement('table');
|
||||||
const tableBody = document.createElement('tbody');
|
const tableBody = document.createElement('tbody');
|
||||||
|
|
||||||
|
// Create table header
|
||||||
const headerRow = document.createElement('tr');
|
const headerRow = document.createElement('tr');
|
||||||
['Competition', 'Solved', 'Remaining'].forEach(headerText => {
|
['Competition', 'Solved', 'Remaining'].forEach(headerText => {
|
||||||
const headerCell = document.createElement('th');
|
const headerCell = document.createElement('th');
|
||||||
|
|
@ -29,24 +30,25 @@ function createRatingTable(solved: number, rating: RatingData): HTMLElement {
|
||||||
});
|
});
|
||||||
tableBody.appendChild(headerRow);
|
tableBody.appendChild(headerRow);
|
||||||
|
|
||||||
if (rating.place > 100) {
|
// Define rating tiers with their display conditions
|
||||||
tableBody.appendChild(createTableRow('Top 100', rating.top100, rating.top100 - solved + 1));
|
const ratingTiers = [
|
||||||
}
|
{ name: 'Top 100', value: rating.top100, showCondition: rating.place > 100 },
|
||||||
if (rating.place > 50) {
|
{ name: 'Top 50', value: rating.top50, showCondition: rating.place > 50 },
|
||||||
tableBody.appendChild(createTableRow('Top 50', rating.top50, rating.top50 - solved + 1));
|
{ name: 'Top 25', value: rating.top25, showCondition: rating.place > 25 },
|
||||||
}
|
{ name: 'Top 10', value: rating.top10, showCondition: rating.place > 10 },
|
||||||
if (rating.place > 25) {
|
{ name: 'Top 5', value: rating.top5, showCondition: rating.place > 5 },
|
||||||
tableBody.appendChild(createTableRow('Top 25', rating.top25, rating.top25 - solved + 1));
|
{ name: 'Top 1', value: rating.top1, showCondition: rating.place >= 1 }
|
||||||
}
|
];
|
||||||
if (rating.place > 10) {
|
|
||||||
tableBody.appendChild(createTableRow('Top 10', rating.top10, rating.top10 - solved + 1));
|
// Filter tiers based on current position and format preference
|
||||||
}
|
const visibleTiers = ratingTiers.filter(tier => tier.showCondition);
|
||||||
if (rating.place > 5) {
|
const tiersToShow = useShortFormat ? visibleTiers.slice(0, 3) : visibleTiers;
|
||||||
tableBody.appendChild(createTableRow('Top 5', rating.top5, rating.top5 - solved + 1));
|
|
||||||
}
|
// Add rows for each visible tier
|
||||||
if (rating.place >= 1) {
|
tiersToShow.forEach(tier => {
|
||||||
tableBody.appendChild(createTableRow('Top 1', rating.top1, rating.top1 - solved + 1));
|
const remaining = tier.value - solved + 1;
|
||||||
}
|
tableBody.appendChild(createTableRow(tier.name, tier.value, remaining));
|
||||||
|
});
|
||||||
|
|
||||||
table.appendChild(tableBody);
|
table.appendChild(tableBody);
|
||||||
return table;
|
return table;
|
||||||
|
|
@ -59,7 +61,7 @@ function createRatingTable(solved: number, rating: RatingData): HTMLElement {
|
||||||
* @param rating - The rating data.
|
* @param rating - The rating data.
|
||||||
* @returns The generated HTMLElement (rating table container).
|
* @returns The generated HTMLElement (rating table container).
|
||||||
*/
|
*/
|
||||||
export function generateRatingTableHTML(url: string, title: string, solved: number, rating: RatingData): HTMLElement {
|
export function generateRatingTableHTML(url: string, title: string, solved: number, rating: RatingData, useShortFormat: boolean): HTMLElement {
|
||||||
const ratingContainer = document.createElement('div');
|
const ratingContainer = document.createElement('div');
|
||||||
|
|
||||||
// Header with link
|
// Header with link
|
||||||
|
|
@ -72,10 +74,12 @@ export function generateRatingTableHTML(url: string, title: string, solved: numb
|
||||||
header.appendChild(link);
|
header.appendChild(link);
|
||||||
ratingContainer.appendChild(header);
|
ratingContainer.appendChild(header);
|
||||||
|
|
||||||
const place = rating.place > 100 ? 'You are not in the Top 100' : rating.place.toString();
|
if (!useShortFormat) {
|
||||||
ratingContainer.appendChild(createSectionHeader(`Current place: ${place}`, 'h4'));
|
const place = rating.place > 100 ? 'You are not in the Top 100' : rating.place.toString();
|
||||||
ratingContainer.appendChild(createSectionHeader(`Solved problems: ${solved}`, 'h5'));
|
ratingContainer.appendChild(createSectionHeader(`Current place: ${place}`, 'h4'));
|
||||||
ratingContainer.appendChild(createRatingTable(solved, rating));
|
ratingContainer.appendChild(createSectionHeader(`Solved problems: ${solved}`, 'h5'));
|
||||||
|
}
|
||||||
|
ratingContainer.appendChild(createRatingTable(solved, rating, useShortFormat));
|
||||||
|
|
||||||
return ratingContainer;
|
return ratingContainer;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
main.ts
16
main.ts
|
|
@ -12,7 +12,7 @@ export default class ProjectEulerStatsPlugin extends Plugin {
|
||||||
|
|
||||||
this.registerMarkdownCodeBlockProcessor('euler-stats', async (source, el, ctx) => {
|
this.registerMarkdownCodeBlockProcessor('euler-stats', async (source, el, ctx) => {
|
||||||
const extractedSource = extractSources(source);
|
const extractedSource = extractSources(source);
|
||||||
const stats = await fetchProgress(this.settings.session_id, this.settings.keep_alive, extractedSource);
|
const stats = await fetchProgress(this.settings.session_id, this.settings.keep_alive, extractedSource, this.settings.use_short_format);
|
||||||
const container = el.createEl('div');
|
const container = el.createEl('div');
|
||||||
container.appendChild(stats);
|
container.appendChild(stats);
|
||||||
});
|
});
|
||||||
|
|
@ -49,11 +49,13 @@ export default class ProjectEulerStatsPlugin extends Plugin {
|
||||||
export interface ProjectEulerStatsSettings {
|
export interface ProjectEulerStatsSettings {
|
||||||
session_id: string;
|
session_id: string;
|
||||||
keep_alive: string;
|
keep_alive: string;
|
||||||
|
use_short_format: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_SETTINGS: ProjectEulerStatsSettings = {
|
export const DEFAULT_SETTINGS: ProjectEulerStatsSettings = {
|
||||||
session_id: '',
|
session_id: '',
|
||||||
keep_alive: ''
|
keep_alive: '',
|
||||||
|
use_short_format: false
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProjectEulerStatsSettingTab extends PluginSettingTab {
|
export class ProjectEulerStatsSettingTab extends PluginSettingTab {
|
||||||
|
|
@ -90,5 +92,15 @@ export class ProjectEulerStatsSettingTab extends PluginSettingTab {
|
||||||
this.plugin.settings.keep_alive = value;
|
this.plugin.settings.keep_alive = value;
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName('Use compact format')
|
||||||
|
.setDesc('Enable to display data in a compact view')
|
||||||
|
.addToggle(toggle => toggle
|
||||||
|
.setValue(this.plugin.settings.use_short_format)
|
||||||
|
.onChange(async (value) => {
|
||||||
|
this.plugin.settings.use_short_format = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue