Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add custom theme support #188

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

zetaloop
Copy link

@zetaloop zetaloop commented Jun 13, 2024

Add custom theme support to the cards.

Here are the new query parameters that can be used to customize the theme of the cards:
title_color, text_color, bg_color, border_color, icon_color, chart_color

The custom color will override the color of the selected theme.
For example, use theme=dark&bg_color=00000000 as dark theme with a transparent background.

Resolve:

#110 - Custom theme
#152 - Custom background color

Example:

https://github-profile-summary-cards.vercel.app/api/cards/productive-time?username=vn7n24fzkq&title_color=ff0&text_color=0ff&bg_color=665544&border_color=f0f&icon_color=1234ff&chart_color=ff4321a0

image

Summary by CodeRabbit

  • New Features

    • Introduced support for custom theme colors across various card types, including most commit language, productive time, profile details, repos per language, and stats.
  • Enhancements

    • Added new query parameters for customizing title, text, background, border, icon, and chart colors.
    • Created and integrated custom theme objects based on user-defined color parameters for card generation.
  • Bug Fixes

    • Ensured validation for new custom color parameters to maintain data integrity.

Copy link

coderabbitai bot commented Jun 13, 2024

Walkthrough

The recent changes introduce support for customizable theme colors across multiple API endpoints and card generation functions. New query parameters allow users to specify colors for titles, text, backgrounds, borders, icons, and charts. This information is utilized to generate custom Theme objects, which are then passed to the related SVG generation functions, enhancing the visual customization capabilities of the service.

Changes

Files/Paths Change Summaries
api/.../most-commit-language.ts Added query parameters for custom colors and modified theme handling to use customTheme object.
api/.../productive-time.ts Added custom theme parameters and updated theme creation and handling to generate customTheme object.
api/.../profile-details.ts Introduced new color parameters and created customTheme object for enhanced SVG card generation.
api/.../repos-per-language.ts Implemented parameters for theme customization and generated customTheme for use in SVG functions.
api/.../stats.ts Added custom theme query parameters and updated corresponding theme usage to include customTheme object.
src/.../most-commit-language-card.ts Updated functions to accept and handle customTheme parameter to support theme customization.
src/.../productive-time-card.ts Enhanced SVG generation functions to accept customTheme parameter and update theme settings accordingly.
src/.../profile-details-card.ts Modified function signatures and logic to include customTheme for custom SVG theme settings.
src/.../repos-per-language-card.ts Added customTheme parameter to SVG generation functions to allow custom theme settings.
src/.../stats-card.ts Modified createStatsCard and SVG functions to include customTheme handling for custom theme settings.

Poem

In the world of code, a change takes flight,
Custom themes bring colors, oh so bright. 🌈
Each card now dons a hue unique,
With borders and charts, a visual tweak.
Celebrate this leap with hops of joy,
CodeRabbit’s delight - design we deploy! 🎨🐰


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Outside diff range and nitpick comments (9)
api/cards/stats.ts (1)

Line range hint 4-64: Refactor repeated type checks to a utility function for cleaner code.

+ function validateParameter(param, paramName, res) {
+     if (typeof param !== 'string') {
+         res.status(400).send(`${paramName} must be a string`);
+         return false;
+     }
+     return true;
+ }

-    if (typeof theme !== 'string') {
+    if (!validateParameter(theme, 'theme', res)) {
-        res.status(400).send('theme must be a string');
-        return;
-    }
...
api/cards/profile-details.ts (1)

Line range hint 4-64: Refactor repeated type checks to a utility function for cleaner code, similar to the suggestion in stats.ts.

api/cards/productive-time.ts (1)

Line range hint 4-69: Refactor repeated type checks to a utility function for cleaner code, similar to the suggestion in stats.ts.

src/cards/most-commit-language-card.ts (1)

Line range hint 26-59: Consider converting this function expression to an arrow function to reduce complexity and improve readability.

- const getCommitsLanguageSVG = function (
+ const getCommitsLanguageSVG = (
    langData: {name: string; value: number; color: string}[],
    themeName: string,
    customTheme: Theme | undefined
): string => {
Tools
GitHub Check: lint

[failure] 48-48:
'theme' is never reassigned. Use 'const' instead


[failure] 48-48:
Replace ·...ThemeMap.get(themeName)!· with ...ThemeMap.get(themeName)!


[failure] 50-50:
Replace "#" with '#'


[failure] 51-51:
Replace "#" with '#'


[failure] 52-52:
Replace "#" with '#'


[failure] 53-53:
Replace ·theme.stroke·=·"#"·+·customTheme.stroke;·theme.strokeOpacity·=·1; with ⏎············theme.stroke·=·'#'·+·customTheme.stroke;⏎············theme.strokeOpacity·=·1;⏎·······


[failure] 54-54:
Replace "#" with '#'


[failure] 55-55:
Replace "#" with '#'

api/cards/repos-per-language.ts (1)

Line range hint 67-69: Consider using an arrow function for the forEach callback to enhance readability and align with modern JavaScript practices.

- exclude.split(',').forEach(function (val) {
+ exclude.split(',').forEach(val => {
src/cards/stats-card.ts (1)

Line range hint 47-112: Consider converting this function into an arrow function to make the code more concise and to use lexical scoping.

- const getStatsData = async function (
+ const getStatsData = async (
src/cards/profile-details-card.ts (3)

Line range hint 9-24: Use arrow functions for these kinds of simple transformations to improve readability and maintain lexical scoping.

- export const createProfileDetailsCard = async function (username: string) {
+ export const createProfileDetailsCard = async (username: string) => {
Tools
Biome

[error] 25-34: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 36-54: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


Line range hint 56-72: Consider using arrow functions to simplify these utility functions, which do not require their own this context.

- const getProfileDateJoined = function (profileDetails: ProfileDetails): string {
+ const getProfileDateJoined = (profileDetails: ProfileDetails): string => {

Line range hint 74-147: This function could benefit from the arrow function syntax for better readability and scoping.

- const getProfileDetailsData = async function (
+ const getProfileDetailsData = async (
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 28c14b9 and 10bce53.

Files selected for processing (10)
  • api/cards/most-commit-language.ts (2 hunks)
  • api/cards/productive-time.ts (2 hunks)
  • api/cards/profile-details.ts (2 hunks)
  • api/cards/repos-per-language.ts (3 hunks)
  • api/cards/stats.ts (2 hunks)
  • src/cards/most-commit-language-card.ts (3 hunks)
  • src/cards/productive-time-card.ts (2 hunks)
  • src/cards/profile-details-card.ts (2 hunks)
  • src/cards/repos-per-language-card.ts (2 hunks)
  • src/cards/stats-card.ts (2 hunks)
Additional context used
Biome
src/cards/repos-per-language-card.ts

[error] 6-13: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 15-24: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 26-42: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 56-58: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 44-61: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

src/cards/most-commit-language-card.ts

[error] 6-13: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 15-24: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 26-59: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 76-78: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 61-82: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

api/cards/repos-per-language.ts

[error] 67-69: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

api/cards/most-commit-language.ts

[error] 58-60: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

src/cards/productive-time-card.ts

[error] 6-13: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 15-24: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 26-43: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 49-60: This else clause can be omitted because previous branches break early. (lint/style/noUselessElse)

Unsafe fix: Omit the else clause.


[error] 53-60: This else clause can be omitted because previous branches break early. (lint/style/noUselessElse)


[error] 57-60: This else clause can be omitted because previous branches break early. (lint/style/noUselessElse)


[error] 45-61: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 63-91: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

src/cards/stats-card.ts

[error] 9-16: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 18-26: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 28-45: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 47-112: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

src/cards/profile-details-card.ts

[error] 9-24: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 25-34: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 36-54: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 56-72: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.


[error] 74-147: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

GitHub Check: lint
src/cards/most-commit-language-card.ts

[failure] 48-48:
'theme' is never reassigned. Use 'const' instead


[failure] 48-48:
Replace ·...ThemeMap.get(themeName)!· with ...ThemeMap.get(themeName)!


[failure] 50-50:
Replace "#" with '#'


[failure] 51-51:
Replace "#" with '#'


[failure] 52-52:
Replace "#" with '#'


[failure] 53-53:
Replace ·theme.stroke·=·"#"·+·customTheme.stroke;·theme.strokeOpacity·=·1; with ⏎············theme.stroke·=·'#'·+·customTheme.stroke;⏎············theme.strokeOpacity·=·1;⏎·······


[failure] 54-54:
Replace "#" with '#'


[failure] 55-55:
Replace "#" with '#'

src/cards/productive-time-card.ts

[failure] 32-32:
'theme' is never reassigned. Use 'const' instead


[failure] 32-32:
Replace ·...ThemeMap.get(themeName)!· with ...ThemeMap.get(themeName)!

Additional comments not posted (7)
src/cards/most-commit-language-card.ts (2)

18-18: The addition of customTheme parameter allows for dynamic theming which is a great feature enhancement.

Also applies to: 23-23


9-9: Consider using an arrow function for better consistency and to leverage ES6 features.

-  for (const themeName of ThemeMap.keys()) {
+  ThemeMap.keys().forEach(themeName => {

Likely invalid or redundant comment.

api/cards/repos-per-language.ts (1)

9-19: The addition of multiple theme-related parameters enhances customization capabilities. Ensure thorough validation for each parameter to prevent potential security risks or errors.

api/cards/most-commit-language.ts (1)

9-19: Similar to the previous file, ensure that all new query parameters are validated properly to avoid errors and potential security issues.

src/cards/productive-time-card.ts (2)

18-23: The addition of customTheme parameter allows for dynamic theming which is a great feature enhancement.


9-9: Using an arrow function here would align with ES6 best practices and improve readability.

- for (const themeName of ThemeMap.keys()) {
+ ThemeMap.keys().forEach(themeName => {

Likely invalid or redundant comment.

src/cards/stats-card.ts (1)

18-26: Refactor to use arrow function for consistency and to leverage lexical this.
[REFACTOR_SUGGESTion]

- export const getStatsSVGWithThemeName = async function (
+ export const getStatsSVGWithThemeName = async (
Tools
Biome

[error] 18-26: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

Comment on lines 9 to 16
export const createStatsCard = async function (username: string) {
const statsData = await getStatsData(username);
for (const themeName of ThemeMap.keys()) {
const svgString = getStatsSVG(statsData, themeName);
const svgString = getStatsSVG(statsData, themeName, undefined);
// output to folder, use 3- prefix for sort in preview
writeSVG(themeName, '3-stats', svgString);
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using arrow functions for better readability and lexical scoping advantages.

- export const createStatsCard = async function (username: string) {
+ export const createStatsCard = async (username: string) => {
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const createStatsCard = async function (username: string) {
const statsData = await getStatsData(username);
for (const themeName of ThemeMap.keys()) {
const svgString = getStatsSVG(statsData, themeName);
const svgString = getStatsSVG(statsData, themeName, undefined);
// output to folder, use 3- prefix for sort in preview
writeSVG(themeName, '3-stats', svgString);
}
};
export const createStatsCard = async (username: string) => {
const statsData = await getStatsData(username);
for (const themeName of ThemeMap.keys()) {
const svgString = getStatsSVG(statsData, themeName, undefined);
// output to folder, use 3- prefix for sort in preview
writeSVG(themeName, '3-stats', svgString);
}
};
Tools
Biome

[error] 9-16: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

Comment on lines 28 to 45
const getStatsSVG = function (
StatsData: {index: number; icon: string; name: string; value: string}[],
themeName: string
themeName: string,
customTheme: Theme | undefined
) {
const title = 'Stats';
const svgString = statsCard(`${title}`, StatsData, ThemeMap.get(themeName)!);
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = statsCard(`${title}`, StatsData, theme);
return svgString;
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can be simplified using an arrow function, improving readability and scoping.

- const getStatsSVG = function (
+ const getStatsSVG = (
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const getStatsSVG = function (
StatsData: {index: number; icon: string; name: string; value: string}[],
themeName: string
themeName: string,
customTheme: Theme | undefined
) {
const title = 'Stats';
const svgString = statsCard(`${title}`, StatsData, ThemeMap.get(themeName)!);
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = statsCard(`${title}`, StatsData, theme);
return svgString;
};
const getStatsSVG = (
StatsData: {index: number; icon: string; name: string; value: string}[],
themeName: string,
customTheme: Theme | undefined
) => {
const title = 'Stats';
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = statsCard(`${title}`, StatsData, theme);
return svgString;
};
Tools
Biome

[error] 28-45: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

Comment on lines +25 to 34
export const getProfileDetailsSVGWithThemeName = async function (
username: string,
themeName: string,
customTheme: Theme
): Promise<string> {
if (!ThemeMap.has(themeName)) throw new Error('Theme does not exist');
const profileDetailsData = await getProfileDetailsData(username);
const title = profileDetailsData[0].name == null ? `${username}` : `${username} (${profileDetailsData[0].name})`;
return getProfileDetailsSVG(title, profileDetailsData[0].contributions, profileDetailsData[1], themeName);
return getProfileDetailsSVG(title, profileDetailsData[0].contributions, profileDetailsData[1], themeName, customTheme);
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching to an arrow function could enhance the readability and consistency of your code.

- export const getProfileDetailsSVGWithThemeName = async function (
+ export const getProfileDetailsSVGWithThemeName = async (
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const getProfileDetailsSVGWithThemeName = async function (
username: string,
themeName: string,
customTheme: Theme
): Promise<string> {
if (!ThemeMap.has(themeName)) throw new Error('Theme does not exist');
const profileDetailsData = await getProfileDetailsData(username);
const title = profileDetailsData[0].name == null ? `${username}` : `${username} (${profileDetailsData[0].name})`;
return getProfileDetailsSVG(title, profileDetailsData[0].contributions, profileDetailsData[1], themeName);
return getProfileDetailsSVG(title, profileDetailsData[0].contributions, profileDetailsData[1], themeName, customTheme);
};
export const getProfileDetailsSVGWithThemeName = async (
username: string,
themeName: string,
customTheme: Theme
): Promise<string> => {
if (!ThemeMap.has(themeName)) throw new Error('Theme does not exist');
const profileDetailsData = await getProfileDetailsData(username);
const title = profileDetailsData[0].name == null ? `${username}` : `${username} (${profileDetailsData[0].name})`;
return getProfileDetailsSVG(title, profileDetailsData[0].contributions, profileDetailsData[1], themeName, customTheme);
};
Tools
Biome

[error] 25-34: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

Comment on lines 36 to 54
const getProfileDetailsSVG = function (
title: string,
contributionsData: ProfileContribution[],
userDetails: {index: number; icon: string; name: string; value: string}[],
themeName: string
themeName: string,
customTheme: Theme | undefined
): string {
const svgString = createDetailCard(`${title}`, userDetails, contributionsData, ThemeMap.get(themeName)!);
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = createDetailCard(`${title}`, userDetails, contributionsData, theme);
return svgString;
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring to use arrow functions can help in keeping the context of this consistent and make the function expressions cleaner.

- const getProfileDetailsSVG = function (
+ const getProfileDetailsSVG = (
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const getProfileDetailsSVG = function (
title: string,
contributionsData: ProfileContribution[],
userDetails: {index: number; icon: string; name: string; value: string}[],
themeName: string
themeName: string,
customTheme: Theme | undefined
): string {
const svgString = createDetailCard(`${title}`, userDetails, contributionsData, ThemeMap.get(themeName)!);
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = createDetailCard(`${title}`, userDetails, contributionsData, theme);
return svgString;
};
const getProfileDetailsSVG = (
title: string,
contributionsData: ProfileContribution[],
userDetails: {index: number; icon: string; name: string; value: string}[],
themeName: string,
customTheme: Theme | undefined
): string => {
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = createDetailCard(`${title}`, userDetails, contributionsData, theme);
return svgString;
};
Tools
Biome

[error] 36-54: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

Comment on lines 15 to 24
export const getReposPerLanguageSVGWithThemeName = async function (
username: string,
themeName: string,
customTheme: Theme,
exclude: Array<string>
) {
if (!ThemeMap.has(themeName)) throw new Error('Theme does not exist');
const langData = await getRepoLanguageData(username, exclude);
return getReposPerLanguageSVG(langData, themeName);
return getReposPerLanguageSVG(langData, themeName, customTheme);
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convert to arrow function for improved readability and consistency.

- export const getReposPerLanguageSVGWithThemeName = async function (
+ export const getReposPerLanguageSVGWithThemeName = async (
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const getReposPerLanguageSVGWithThemeName = async function (
username: string,
themeName: string,
customTheme: Theme,
exclude: Array<string>
) {
if (!ThemeMap.has(themeName)) throw new Error('Theme does not exist');
const langData = await getRepoLanguageData(username, exclude);
return getReposPerLanguageSVG(langData, themeName);
return getReposPerLanguageSVG(langData, themeName, customTheme);
};
export const getReposPerLanguageSVGWithThemeName = async (
username: string,
themeName: string,
customTheme: Theme,
exclude: Array<string>
) => {
if (!ThemeMap.has(themeName)) throw new Error('Theme does not exist');
const langData = await getRepoLanguageData(username, exclude);
return getReposPerLanguageSVG(langData, themeName, customTheme);
};
Tools
Biome

[error] 15-24: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

Comment on lines +33 to +55
if (typeof title_color !== 'string') {
res.status(400).send('title_color must be a string');
return;
}
if (typeof text_color !== 'string') {
res.status(400).send('text_color must be a string');
return;
}
if (typeof bg_color !== 'string') {
res.status(400).send('bg_color must be a string');
return;
}
if (typeof border_color !== 'string') {
res.status(400).send('border_color must be a string');
return;
}
if (typeof icon_color !== 'string') {
res.status(400).send('icon_color must be a string');
return;
}
if (typeof chart_color !== 'string') {
res.status(400).send('chart_color must be a string');
return;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repeated pattern of parameter validation can be refactored into a utility function to adhere to DRY principles.

+ function validateParam(param, paramName) {
+   if (typeof param !== 'string') {
+       res.status(400).send(`${paramName} must be a string`);
+       return false;
+   }
+   return true;
+ }
- if (typeof title_color !== 'string') {
-     res.status(400).send('title_color must be a string');
-     return;
- }
+ if (!validateParam(title_color, 'title_color')) return;

Committable suggestion was skipped due to low confidence.

Comment on lines 58 to 60
exclude.split(',').forEach(function (val) {
excludeArr.push(translateLanguage(val));
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using an arrow function for the forEach callback to improve consistency with modern JavaScript syntax.

- exclude.split(',').forEach(function (val) {
+ exclude.split(',').forEach(val => {
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
exclude.split(',').forEach(function (val) {
excludeArr.push(translateLanguage(val));
});
exclude.split(',').forEach(val => {
excludeArr.push(translateLanguage(val));
});
Tools
Biome

[error] 58-60: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

Comment on lines +33 to +55
if (typeof title_color !== 'string') {
res.status(400).send('title_color must be a string');
return;
}
if (typeof text_color !== 'string') {
res.status(400).send('text_color must be a string');
return;
}
if (typeof bg_color !== 'string') {
res.status(400).send('bg_color must be a string');
return;
}
if (typeof border_color !== 'string') {
res.status(400).send('border_color must be a string');
return;
}
if (typeof icon_color !== 'string') {
res.status(400).send('icon_color must be a string');
return;
}
if (typeof chart_color !== 'string') {
res.status(400).send('chart_color must be a string');
return;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor the repeated validation code into a utility function to reduce redundancy and enhance maintainability.

+ function validateParam(param, paramName) {
+   if (typeof param !== 'string') {
+       res.status(400).send(`${paramName} must be a string`);
+       return false;
+   }
+   return true;
+ }
- if (typeof title_color !== 'string') {
-     res.status(400).send('title_color must be a string');
-     return;
- }
+ if (!validateParam(title_color, 'title_color')) return;

Committable suggestion was skipped due to low confidence.

Comment on lines +32 to +40
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use const for theme since it's never reassigned. Also, replace double quotes with single quotes for consistency.

- let theme = { ...ThemeMap.get(themeName)! };
+ const theme = { ...ThemeMap.get(themeName)! };
- if (customTheme.title) theme.title = "#" + customTheme.title;
+ if (customTheme.title) theme.title = '#' + customTheme.title;
- if (customTheme.text) theme.text = "#" + customTheme.text;
+ if (customTheme.text) theme.text = '#' + customTheme.text;
- if (customTheme.background) theme.background = "#" + customTheme.background;
+ if (customTheme.background) theme.background = '#' + customTheme.background;
- if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
+ if (customTheme.stroke) { theme.stroke = '#' + customTheme.stroke; theme.strokeOpacity = 1; }
- if (customTheme.icon) theme.icon = "#" + customTheme.icon;
+ if (customTheme.icon) theme.icon = '#' + customTheme.icon;
- if (customTheme.chart) theme.chart = "#" + customTheme.chart;
+ if (customTheme.chart) theme.chart = '#' + customTheme.chart;
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = '#' + customTheme.title;
if (customTheme.text) theme.text = '#' + customTheme.text;
if (customTheme.background) theme.background = '#' + customTheme.background;
if (customTheme.stroke) { theme.stroke = '#' + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = '#' + customTheme.icon;
if (customTheme.chart) theme.chart = '#' + customTheme.chart;
}
Tools
GitHub Check: lint

[failure] 32-32:
'theme' is never reassigned. Use 'const' instead


[failure] 32-32:
Replace ·...ThemeMap.get(themeName)!· with ...ThemeMap.get(themeName)!

Comment on lines 26 to 43
const getProductiveTimeSVG = function (
productiveTimeData: Array<number>,
themeName: string,
customTheme: Theme | undefined,
utcOffset: number
): string {
const svgString = productiveTimeCard(productiveTimeData, ThemeMap.get(themeName)!, utcOffset);
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = productiveTimeCard(productiveTimeData, theme, utcOffset);
return svgString;
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider converting this function expression to an arrow function to reduce complexity and improve readability.

- const getProductiveTimeSVG = function (
+ const getProductiveTimeSVG = (
    productiveTimeData: Array<number>,
    themeName: string,
    customTheme: Theme | undefined,
    utcOffset: number
): string => {
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const getProductiveTimeSVG = function (
productiveTimeData: Array<number>,
themeName: string,
customTheme: Theme | undefined,
utcOffset: number
): string {
const svgString = productiveTimeCard(productiveTimeData, ThemeMap.get(themeName)!, utcOffset);
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = productiveTimeCard(productiveTimeData, theme, utcOffset);
return svgString;
};
const getProductiveTimeSVG = (
productiveTimeData: Array<number>,
themeName: string,
customTheme: Theme | undefined,
utcOffset: number
): string => {
let theme = { ...ThemeMap.get(themeName)! };
if (customTheme !== undefined) {
if (customTheme.title) theme.title = "#" + customTheme.title;
if (customTheme.text) theme.text = "#" + customTheme.text;
if (customTheme.background) theme.background = "#" + customTheme.background;
if (customTheme.stroke) { theme.stroke = "#" + customTheme.stroke; theme.strokeOpacity = 1; }
if (customTheme.icon) theme.icon = "#" + customTheme.icon;
if (customTheme.chart) theme.chart = "#" + customTheme.chart;
}
const svgString = productiveTimeCard(productiveTimeData, theme, utcOffset);
return svgString;
};
Tools
Biome

[error] 26-43: This function expression can be turned into an arrow function. (lint/complexity/useArrowFunction)

Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.

GitHub Check: lint

[failure] 32-32:
'theme' is never reassigned. Use 'const' instead


[failure] 32-32:
Replace ·...ThemeMap.get(themeName)!· with ...ThemeMap.get(themeName)!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant