Commit 9af56df2 authored by anuraghazra's avatar anuraghazra
Browse files

feat: added bg_color options, added RepoCard color options too

parent 61a0f517
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ module.exports = async (req, res) => {
    title_color,
    icon_color,
    text_color,
    bg_color,
  } = req.query;
  let stats;

@@ -32,6 +33,7 @@ module.exports = async (req, res) => {
      title_color,
      icon_color,
      text_color,
      bg_color,
    })
  );
};
+16 −2
Original line number Diff line number Diff line
@@ -4,7 +4,14 @@ const fetchRepo = require("../src/fetchRepo");
const renderRepoCard = require("../src/renderRepoCard");

module.exports = async (req, res) => {
  const { username, repo } = req.query;
  const {
    username,
    repo,
    title_color,
    icon_color,
    text_color,
    bg_color,
  } = req.query;

  let repoData;
  res.setHeader("Content-Type", "image/svg+xml");
@@ -16,5 +23,12 @@ module.exports = async (req, res) => {
    return res.send(renderError(err.message));
  }

  res.send(renderRepoCard(repoData));
  res.send(
    renderRepoCard(repoData, {
      title_color,
      icon_color,
      text_color,
      bg_color,
    })
  );
};
+20 −12
Original line number Diff line number Diff line
const { kFormatter, encodeHTML } = require("../src/utils");
const { kFormatter, encodeHTML, isValidHexColor } = require("../src/utils");

const renderRepoCard = (repo) => {
const renderRepoCard = (repo, options = {}) => {
  const { name, description, primaryLanguage, stargazers, forkCount } = repo;
  const { title_color, icon_color, text_color, bg_color } = options;

  const height = 120;
  const shiftText = primaryLanguage.name.length > 15 ? 0 : 30;

@@ -10,20 +12,26 @@ const renderRepoCard = (repo) => {
    desc = `${description.slice(0, 55)}..`;
  }

  const titleColor =
    (isValidHexColor(title_color) && `#${title_color}`) || "#2f80ed";
  const iconColor =
    (isValidHexColor(icon_color) && `#${icon_color}`) || "#586069";
  const bgColor =
    (isValidHexColor(bg_color) && `#${bg_color}`) || "rgba(255, 255, 255, 0)";
  const textColor = (isValidHexColor(text_color) && `#${text_color}`) || "#333";

  const totalStars = kFormatter(stargazers.totalCount);
  const totalForks = kFormatter(forkCount);
  return `
    <svg width="400" height="${height}" viewBox="0 0 400 ${height}" fill="none" xmlns="http://www.w3.org/2000/svg">
      <style>
      .header { font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif; fill: #2F80ED }
      .stat { font: 600 14px 'Segoe UI', Ubuntu, Sans-Serif; fill: #333 }
      .star-icon { font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif; }
      .bold { font-weight: 700 }
      .description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: #586069 }
      .gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: #586069 }
      .header { font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${titleColor} }
      .description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
      .gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
      .icon { fill: ${iconColor} }
      </style>
      <rect x="0.5" y="0.5" width="399" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>
      <svg x="25" y="25" viewBox="0 0 16 16" version="1.1" width="16" height="16" fill="#586069">
      <rect data-testid="card-border" x="0.5" y="0.5" width="399" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>
      <svg class="icon" x="25" y="25" viewBox="0 0 16 16" version="1.1" width="16" height="16">
        <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path>
      </svg>

@@ -40,14 +48,14 @@ const renderRepoCard = (repo) => {
      </g>

      <g transform="translate(${155 - shiftText}, 100)">
        <svg y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16" fill="#586069">
        <svg class="icon" y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16">
          <path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path>
        </svg>
        <text data-testid="stargazers" class="gray" x="25">${totalStars}</text>
      </g>

      <g transform="translate(${220 - shiftText}, 100)">
        <svg y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16" fill="#586069">
        <svg class="icon" y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16">
          <path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path>
        </svg>
        <text data-testid="forkcount" class="gray" x="25">${totalForks}</text>
+4 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
    title_color,
    icon_color,
    text_color,
    bg_color,
  } = options;

  const lheight = parseInt(line_height);
@@ -36,6 +37,8 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
  const iconColor =
    (isValidHexColor(icon_color) && `#${icon_color}`) || "#4c71f2";
  const textColor = (isValidHexColor(text_color) && `#${text_color}`) || "#333";
  const bgColor =
    (isValidHexColor(bg_color) && `#${bg_color}`) || "rgba(255, 255, 255, 0)";

  const STAT_MAP = {
    stars: createTextNode({
@@ -81,7 +84,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {

  const height = 45 + (statItems.length + 1) * lheight;

  const border = `<rect data-testid="card-border" x="0.5" y="0.5" width="494" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>`;
  const border = `<rect data-testid="card-border" x="0.5" y="0.5" width="494" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>`;
  return `
    <svg width="495" height="${height}" viewBox="0 0 495 ${height}" fill="none" xmlns="http://www.w3.org/2000/svg">
      <style>
+48 −0
Original line number Diff line number Diff line
require("@testing-library/jest-dom");
const cssToObject = require("css-to-object");
const renderRepoCard = require("../src/renderRepoCard");

const { queryByTestId } = require("@testing-library/dom");
@@ -88,4 +89,51 @@ describe("Test renderRepoCard", () => {
      "translate(125, 100)"
    );
  });

  it("should render default colors properly", () => {
    document.body.innerHTML = renderRepoCard(data_repo.repository);

    const styleTag = document.querySelector("style");
    const stylesObject = cssToObject(styleTag.innerHTML);

    const headerClassStyles = stylesObject[".header"];
    const statClassStyles = stylesObject[".description"];
    const iconClassStyles = stylesObject[".icon"];

    expect(headerClassStyles.fill).toBe("#2f80ed");
    expect(statClassStyles.fill).toBe("#333");
    expect(iconClassStyles.fill).toBe("#586069");
    expect(queryByTestId(document.body, "card-border")).toHaveAttribute(
      "fill",
      "rgba(255, 255, 255, 0)"
    );
  });

  it("should render custom colors properly", () => {
    const customColors = {
      title_color: "5a0",
      icon_color: "1b998b",
      text_color: "9991",
      bg_color: "252525",
    };

    document.body.innerHTML = renderRepoCard(data_repo.repository, {
      ...customColors,
    });

    const styleTag = document.querySelector("style");
    const stylesObject = cssToObject(styleTag.innerHTML);

    const headerClassStyles = stylesObject[".header"];
    const statClassStyles = stylesObject[".description"];
    const iconClassStyles = stylesObject[".icon"];

    expect(headerClassStyles.fill).toBe(`#${customColors.title_color}`);
    expect(statClassStyles.fill).toBe(`#${customColors.text_color}`);
    expect(iconClassStyles.fill).toBe(`#${customColors.icon_color}`);
    expect(queryByTestId(document.body, "card-border")).toHaveAttribute(
      "fill",
      "#252525"
    );
  });
});
Loading