forked from mirrored/github-readme-stats
refactor: added i18n class to manage translation logic & improved code
This commit is contained in:
+5
-3
@@ -5,6 +5,7 @@ const {
|
||||
parseArray,
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
isLocaleAvailable,
|
||||
} = require("../src/common/utils");
|
||||
const fetchStats = require("../src/fetchers/stats-fetcher");
|
||||
const renderStatsCard = require("../src/cards/stats-card");
|
||||
@@ -28,7 +29,7 @@ module.exports = async (req, res) => {
|
||||
theme,
|
||||
cache_seconds,
|
||||
custom_title,
|
||||
lang,
|
||||
locale,
|
||||
} = req.query;
|
||||
let stats;
|
||||
|
||||
@@ -37,7 +38,8 @@ module.exports = async (req, res) => {
|
||||
if (blacklist.includes(username)) {
|
||||
return res.send(renderError("Something went wrong"));
|
||||
}
|
||||
if (lang && ![ "cn", "de", "en", "es", "fr", "it", "ja", "kr", "pt-br" ].includes(lang.toLowerCase())) {
|
||||
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
return res.send(renderError("Something went wrong", "Language not found"));
|
||||
}
|
||||
|
||||
@@ -71,7 +73,7 @@ module.exports = async (req, res) => {
|
||||
bg_color,
|
||||
theme,
|
||||
custom_title,
|
||||
lang: lang ? lang.toLowerCase() : null,
|
||||
locale: locale ? locale.toLowerCase() : null,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
|
||||
+4
-3
@@ -4,6 +4,7 @@ const {
|
||||
parseBoolean,
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
isLocaleAvailable,
|
||||
} = require("../src/common/utils");
|
||||
const fetchRepo = require("../src/fetchers/repo-fetcher");
|
||||
const renderRepoCard = require("../src/cards/repo-card");
|
||||
@@ -21,7 +22,7 @@ module.exports = async (req, res) => {
|
||||
theme,
|
||||
show_owner,
|
||||
cache_seconds,
|
||||
lang,
|
||||
locale,
|
||||
} = req.query;
|
||||
|
||||
let repoData;
|
||||
@@ -32,7 +33,7 @@ module.exports = async (req, res) => {
|
||||
return res.send(renderError("Something went wrong"));
|
||||
}
|
||||
|
||||
if (lang && ![ "cn", "de", "en", "es", "fr", "it", "ja", "kr", "pt-br" ].includes(lang.toLowerCase())) {
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
return res.send(renderError("Something went wrong", "Language not found"));
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ module.exports = async (req, res) => {
|
||||
bg_color,
|
||||
theme,
|
||||
show_owner: parseBoolean(show_owner),
|
||||
lang: lang ? lang.toLowerCase() : null,
|
||||
locale: locale ? locale.toLowerCase() : null,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
|
||||
+4
-3
@@ -5,6 +5,7 @@ const {
|
||||
parseBoolean,
|
||||
parseArray,
|
||||
CONSTANTS,
|
||||
isLocaleAvailable,
|
||||
} = require("../src/common/utils");
|
||||
const fetchTopLanguages = require("../src/fetchers/top-languages-fetcher");
|
||||
const renderTopLanguages = require("../src/cards/top-languages-card");
|
||||
@@ -26,7 +27,7 @@ module.exports = async (req, res) => {
|
||||
langs_count,
|
||||
exclude_repo,
|
||||
custom_title,
|
||||
lang,
|
||||
locale,
|
||||
} = req.query;
|
||||
let topLangs;
|
||||
|
||||
@@ -36,7 +37,7 @@ module.exports = async (req, res) => {
|
||||
return res.send(renderError("Something went wrong"));
|
||||
}
|
||||
|
||||
if (lang && ![ "cn", "de", "en", "es", "fr", "it", "ja", "kr", "pt-br" ].includes(lang.toLowerCase())) {
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
return res.send(renderError("Something went wrong", "Language not found"));
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ module.exports = async (req, res) => {
|
||||
bg_color,
|
||||
theme,
|
||||
layout,
|
||||
lang: lang ? lang.toLowerCase() : null,
|
||||
locale: locale ? locale.toLowerCase() : null,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
|
||||
+4
-3
@@ -4,6 +4,7 @@ const {
|
||||
parseBoolean,
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
isLocaleAvailable,
|
||||
} = require("../src/common/utils");
|
||||
const { fetchLast7Days } = require("../src/fetchers/wakatime-fetcher");
|
||||
const wakatimeCard = require("../src/cards/wakatime-card");
|
||||
@@ -22,12 +23,12 @@ module.exports = async (req, res) => {
|
||||
hide_title,
|
||||
hide_progress,
|
||||
custom_title,
|
||||
lang,
|
||||
locale,
|
||||
} = req.query;
|
||||
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
if (lang && ![ "cn", "de", "en", "es", "fr", "it", "ja", "kr", "pt-br" ].includes(lang.toLowerCase())) {
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
return res.send(renderError("Something went wrong", "Language not found"));
|
||||
}
|
||||
|
||||
@@ -58,7 +59,7 @@ module.exports = async (req, res) => {
|
||||
bg_color,
|
||||
theme,
|
||||
hide_progress,
|
||||
lang: lang ? lang.toLowerCase() : null,
|
||||
locale: locale ? locale.toLowerCase() : null,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
|
||||
+13
-31
@@ -1,3 +1,4 @@
|
||||
const toEmoji = require("emoji-name-map");
|
||||
const {
|
||||
kFormatter,
|
||||
encodeHTML,
|
||||
@@ -5,9 +6,10 @@ const {
|
||||
FlexLayout,
|
||||
wrapTextMultiline,
|
||||
} = require("../common/utils");
|
||||
const icons = require("../common/icons");
|
||||
const I18n = require("../common/I18n");
|
||||
const Card = require("../common/Card");
|
||||
const toEmoji = require("emoji-name-map");
|
||||
const icons = require("../common/icons");
|
||||
const { repoCardLocales } = require("../translations");
|
||||
|
||||
const renderRepoCard = (repo, options = {}) => {
|
||||
const {
|
||||
@@ -28,34 +30,9 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
bg_color,
|
||||
show_owner,
|
||||
theme = "default_repocard",
|
||||
lang = "en",
|
||||
locale,
|
||||
} = options;
|
||||
|
||||
const translations = {
|
||||
template: {
|
||||
cn: "模板",
|
||||
de: "Vorlage",
|
||||
en: "Template",
|
||||
es: "Modelo",
|
||||
fr: "Modèle",
|
||||
it: "Template",
|
||||
ja: "テンプレート",
|
||||
kr: "주형",
|
||||
"pt-br": "Modelo",
|
||||
},
|
||||
archived: {
|
||||
cn: "已封存",
|
||||
de: "Archiviert",
|
||||
en: "Archived",
|
||||
es: "Archivé",
|
||||
fr: "Archivé",
|
||||
it: "Archiviata",
|
||||
ja: "アーカイブ済み",
|
||||
kr: "보관 됨",
|
||||
"pt-br": "Arquivada",
|
||||
},
|
||||
};
|
||||
|
||||
const header = show_owner ? nameWithOwner : name;
|
||||
const langName = (primaryLanguage && primaryLanguage.name) || "Unspecified";
|
||||
const langColor = (primaryLanguage && primaryLanguage.color) || "#333";
|
||||
@@ -76,6 +53,11 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
const height =
|
||||
(descriptionLines > 1 ? 120 : 110) + descriptionLines * lineHeight;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: repoCardLocales,
|
||||
});
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||
title_color,
|
||||
@@ -89,7 +71,7 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
const totalForks = kFormatter(forkCount);
|
||||
|
||||
const getBadgeSVG = (label) => `
|
||||
<g data-testid="badge" class="badge" transform="translate(320, 38)">
|
||||
<g data-testid="badge" class="badge" transform="translate(320, -18)">
|
||||
<rect stroke="${textColor}" stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
|
||||
<text
|
||||
x="23" y="-5"
|
||||
@@ -158,9 +140,9 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
return card.render(`
|
||||
${
|
||||
isTemplate
|
||||
? getBadgeSVG(translations.template[lang] || "Template")
|
||||
? getBadgeSVG(i18n.t("repocard.template"))
|
||||
: isArchived
|
||||
? getBadgeSVG(translations.archived[lang] || "Archived")
|
||||
? getBadgeSVG(i18n.t("repocard.archived"))
|
||||
: ""
|
||||
}
|
||||
|
||||
|
||||
+16
-85
@@ -1,12 +1,9 @@
|
||||
const {
|
||||
kFormatter,
|
||||
getCardColors,
|
||||
FlexLayout,
|
||||
encodeHTML,
|
||||
} = require("../common/utils");
|
||||
const { getStyles } = require("../getStyles");
|
||||
const icons = require("../common/icons");
|
||||
const I18n = require("../common/I18n");
|
||||
const Card = require("../common/Card");
|
||||
const icons = require("../common/icons");
|
||||
const { getStyles } = require("../getStyles");
|
||||
const { statCardLocales } = require("../translations");
|
||||
const { kFormatter, getCardColors, FlexLayout } = require("../common/utils");
|
||||
|
||||
const createTextNode = ({
|
||||
icon,
|
||||
@@ -66,7 +63,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
bg_color,
|
||||
theme = "default",
|
||||
custom_title,
|
||||
lang = "en",
|
||||
locale,
|
||||
} = options;
|
||||
|
||||
const lheight = parseInt(line_height, 10);
|
||||
@@ -81,86 +78,22 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
});
|
||||
|
||||
const apostrophe = ["x", "s"].includes(name.slice(-1)) ? "" : "s";
|
||||
const translations = {
|
||||
title: {
|
||||
cn: `${encodeHTML(name)}的GitHub统计`,
|
||||
de: `${encodeHTML(name) + apostrophe} GitHub-Statistiken`,
|
||||
en: `${encodeHTML(name)}'${apostrophe} GitHub Stats`,
|
||||
es: `Estadísticas de GitHub de ${encodeHTML(name)}`,
|
||||
fr: `Statistiques GitHub de ${encodeHTML(name)}`,
|
||||
it: `Statistiche GitHub di ${encodeHTML(name)}`,
|
||||
ja: `${encodeHTML(name)}のGitHub統計`,
|
||||
kr: `${encodeHTML(name)}의 GitHub 통계`,
|
||||
"pt-br": `Estatísticas do GitHub de ${encodeHTML(name)}`,
|
||||
},
|
||||
stars: {
|
||||
cn: "总星数",
|
||||
de: "Sterne Insgesamt",
|
||||
en: "Total Stars",
|
||||
es: "Estrellas totales",
|
||||
fr: "Total d'étoiles",
|
||||
it: "Stelle totali",
|
||||
ja: "星の合計",
|
||||
kr: "총 별",
|
||||
"pt-br": "Total de estrelas",
|
||||
},
|
||||
commits: {
|
||||
cn: "总承诺",
|
||||
de: "Anzahl Commits",
|
||||
en: "Total Commits",
|
||||
es: "Compromisos totales",
|
||||
fr: "Total des engagements",
|
||||
it: "Commit totali",
|
||||
ja: "総コミット",
|
||||
kr: "총 커밋",
|
||||
"pt-br": "Total de compromissos",
|
||||
},
|
||||
prs: {
|
||||
cn: "总公关",
|
||||
de: "PRs Insgesamt",
|
||||
en: "Total PRs",
|
||||
es: "RP totales",
|
||||
fr: "Total des PR",
|
||||
it: "PR totali",
|
||||
ja: "合計PR",
|
||||
kr: "총 PR",
|
||||
"pt-br": "Total de PRs",
|
||||
},
|
||||
issues: {
|
||||
cn: "总发行量",
|
||||
de: "Anzahl Issues",
|
||||
en: "Total Issues",
|
||||
es: "Problemas totales",
|
||||
fr: "Nombre total de problèmes",
|
||||
it: "Segnalazioni totali",
|
||||
ja: "総問題",
|
||||
kr: "총 문제",
|
||||
"pt-br": "Total de problemas",
|
||||
},
|
||||
contribs: {
|
||||
cn: "有助于",
|
||||
de: "Beigetragen zu",
|
||||
en: "Contributed to",
|
||||
es: "Contribuido a",
|
||||
fr: "Contribué à",
|
||||
it: "Ha contribuito a",
|
||||
ja: "に貢献しました",
|
||||
kr: "에 기여하다",
|
||||
"pt-br": "Contribuiu para",
|
||||
},
|
||||
};
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: statCardLocales({ name, apostrophe }),
|
||||
});
|
||||
|
||||
// Meta data for creating text nodes with createTextNode function
|
||||
const STATS = {
|
||||
stars: {
|
||||
icon: icons.star,
|
||||
label: translations.stars[lang] || "Total Stars",
|
||||
label: i18n.t("statcard.totalstars"),
|
||||
value: totalStars,
|
||||
id: "stars",
|
||||
},
|
||||
commits: {
|
||||
icon: icons.commits,
|
||||
label: `${translations.commits[lang] || "Total Commits"}${
|
||||
label: `${i18n.t("statcard.commits")}${
|
||||
include_all_commits ? "" : ` (${new Date().getFullYear()})`
|
||||
}`,
|
||||
value: totalCommits,
|
||||
@@ -168,19 +101,19 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
},
|
||||
prs: {
|
||||
icon: icons.prs,
|
||||
label: translations.prs[lang] || "Total PRs",
|
||||
label: i18n.t("statcard.prs"),
|
||||
value: totalPRs,
|
||||
id: "prs",
|
||||
},
|
||||
issues: {
|
||||
icon: icons.issues,
|
||||
label: translations.issues[lang] || "Total Issues",
|
||||
label: i18n.t("statcard.issues"),
|
||||
value: totalIssues,
|
||||
id: "issues",
|
||||
},
|
||||
contribs: {
|
||||
icon: icons.contribs,
|
||||
label: translations.contribs[lang] || "Contributed to",
|
||||
label: i18n.t("statcard.contribs"),
|
||||
value: contributedTo,
|
||||
id: "contribs",
|
||||
},
|
||||
@@ -239,9 +172,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
|
||||
const card = new Card({
|
||||
customTitle: custom_title,
|
||||
defaultTitle:
|
||||
translations.title[lang] ||
|
||||
`${encodeHTML(name)}'${apostrophe} GitHub Stats`,
|
||||
defaultTitle: i18n.t("statcard.title"),
|
||||
width: 495,
|
||||
height,
|
||||
colors: {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
const Card = require("../common/Card");
|
||||
const { getCardColors, FlexLayout } = require("../common/utils");
|
||||
const { createProgressNode } = require("../common/createProgressNode");
|
||||
const { langCardLocales } = require("../translations");
|
||||
const I18n = require("../common/I18n");
|
||||
|
||||
const createProgressTextNode = ({ width, color, name, progress }) => {
|
||||
const paddingRight = 95;
|
||||
@@ -70,26 +72,17 @@ const renderTopLanguages = (topLangs, options = {}) => {
|
||||
theme,
|
||||
layout,
|
||||
custom_title,
|
||||
lang = "en",
|
||||
locale,
|
||||
} = options;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: langCardLocales,
|
||||
});
|
||||
|
||||
let langs = Object.values(topLangs);
|
||||
let langsToHide = {};
|
||||
|
||||
const translations = {
|
||||
title: {
|
||||
cn: "最常用的语言",
|
||||
de: "Meist verwendete Sprachen",
|
||||
en: "Most Used Languages",
|
||||
es: "Idiomas más usados",
|
||||
fr: "Langues les plus utilisées",
|
||||
it: "Linguaggi più utilizzati",
|
||||
ja: "最もよく使われる言語",
|
||||
kr: "가장 많이 사용되는 언어",
|
||||
"pt-br": "Línguas Mais Usadas",
|
||||
},
|
||||
};
|
||||
|
||||
// populate langsToHide map for quick lookup
|
||||
// while filtering out
|
||||
if (hide) {
|
||||
@@ -187,7 +180,7 @@ const renderTopLanguages = (topLangs, options = {}) => {
|
||||
|
||||
const card = new Card({
|
||||
customTitle: custom_title,
|
||||
defaultTitle: translations.title[lang] || "Most Used Languages",
|
||||
defaultTitle: i18n.t("langcard.title"),
|
||||
width,
|
||||
height,
|
||||
colors: {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
const Card = require("../common/Card");
|
||||
const I18n = require("../common/I18n");
|
||||
const { getStyles } = require("../getStyles");
|
||||
const { wakatimeCardLocales } = require("../translations");
|
||||
const { getCardColors, FlexLayout } = require("../common/utils");
|
||||
const { createProgressNode } = require("../common/createProgressNode");
|
||||
|
||||
@@ -60,33 +62,13 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
theme = "default",
|
||||
hide_progress,
|
||||
custom_title,
|
||||
lang = "en",
|
||||
locale,
|
||||
} = options;
|
||||
|
||||
const translations = {
|
||||
title: {
|
||||
cn: "Wakatime周统计",
|
||||
de: "Wakatime Wochen Status",
|
||||
en: "Wakatime Week Stats",
|
||||
es: "Estadísticas de la semana de Wakatime",
|
||||
fr: "Statistiques de la semaine Wakatime",
|
||||
it: "Statistiche della settimana di Wakatime",
|
||||
ja: "ワカタイムウィーク統計",
|
||||
kr: "Wakatime 주간 통계",
|
||||
"pt-br": "Estatísticas da semana Wakatime",
|
||||
},
|
||||
noCodingActivity: {
|
||||
cn: "本周没有编码活动",
|
||||
de: "Keine Codierungsaktivität diese Woche",
|
||||
en: "No coding activity this week",
|
||||
es: "No hay actividad de codificación esta semana",
|
||||
fr: "Aucune activité de codage cette semaine",
|
||||
it: "Nessuna attività in questa settimana",
|
||||
ja: "今週のコーディング活動はありません",
|
||||
kr: "이번 주 코딩 활동 없음",
|
||||
"pt-br": "Nenhuma atividade de codificação esta semana",
|
||||
},
|
||||
};
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: wakatimeCardLocales,
|
||||
});
|
||||
|
||||
const lheight = parseInt(line_height, 10);
|
||||
|
||||
@@ -127,7 +109,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
|
||||
const card = new Card({
|
||||
customTitle: custom_title,
|
||||
defaultTitle: translations.title[lang] || "Wakatime Week Stats",
|
||||
defaultTitle: i18n.t("wakatimecard.title"),
|
||||
width: 495,
|
||||
height,
|
||||
colors: {
|
||||
@@ -155,9 +137,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
: [
|
||||
noCodingActivityNode({
|
||||
color: textColor,
|
||||
text:
|
||||
translations.noCodingActivity[lang] ||
|
||||
"No coding activity this week",
|
||||
text: i18n.t("wakatimecard.nocodingactivity"),
|
||||
}),
|
||||
],
|
||||
gap: lheight,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
class I18n {
|
||||
constructor({ locale, translations }) {
|
||||
this.locale = locale;
|
||||
this.translations = translations;
|
||||
this.fallbackLocale = "en";
|
||||
}
|
||||
|
||||
t(str) {
|
||||
if (!this.translations[str]) {
|
||||
throw new Error(`${str} Translation string not found`);
|
||||
}
|
||||
|
||||
if (!this.translations[str][this.locale || this.fallbackLocale]) {
|
||||
throw new Error(`${str} Translation locale not found`);
|
||||
}
|
||||
|
||||
return this.translations[str][this.locale || this.fallbackLocale];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = I18n;
|
||||
@@ -188,6 +188,12 @@ class CustomError extends Error {
|
||||
static USER_NOT_FOUND = "USER_NOT_FOUND";
|
||||
}
|
||||
|
||||
function isLocaleAvailable(locale) {
|
||||
return ["cn", "de", "en", "es", "fr", "it", "ja", "kr", "pt-br"].includes(
|
||||
locale.toLowerCase(),
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
renderError,
|
||||
kFormatter,
|
||||
@@ -201,6 +207,7 @@ module.exports = {
|
||||
getCardColors,
|
||||
clampValue,
|
||||
wrapTextMultiline,
|
||||
isLocaleAvailable,
|
||||
logger,
|
||||
CONSTANTS,
|
||||
CustomError,
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
const { encodeHTML } = require("./common/utils");
|
||||
|
||||
const statCardLocales = ({ name, apostrophe }) => {
|
||||
return {
|
||||
"statcard.title": {
|
||||
cn: `${encodeHTML(name)}的GitHub统计`,
|
||||
de: `${encodeHTML(name) + apostrophe} GitHub-Statistiken`,
|
||||
en: `${encodeHTML(name)}'${apostrophe} GitHub Stats`,
|
||||
es: `Estadísticas de GitHub de ${encodeHTML(name)}`,
|
||||
fr: `Statistiques GitHub de ${encodeHTML(name)}`,
|
||||
it: `Statistiche GitHub di ${encodeHTML(name)}`,
|
||||
ja: `${encodeHTML(name)}のGitHub統計`,
|
||||
kr: `${encodeHTML(name)}의 GitHub 통계`,
|
||||
"pt-br": `Estatísticas do GitHub de ${encodeHTML(name)}`,
|
||||
},
|
||||
"statcard.totalstars": {
|
||||
cn: "总星数",
|
||||
de: "Sterne Insgesamt",
|
||||
en: "Total Stars",
|
||||
es: "Estrellas totales",
|
||||
fr: "Total d'étoiles",
|
||||
it: "Stelle totali",
|
||||
ja: "星の合計",
|
||||
kr: "총 별",
|
||||
"pt-br": "Total de estrelas",
|
||||
},
|
||||
"statcard.commits": {
|
||||
cn: "总承诺",
|
||||
de: "Anzahl Commits",
|
||||
en: "Total Commits",
|
||||
es: "Compromisos totales",
|
||||
fr: "Total des engagements",
|
||||
it: "Commit totali",
|
||||
ja: "総コミット",
|
||||
kr: "총 커밋",
|
||||
"pt-br": "Total de compromissos",
|
||||
},
|
||||
"statcard.prs": {
|
||||
cn: "总公关",
|
||||
de: "PRs Insgesamt",
|
||||
en: "Total PRs",
|
||||
es: "RP totales",
|
||||
fr: "Total des PR",
|
||||
it: "PR totali",
|
||||
ja: "合計PR",
|
||||
kr: "총 PR",
|
||||
"pt-br": "Total de PRs",
|
||||
},
|
||||
"statcard.issues": {
|
||||
cn: "总发行量",
|
||||
de: "Anzahl Issues",
|
||||
en: "Total Issues",
|
||||
es: "Problemas totales",
|
||||
fr: "Nombre total de problèmes",
|
||||
it: "Segnalazioni totali",
|
||||
ja: "総問題",
|
||||
kr: "총 문제",
|
||||
"pt-br": "Total de problemas",
|
||||
},
|
||||
"statcard.contribs": {
|
||||
cn: "有助于",
|
||||
de: "Beigetragen zu",
|
||||
en: "Contributed to",
|
||||
es: "Contribuido a",
|
||||
fr: "Contribué à",
|
||||
it: "Ha contribuito a",
|
||||
ja: "に貢献しました",
|
||||
kr: "에 기여하다",
|
||||
"pt-br": "Contribuiu para",
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const repoCardLocales = {
|
||||
"repocard.template": {
|
||||
cn: "模板",
|
||||
de: "Vorlage",
|
||||
en: "Template",
|
||||
es: "Modelo",
|
||||
fr: "Modèle",
|
||||
it: "Template",
|
||||
ja: "テンプレート",
|
||||
kr: "주형",
|
||||
"pt-br": "Modelo",
|
||||
},
|
||||
"repocard.archived": {
|
||||
cn: "已封存",
|
||||
de: "Archiviert",
|
||||
en: "Archived",
|
||||
es: "Archivé",
|
||||
fr: "Archivé",
|
||||
it: "Archiviata",
|
||||
ja: "アーカイブ済み",
|
||||
kr: "보관 됨",
|
||||
"pt-br": "Arquivada",
|
||||
},
|
||||
};
|
||||
|
||||
const langCardLocales = {
|
||||
"langcard.title": {
|
||||
cn: "最常用的语言",
|
||||
de: "Meist verwendete Sprachen",
|
||||
en: "Most Used Languages",
|
||||
es: "Idiomas más usados",
|
||||
fr: "Langues les plus utilisées",
|
||||
it: "Linguaggi più utilizzati",
|
||||
ja: "最もよく使われる言語",
|
||||
kr: "가장 많이 사용되는 언어",
|
||||
"pt-br": "Línguas Mais Usadas",
|
||||
},
|
||||
};
|
||||
|
||||
const wakatimeCardLocales = {
|
||||
"wakatimecard.title": {
|
||||
cn: "Wakatime周统计",
|
||||
de: "Wakatime Wochen Status",
|
||||
en: "Wakatime Week Stats",
|
||||
es: "Estadísticas de la semana de Wakatime",
|
||||
fr: "Statistiques de la semaine Wakatime",
|
||||
it: "Statistiche della settimana di Wakatime",
|
||||
ja: "ワカタイムウィーク統計",
|
||||
kr: "Wakatime 주간 통계",
|
||||
"pt-br": "Estatísticas da semana Wakatime",
|
||||
},
|
||||
"wakatimecard.nocodingactivity": {
|
||||
cn: "本周没有编码活动",
|
||||
de: "Keine Codierungsaktivität diese Woche",
|
||||
en: "No coding activity this week",
|
||||
es: "No hay actividad de codificación esta semana",
|
||||
fr: "Aucune activité de codage cette semaine",
|
||||
it: "Nessuna attività in questa settimana",
|
||||
ja: "今週のコーディング活動はありません",
|
||||
kr: "이번 주 코딩 활동 없음",
|
||||
"pt-br": "Nenhuma atividade de codificação esta semana",
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
statCardLocales,
|
||||
repoCardLocales,
|
||||
langCardLocales,
|
||||
wakatimeCardLocales,
|
||||
};
|
||||
@@ -309,21 +309,27 @@ describe("Test renderRepoCard", () => {
|
||||
});
|
||||
|
||||
it("should render translated badges", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
isArchived: true,
|
||||
}, {
|
||||
lang: 'cn'
|
||||
});
|
||||
document.body.innerHTML = renderRepoCard(
|
||||
{
|
||||
...data_repo.repository,
|
||||
isArchived: true,
|
||||
},
|
||||
{
|
||||
locale: "cn",
|
||||
},
|
||||
);
|
||||
|
||||
expect(queryByTestId(document.body, "badge")).toHaveTextContent("已封存");
|
||||
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
isTemplate: true,
|
||||
}, {
|
||||
lang: 'cn'
|
||||
});
|
||||
document.body.innerHTML = renderRepoCard(
|
||||
{
|
||||
...data_repo.repository,
|
||||
isTemplate: true,
|
||||
},
|
||||
{
|
||||
locale: "cn",
|
||||
},
|
||||
);
|
||||
expect(queryByTestId(document.body, "badge")).toHaveTextContent("模板");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -211,12 +211,34 @@ describe("Test renderStatsCard", () => {
|
||||
});
|
||||
|
||||
it("should render translations", () => {
|
||||
document.body.innerHTML = renderStatsCard(stats, { lang: "cn" })
|
||||
expect(document.getElementsByClassName("header")[0].textContent).toBe("Anurag Hazra的GitHub统计");
|
||||
expect(document.querySelector("g[transform=\"translate(0, 0)\"]>.stagger>.stat.bold").textContent).toBe("总星数:");
|
||||
expect(document.querySelector("g[transform=\"translate(0, 25)\"]>.stagger>.stat.bold").textContent).toBe("总承诺 (2020):");
|
||||
expect(document.querySelector("g[transform=\"translate(0, 50)\"]>.stagger>.stat.bold").textContent).toBe("总公关:");
|
||||
expect(document.querySelector("g[transform=\"translate(0, 75)\"]>.stagger>.stat.bold").textContent).toBe("总发行量:");
|
||||
expect(document.querySelector("g[transform=\"translate(0, 100)\"]>.stagger>.stat.bold").textContent).toBe("有助于:");
|
||||
})
|
||||
document.body.innerHTML = renderStatsCard(stats, { locale: "cn" });
|
||||
expect(document.getElementsByClassName("header")[0].textContent).toBe(
|
||||
"Anurag Hazra的GitHub统计",
|
||||
);
|
||||
expect(
|
||||
document.querySelector(
|
||||
'g[transform="translate(0, 0)"]>.stagger>.stat.bold',
|
||||
).textContent,
|
||||
).toBe("总星数:");
|
||||
expect(
|
||||
document.querySelector(
|
||||
'g[transform="translate(0, 25)"]>.stagger>.stat.bold',
|
||||
).textContent,
|
||||
).toBe("总承诺 (2020):");
|
||||
expect(
|
||||
document.querySelector(
|
||||
'g[transform="translate(0, 50)"]>.stagger>.stat.bold',
|
||||
).textContent,
|
||||
).toBe("总公关:");
|
||||
expect(
|
||||
document.querySelector(
|
||||
'g[transform="translate(0, 75)"]>.stagger>.stat.bold',
|
||||
).textContent,
|
||||
).toBe("总发行量:");
|
||||
expect(
|
||||
document.querySelector(
|
||||
'g[transform="translate(0, 100)"]>.stagger>.stat.bold',
|
||||
).textContent,
|
||||
).toBe("有助于:");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -218,7 +218,9 @@ describe("Test renderTopLanguages", () => {
|
||||
});
|
||||
|
||||
it("should render a translated title", () => {
|
||||
document.body.innerHTML = renderTopLanguages(langs, { lang: "cn" })
|
||||
expect(document.getElementsByClassName("header")[0].textContent).toBe("最常用的语言")
|
||||
document.body.innerHTML = renderTopLanguages(langs, { locale: "cn" });
|
||||
expect(document.getElementsByClassName("header")[0].textContent).toBe(
|
||||
"最常用的语言",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -113,9 +113,15 @@ describe("Test Render Wakatime Card", () => {
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it("should render translations", () => {
|
||||
document.body.innerHTML = renderWakatimeCard({}, {lang: "cn"})
|
||||
expect(document.getElementsByClassName("header")[0].textContent).toBe("Wakatime周统计")
|
||||
expect(document.querySelector("g[transform=\"translate(0, 0)\"]>text.stat.bold").textContent).toBe("本周没有编码活动")
|
||||
})
|
||||
document.body.innerHTML = renderWakatimeCard({}, { locale: "cn" });
|
||||
expect(document.getElementsByClassName("header")[0].textContent).toBe(
|
||||
"Wakatime周统计",
|
||||
);
|
||||
expect(
|
||||
document.querySelector('g[transform="translate(0, 0)"]>text.stat.bold')
|
||||
.textContent,
|
||||
).toBe("本周没有编码活动");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user