From e044cc8b2abea7fd18ccddc9a072b1aea7d56745 Mon Sep 17 00:00:00 2001 From: yaten2302 Date: Sun, 27 Aug 2023 15:55:36 +0530 Subject: [PATCH 1/8] test translations.js --- src/translations.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/translations.js b/src/translations.js index 1ced5f69263fd..67bc12ab3aca1 100644 --- a/src/translations.js +++ b/src/translations.js @@ -385,6 +385,36 @@ const statCardLocales = ({ name, apostrophe }) => { vi: "Tỷ Lệ PR Đã Hợp Nhất", se: "Procent av sammanfogade PR", }, + "statcard.test": { + ar: "نسبة الطلبات المدمجة", + cn: "合并的 PR 百分比", + "zh-tw": "合併的 PR 百分比", + cs: "Sloučené PRs v procentech", + de: "Zusammengeführte PRs in Prozent", + en: "Test", + bn: "PR একত্রীকরণের শতাংশ", + es: "Porcentaje de PR fusionados", + fr: "Pourcentage de PR fusionnés", + hu: "Egyesített PR-k százaléka", + it: "Percentuale di PR uniti", + ja: "マージされた PR の割合", + kr: "병합된 PR의 비율", + nl: "Percentage samengevoegde PR's", + "pt-pt": "Percentagem de PRs Fundidos", + "pt-br": "Porcentagem de PRs Fundidos", + np: "PR मर्ज गरिएको प्रतिशत", + el: "Ποσοστό Συγχωνευμένων PR", + ru: "Процент объединённых pull request`ов", + "uk-ua": "Відсоток об'єднаних pull request`iв", + id: "Persentase PR Digabungkan", + my: "Peratus PR Digabungkan", + sk: "Percento zlúčených PR", + tr: "Birleştirilmiş PR Yüzdesi", + pl: "Procent połączonych PR", + uz: "Birlangan PR-lar foizi", + vi: "Tỷ Lệ PR Đã Hợp Nhất", + se: "Procent av sammanfogade PR", + }, }; }; From f48d5c4b448127d1042a19f52cd5df7f588efe2f Mon Sep 17 00:00:00 2001 From: yaten2302 Date: Sun, 27 Aug 2023 16:00:33 +0530 Subject: [PATCH 2/8] test icons.js --- src/cards/stats-card.js | 8 ++++++++ src/common/icons.js | 1 + 2 files changed, 9 insertions(+) diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 778e67647f342..5d2643c102778 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -102,6 +102,7 @@ const renderStatsCard = (stats, options = {}) => { totalDiscussionsAnswered, contributedTo, rank, + test, } = stats; const { hide = [], @@ -234,6 +235,13 @@ const renderStatsCard = (stats, options = {}) => { id: "contribs", }; + STATS.test = { + icon: icons.test, + label: i18n.t("statcard.test"), + value: test, + id: "test", + }; + const longLocales = [ "cn", "es", diff --git a/src/common/icons.js b/src/common/icons.js index 771704a335d12..575ed757f8412 100644 --- a/src/common/icons.js +++ b/src/common/icons.js @@ -12,6 +12,7 @@ const icons = { discussions_started: ``, discussions_answered: ``, gist: ``, + test: ``, }; /** From 53decae174eb40e096ad4ab2cb37e0669378d2fa Mon Sep 17 00:00:00 2001 From: yaten2302 Date: Sun, 27 Aug 2023 16:04:23 +0530 Subject: [PATCH 3/8] test stats-fetcher.js --- src/fetchers/stats-fetcher.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index ac51d49bebcab..8396c59c97278 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -214,6 +214,7 @@ const fetchStats = async ( totalDiscussionsAnswered: 0, contributedTo: 0, rank: { level: "C", percentile: 100 }, + test: "", }; let res = await statsFetcher(username); @@ -260,6 +261,7 @@ const fetchStats = async ( stats.totalDiscussionsStarted = user.repositoryDiscussions.totalCount; stats.totalDiscussionsAnswered = user.repositoryDiscussionComments.totalCount; stats.contributedTo = user.repositoriesContributedTo.totalCount; + stats.test = user.name; // Test: "not changing" // Retrieve stars while filtering out repositories to be hidden. let repoToHide = new Set(exclude_repo); From b19934fa9c7f2e26d309fa11119f6a00546b6781 Mon Sep 17 00:00:00 2001 From: yaten2302 Date: Sun, 27 Aug 2023 16:08:44 +0530 Subject: [PATCH 4/8] test types.d.ts --- src/fetchers/types.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fetchers/types.d.ts b/src/fetchers/types.d.ts index affb407b816b0..fcfe7c044cff7 100644 --- a/src/fetchers/types.d.ts +++ b/src/fetchers/types.d.ts @@ -37,6 +37,7 @@ export type StatsData = { totalDiscussionsAnswered: number; contributedTo: number; rank: { level: string; percentile: number }; + test: string; }; export type Lang = { From 982375ff1379a0798a49faf32887d0dd4d74ff10 Mon Sep 17 00:00:00 2001 From: yaten2302 Date: Tue, 29 Aug 2023 22:03:17 +0530 Subject: [PATCH 5/8] all changes reverted --- src/cards/stats-card.js | 8 -------- src/common/icons.js | 1 - src/fetchers/stats-fetcher.js | 2 -- src/fetchers/types.d.ts | 1 - src/translations.js | 30 ------------------------------ 5 files changed, 42 deletions(-) diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 5d2643c102778..778e67647f342 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -102,7 +102,6 @@ const renderStatsCard = (stats, options = {}) => { totalDiscussionsAnswered, contributedTo, rank, - test, } = stats; const { hide = [], @@ -235,13 +234,6 @@ const renderStatsCard = (stats, options = {}) => { id: "contribs", }; - STATS.test = { - icon: icons.test, - label: i18n.t("statcard.test"), - value: test, - id: "test", - }; - const longLocales = [ "cn", "es", diff --git a/src/common/icons.js b/src/common/icons.js index 575ed757f8412..771704a335d12 100644 --- a/src/common/icons.js +++ b/src/common/icons.js @@ -12,7 +12,6 @@ const icons = { discussions_started: ``, discussions_answered: ``, gist: ``, - test: ``, }; /** diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 8396c59c97278..ac51d49bebcab 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -214,7 +214,6 @@ const fetchStats = async ( totalDiscussionsAnswered: 0, contributedTo: 0, rank: { level: "C", percentile: 100 }, - test: "", }; let res = await statsFetcher(username); @@ -261,7 +260,6 @@ const fetchStats = async ( stats.totalDiscussionsStarted = user.repositoryDiscussions.totalCount; stats.totalDiscussionsAnswered = user.repositoryDiscussionComments.totalCount; stats.contributedTo = user.repositoriesContributedTo.totalCount; - stats.test = user.name; // Test: "not changing" // Retrieve stars while filtering out repositories to be hidden. let repoToHide = new Set(exclude_repo); diff --git a/src/fetchers/types.d.ts b/src/fetchers/types.d.ts index fcfe7c044cff7..affb407b816b0 100644 --- a/src/fetchers/types.d.ts +++ b/src/fetchers/types.d.ts @@ -37,7 +37,6 @@ export type StatsData = { totalDiscussionsAnswered: number; contributedTo: number; rank: { level: string; percentile: number }; - test: string; }; export type Lang = { diff --git a/src/translations.js b/src/translations.js index 67bc12ab3aca1..1ced5f69263fd 100644 --- a/src/translations.js +++ b/src/translations.js @@ -385,36 +385,6 @@ const statCardLocales = ({ name, apostrophe }) => { vi: "Tỷ Lệ PR Đã Hợp Nhất", se: "Procent av sammanfogade PR", }, - "statcard.test": { - ar: "نسبة الطلبات المدمجة", - cn: "合并的 PR 百分比", - "zh-tw": "合併的 PR 百分比", - cs: "Sloučené PRs v procentech", - de: "Zusammengeführte PRs in Prozent", - en: "Test", - bn: "PR একত্রীকরণের শতাংশ", - es: "Porcentaje de PR fusionados", - fr: "Pourcentage de PR fusionnés", - hu: "Egyesített PR-k százaléka", - it: "Percentuale di PR uniti", - ja: "マージされた PR の割合", - kr: "병합된 PR의 비율", - nl: "Percentage samengevoegde PR's", - "pt-pt": "Percentagem de PRs Fundidos", - "pt-br": "Porcentagem de PRs Fundidos", - np: "PR मर्ज गरिएको प्रतिशत", - el: "Ποσοστό Συγχωνευμένων PR", - ru: "Процент объединённых pull request`ов", - "uk-ua": "Відсоток об'єднаних pull request`iв", - id: "Persentase PR Digabungkan", - my: "Peratus PR Digabungkan", - sk: "Percento zlúčených PR", - tr: "Birleştirilmiş PR Yüzdesi", - pl: "Procent połączonych PR", - uz: "Birlangan PR-lar foizi", - vi: "Tỷ Lệ PR Đã Hợp Nhất", - se: "Procent av sammanfogade PR", - }, }; }; From b20a4b170122bee35f0675d85e4355808120d380 Mon Sep 17 00:00:00 2001 From: Yaten Dhingra Date: Mon, 9 Oct 2023 19:30:17 +0530 Subject: [PATCH 6/8] added streak card to readme --- readme.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/readme.md b/readme.md index 60747cba5c53b..fd5fd872f5ffe 100644 --- a/readme.md +++ b/readme.md @@ -114,6 +114,9 @@ Please visit [this link](https://give.do/fundraisers/stand-beside-the-victims-of - [Demo](#demo-2) - [Wakatime Stats Card](#wakatime-stats-card) - [Demo](#demo-3) +- [GitHub Streaks Card](#github-streaks-card) + - [Usage](#usage-3) + - [Hide individual elements from the streaks card](#hide-individual-elements-from-the-streaks-card) - [All Demos](#all-demos) - [Quick Tip (Align The Cards)](#quick-tip-align-the-cards) - [Deploy on your own](#deploy-on-your-own) @@ -565,6 +568,24 @@ Change the `?username=` value to your [Wakatime](https://wakatime.com) username. *** +# GitHub Streaks Card + +GitHub Streaks Card allows you to show your streak of your contributions on GitHub(like total contributions, weekly and longest streak on daily and weekly basis). + +### Usage + +Copy-paste this code into your readme and change the links. + +Endpoint: `api/streak/?username=YOUR_USERNAME` + +```md +![Streaks Card](https://github-readme-stats.vercel.app/api/streak/?username=YOUR_USERNAME) +``` + +### Hide individual elements from the streaks card + +To hide individual elements form the card, use - `&hide=params`, where `params` = `totalContributions`, `weeklyLongest`, `weeklyCurrent`, `dailyLongest`, `dailyCurrent` + # All Demos * Default From 1766373c830f0c2511bc140c5d8aa69dc4ace1cb Mon Sep 17 00:00:00 2001 From: Yaten Dhingra Date: Mon, 9 Oct 2023 19:30:58 +0530 Subject: [PATCH 7/8] added streak card --- api/streak.js | 87 +++++++++++++++ src/cards/streak-card.js | 195 +++++++++++++++++++++++++++++++++ src/common/utils.js | 18 ++- src/fetchers/streak-fetcher.js | 123 +++++++++++++++++++++ src/translations.js | 105 ++++++++++++++++++ 5 files changed, 524 insertions(+), 4 deletions(-) create mode 100644 api/streak.js create mode 100644 src/cards/streak-card.js create mode 100644 src/fetchers/streak-fetcher.js diff --git a/api/streak.js b/api/streak.js new file mode 100644 index 0000000000000..671cf8de9b9d8 --- /dev/null +++ b/api/streak.js @@ -0,0 +1,87 @@ +import renderStreaksCard from "../src/cards/streak-card.js"; +import { blacklist } from "../src/common/blacklist.js"; +import { + clampValue, + CONSTANTS, + parseArray, + parseBoolean, + renderError, +} from "../src/common/utils.js"; + +import { isLocaleAvailable } from "../src/translations.js"; +import { streakFetcher } from "../src/fetchers/streak-fetcher.js"; +import axios from "axios"; +export default async (req, res) => { + const { + username, + hide, + hide_border, + card_width, + line_height, + title_color, + text_color, + text_bold, + bg_color, + theme, + cache_seconds, + custom_title, + locale, + disable_animations, + border_radius, + number_format, + border_color, + } = req.query; + res.setHeader("Content-Type", "image/svg+xml"); + + if (blacklist.includes(username)) { + return res.send(renderError("Something went wrong")); + } + + if (locale && !isLocaleAvailable(locale)) { + return res.send(renderError("Something went wrong", "Language not found")); + } + + try { + const streaks = await streakFetcher(username); + + let cacheSeconds = clampValue( + parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10), + CONSTANTS.FOUR_HOURS, + CONSTANTS.ONE_DAY, + ); + cacheSeconds = process.env.CACHE_SECONDS + ? parseInt(process.env.CACHE_SECONDS, 10) || cacheSeconds + : cacheSeconds; + + res.setHeader( + "Cache-Control", + `max-age=${ + cacheSeconds / 2 + }, s-maxage=${cacheSeconds}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`, + ); + + return res.send( + renderStreaksCard(streaks, { + hide: parseArray(hide), + hide_border: parseBoolean(hide_border), + card_width: parseInt(card_width, 10), + line_height, + title_color, + text_color, + text_bold: parseBoolean(text_bold), + bg_color, + theme, + custom_title, + border_radius, + border_color, + number_format, + locale: locale ? locale : null, + disable_animations: parseBoolean(disable_animations), + }), + ); + + } catch (err) { + res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses. + return res.send(renderError(err.message, err.secondaryMessage)); + } +}; diff --git a/src/cards/streak-card.js b/src/cards/streak-card.js new file mode 100644 index 0000000000000..6aa1074cd2218 --- /dev/null +++ b/src/cards/streak-card.js @@ -0,0 +1,195 @@ +import Card from "../common/Card.js"; +import I18n from "../common/I18n.js"; +import { flexLayout, getCardColors, kFormatter } from "../common/utils.js"; +import { getStyles } from "../getStyles.js"; +import { streakCardLocales } from "../translations.js"; + +const CARD_MIN_WIDTH = 300; +const CARD_DEFAULT_WIDTH = 300; + +const createTextNode = ({ + value, + label, + id, + index, + shiftValuePos, + bold, + number_format, +}) => { + const kValue = number_format === "long" ? value : kFormatter(value); + const staggerDelay = (index + 3) * 150; + + return ` + + ${label}: + ${kValue} + + `; +}; + +const renderStreaksCard = (streaksData, options = {}) => { + const { + user_name, + longest_streak_weekly, + current_streak_weekly, + longest_streak_daily, + current_streak_daily, + total_contributions, + } = streaksData; + const { + hide = [], + hide_border = false, + card_width, + line_height = 25, + title_color, + text_color, + text_bold = true, + bg_color, + theme = "default", + custom_title, + border_radius, + border_color, + number_format = "short", + locale, + disable_animations = false, + } = options; + + const lheight = String(parseInt(line_height), 10); + + const { titleColor, textColor, bgColor, borderColor } = getCardColors({ + title_color, + text_color, + bg_color, + border_color, + theme, + }); + + const apostrophe = ["x", "s"].includes(user_name.slice(-1)) ? "" : "s"; + + const i18n = new I18n({ + locale, + translations: streakCardLocales({ user_name, apostrophe }), + }); + + const STREAKS = {}; + + STREAKS.totalContributions = { + label: i18n.t("streakcard.totalcontributions"), + value: total_contributions, + id: "total contributions", + }; + + STREAKS.weeklyLongest = { + label: i18n.t("streakcard.longest"), + value: longest_streak_weekly + " weeks", + id: "weekly longest streak", + }; + + STREAKS.weeklyCurrent = { + label: i18n.t("streakcard.current"), + value: current_streak_weekly + " weeks", + id: "weekly current streak", + }; + + STREAKS.dailyLongest = { + label: i18n.t("streakcard.longest"), + value: longest_streak_daily + " days", + id: "daily longest streak", + }; + + STREAKS.dailyCurrent = { + label: i18n.t("streakcard.current"), + value: current_streak_daily + " days", + id: "daily longest streak", + }; + const longLocales = [ + "cn", + "es", + "fr", + "pt-br", + "ru", + "uk-ua", + "id", + "ml", + "my", + "pl", + "de", + "nl", + "zh-tw", + "uz", + ]; + const isLongLocale = locale ? longLocales.includes(locale) : false; + + const streakItems = Object.keys(STREAKS) + .filter((key) => !hide.includes(key)) + .map((key, index) => + // create the text nodes, and pass index so that we can calculate the line spacing + createTextNode({ + label: STREAKS[key].label, + value: STREAKS[key].value, + id: STREAKS[key].id, + index, + shiftValuePos: 79.01 + (isLongLocale ? 50 : 0), + bold: text_bold, + number_format, + }), + ); + + const cssStyles = getStyles({ + titleColor, + textColor, + }); + + let height = 45 + (streakItems.length + 1) * lheight; + + const minCardWidth = CARD_MIN_WIDTH; + const defaultCardWidth = CARD_DEFAULT_WIDTH; + let width = card_width + ? isNaN(card_width) + ? defaultCardWidth + : card_width + : defaultCardWidth; + if (width < minCardWidth) { + width = minCardWidth; + } + + const card = new Card({ + customTitle: custom_title, + defaultTitle: streakItems.length + ? i18n.t("streakcard.title") + : i18n.t("streakcard.title"), + width, + height, + border_radius, + colors: { + titleColor, + textColor, + bgColor, + borderColor, + }, + }); + + card.setHideBorder(hide_border); + card.setCSS(cssStyles); + + if (disable_animations) card.disableAnimations(); + + card.setAccessibilityLabel({ + title: `${card.title}`, + }); + + return card.render(` + + ${flexLayout({ + items: streakItems, + gap: Number(lheight), + direction: "column", + }).join("")} + + `); +}; + +export { renderStreaksCard }; +export default renderStreaksCard; diff --git a/src/common/utils.js b/src/common/utils.js index 4b5dced487453..351240f63646d 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -53,13 +53,23 @@ const encodeHTML = (str) => { /** * Retrieves num with suffix k(thousands) precise to 1 decimal if greater than 999. * - * @param {number} num The number to format. - * @returns {string|number} The formatted number. + * num The number to format. + * The formatted number. */ const kFormatter = (num) => { - return Math.abs(num) > 999 + /* return Math.abs(num) > 999 ? Math.sign(num) * parseFloat((Math.abs(num) / 1000).toFixed(1)) + "k" - : Math.sign(num) * Math.abs(num); + : Math.sign(num) * Math.abs(num); */ + + if (typeof num == "number") { + return Math.abs(num) > 999 + ? Math.sign(num) * parseFloat((Math.abs(num) / 1000).toFixed(1)) + "k" + : Math.sign(num) * Math.abs(num); + } + + if (typeof num == "string") { + return num; + } }; /** diff --git a/src/fetchers/streak-fetcher.js b/src/fetchers/streak-fetcher.js new file mode 100644 index 0000000000000..edad2c224ecf8 --- /dev/null +++ b/src/fetchers/streak-fetcher.js @@ -0,0 +1,123 @@ +import retryer from "../common/retryer.js"; +import { MissingParamError, request } from "../common/utils.js"; + +const QUERY = ` +query streakInfo($userName:String!) { + user(login: $userName){ + name + contributionsCollection { + contributionCalendar { + totalContributions + weeks { + contributionDays { + contributionCount + date + } + } + } + } + } +} +`; + +const fetcher = async (variables, token) => { + return await request( + { query: QUERY, variables }, + { Authorization: `token ${token}` }, + ); +}; + +/** + * + * @param {string} username GitHub username + */ + +const streakFetcher = async (username) => { + if (!username) throw new MissingParamError(["username"]); + + const res = await retryer(fetcher, { userName: username }); + const contribsData = + res.data.data.user.contributionsCollection.contributionCalendar; + + //Fetching contributions weekly + let contributionsCountWeekly = 0; + let contributionsListWeekly = []; + + for (let i in contribsData.weeks) { + for (let j in contribsData.weeks[i].contributionDays) { + contributionsCountWeekly += + contribsData.weeks[i].contributionDays[j].contributionCount; + } + + contributionsListWeekly.push(contributionsCountWeekly); + contributionsCountWeekly = 0; + } + + //Longest streak weekly + let longestStreak = 0; + let calcLongestStreakList = []; + + for (let i in contributionsListWeekly) { + if (contributionsListWeekly[i] > 0) { + longestStreak++; + calcLongestStreakList.push(longestStreak); + } + + if (contributionsListWeekly[i] == 0) longestStreak = 0; + } + + //Current streak weekly + let currentStreak = 0; + + for (let i in contributionsListWeekly) { + if (contributionsListWeekly[i] > 0) currentStreak++; + + if (contributionsListWeekly[i] == 0) currentStreak = 0; + } + + //Fetching contributions daily + let contributionsListDaily = []; + + for (let i in contribsData.weeks) { + for (let j in contribsData.weeks[i].contributionDays) { + contributionsListDaily.push( + contribsData.weeks[i].contributionDays[j].contributionCount, + ); + } + } + + //Longest streak daily + let longestStreakDaily = 0; + let calcLongestStreakListDaily = []; + + for (let i in contributionsListDaily) { + if (contributionsListDaily[i] > 0) { + longestStreakDaily++; + calcLongestStreakListDaily.push(longestStreakDaily); + } + + if (contributionsListDaily[i] == 0) longestStreakDaily = 0; + } + + //Current streak daily + let currentStreakDaily = 0; + + for (let i in contributionsListDaily) { + if (contributionsListDaily[i] > 0) currentStreakDaily++; + + if (contributionsListDaily[i] == 0) currentStreakDaily = 0; + } + + //Returning the streaks of the user + return { + user_name: res.data.data.user.name, + longest_streak_weekly: Math.max(...calcLongestStreakList), + current_streak_weekly: currentStreak, + longest_streak_daily: Math.max(...calcLongestStreakListDaily), + current_streak_daily: currentStreakDaily, + total_contributions: contribsData.totalContributions, + }; +}; + +export { streakFetcher }; +export default streakFetcher; diff --git a/src/translations.js b/src/translations.js index 1ced5f69263fd..a08a895194500 100644 --- a/src/translations.js +++ b/src/translations.js @@ -709,6 +709,110 @@ const wakatimeCardLocales = { }, }; +const streakCardLocales = ({ user_name, apostrophe }) => { + const encodedName = encodeHTML(user_name); + return { + "streakcard.title": { + ar: `${encodedName} احصائيات الخط`, + cn: `${encodedName} 连胜统计`, + "zh-tw": `${encodedName} 連勝統計`, + cs: ` ${encodedName} statistiky pruhů`, + de: `${encodedName + apostrophe} Streak-Statistiken`, + en: `${encodedName}'${apostrophe} Streak Stats`, + es: `estadísticas de racha de ${encodedName}`, + fr: `statistiques de séquence de ${encodedName}`, + hu: `${encodedName} sorozat statisztika`, + it: `statistiche delle serie consecutive di ${encodedName}`, + ja: `${encodedName} 連続統計`, + nl: `${encodedName}'${apostrophe} streak-statistieken`, + "pt-pt": `Estatísticas de sequência de ${encodedName}`, + "pt-br": `Estatísticas de sequência de ${encodedName}`, + el: `στατιστικά σερί του ${encodedName}`, + ru: `статистика полос ${encodedName}`, + id: `statistik beruntun ${encodedName}`, + ml: `${encodedName}'${apostrophe} സ്ട്രീക്ക് സ്ഥിതിവിവരക്കണക്കുകൾ`, + sk: `štatistiky série ${encodedName}`, + tr: `${encodedName} galibiyet serisi istatistikleri`, + pl: `statystyki serii ${encodedName}`, + vi: `số liệu thống kê liên tục ${encodedName}`, + }, + + "streakcard.totalcontributions": { + ar: "إجمالي المساهمات", + cn: "捐款总额", + "zh-tw": "捐款總額", + cs: "celkové příspěvky", + de: "Gesamtbeiträge", + en: "Total contributions", + es: "contribuciones totales", + fr: "cotisations totales", + hu: "teljes hozzájárulás", + it: "contributi totali", + ja: "寄付総額", + nl: "totale bijdragen", + "pt-pt": "contribuições totais", + "pt-br": "contribuições totais", + el: "συνολικές εισφορές", + ru: "общая сумма взносов", + id: "total kontribusi", + ml: "മൊത്തം സംഭാവനകൾ", + sk: "celkové príspevky", + tr: "toplam katkılar", + pl: "całkowite składki", + vi: "tổng đóng góp", + }, + + "streakcard.longest": { + ar: "أطول أثر", + cn: "最长连胜", + "zh-tw": "最長連勝", + cs: "nejdelší série", + de: "Längste Strähne", + en: "Longest Streak", + es: "Racha más larga", + fr: "La plus longue série", + hu: "leghosszabb sorozata", + it: "serie più lunga", + ja: "最長連続記録", + nl: "langste reeks", + "pt-pt": "sequência mais longa", + "pt-br": "sequência mais longa", + el: "μεγαλύτερο σερί", + ru: "самая длинная серия", + id: "pukulan terpanjang", + ml: "ഏറ്റവും ദൈർഘ്യമേറിയ സ്ട്രീക്ക്", + sk: "najdlhšia séria", + tr: "en uzun seri", + pl: "najdłuższa passa", + vi: "chuỗi dài nhất", + }, + + "streakcard.current": { + ar: "العلامة الحالية", + cn: "目前的连胜", + "zh-tw": "目前的連勝", + cs: "nuværende streak", + de: "aktuelle Serie", + en: "Current Streak", + fr: "séquence actuelle", + hu: "jelenlegi sorozat", + it: "serie attuale", + ja: "現在の連続", + nl: "huidige streep", + "pt-pt": "sequência atual", + "pt-br": "sequência atual", + el: "τρέχον σερί", + ru: "текущая полоса", + id: "rentetan saat ini", + ml: "നിലവിലെ സ്ട്രീക്ക്", + sk: "aktuálna séria", + tr: "mevcut seri", + pl: "obecna passa", + vi: "chuỗi hiện tại", + }, + }; +}; + const availableLocales = Object.keys(repoCardLocales["repocard.archived"]); /** @@ -728,4 +832,5 @@ export { repoCardLocales, statCardLocales, wakatimeCardLocales, + streakCardLocales, }; From c873703fed630a003253d8f347b4848cc25f139e Mon Sep 17 00:00:00 2001 From: Yaten Dhingra <129659514+yaten2302@users.noreply.github.com> Date: Mon, 23 Oct 2023 00:45:37 +0530 Subject: [PATCH 8/8] Update gist.js --- api/gist.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/gist.js b/api/gist.js index 1dbc5aeeddd53..9f2d17480cc4c 100644 --- a/api/gist.js +++ b/api/gist.js @@ -22,6 +22,7 @@ export default async (req, res) => { border_color, show_owner, hide_border, + card_width, } = req.query; res.setHeader("Content-Type", "image/svg+xml"); @@ -74,6 +75,7 @@ export default async (req, res) => { locale: locale ? locale.toLowerCase() : null, show_owner: parseBoolean(show_owner), hide_border: parseBoolean(hide_border), + card_width: parseInt(card_width), }), ); } catch (err) {