diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js index c6cedb1..92f5b9d 100644 --- a/src/cards/top-languages-card.js +++ b/src/cards/top-languages-card.js @@ -17,6 +17,7 @@ const MIN_CARD_WIDTH = 280; const DEFAULT_LANGS_COUNT = 5; const DEFAULT_LANG_COLOR = "#858585"; const CARD_PADDING = 25; +const COMPACT_LAYOUT_BASE_HEIGHT = 90; /** * @typedef {import("../fetchers/types").Lang} Lang @@ -101,7 +102,7 @@ const getCircleLength = (radius) => { * @returns {number} Card height. */ const calculateCompactLayoutHeight = (totalLangs) => { - return 90 + Math.round(totalLangs / 2) * 25; + return COMPACT_LAYOUT_BASE_HEIGHT + Math.round(totalLangs / 2) * 25; }; /** @@ -654,6 +655,19 @@ const renderDonutLayout = (langs, width, totalLanguageSize) => { `; }; +/** + * Creates the no coding activity SVG node. + * + * @param {{color: string, text: string, layout: import("./types").TopLangOptions["layout"]}} The function prop + */ +const noLanguagesDataNode = ({ color, text, layout }) => { + return ` + ${text} + `; +}; + /** * Renders card that display user's most frequently used programming languages. * @@ -699,8 +713,24 @@ const renderTopLanguages = (topLangs, options = {}) => { : card_width; let height = calculateNormalLayoutHeight(langs.length); + // returns theme based colors with proper overrides and defaults + const colors = getCardColors({ + title_color, + text_color, + bg_color, + border_color, + theme, + }); + let finalLayout = ""; - if (layout === "pie") { + if (langs.length === 0) { + height = COMPACT_LAYOUT_BASE_HEIGHT; + finalLayout = noLanguagesDataNode({ + color: colors.textColor, + text: i18n.t("langcard.nodata"), + layout, + }); + } else if (layout === "pie") { height = calculatePieLayoutHeight(langs.length); finalLayout = renderPieLayout(langs, totalLanguageSize); } else if (layout === "donut-vertical") { @@ -724,15 +754,6 @@ const renderTopLanguages = (topLangs, options = {}) => { finalLayout = renderNormalLayout(langs, width, totalLanguageSize); } - // returns theme based colors with proper overrides and defaults - const colors = getCardColors({ - title_color, - text_color, - bg_color, - border_color, - theme, - }); - const card = new Card({ customTitle: custom_title, defaultTitle: i18n.t("langcard.title"), @@ -764,6 +785,14 @@ const renderTopLanguages = (topLangs, options = {}) => { width: 100%; } } + .stat { + font: 600 14px 'Segoe UI', Ubuntu, "Helvetica Neue", Sans-Serif; fill: ${colors.textColor}; + } + @supports(-moz-appearance: auto) { + /* Selector detects Firefox */ + .stat { font-size:12px; } + } + .bold { font-weight: 700 } .lang-name { font: 400 11px "Segoe UI", Ubuntu, Sans-Serif; fill: ${colors.textColor}; diff --git a/src/translations.js b/src/translations.js index 92a6fc5..51fc6aa 100644 --- a/src/translations.js +++ b/src/translations.js @@ -293,6 +293,36 @@ const langCardLocales = { vi: "Ngôn Ngữ Thường Sử Dụng", se: "Mest använda språken", }, + "langcard.nodata": { + ar: "لا توجد بيانات لغات.", + cn: "沒有語言數據。", + "zh-tw": "沒有語言數據。", + cs: "Žádné jazykové údaje.", + de: "Keine Sprachdaten.", + bn: "কোন ভাষার ডেটা নেই।", + en: "No languages data.", + es: "Sin datos de idiomas.", + fr: "Aucune donnée sur les langues.", + hu: "Nincsenek nyelvi adatok.", + it: "Nessun dato sulle lingue.", + ja: "言語データがありません。", + kr: "언어 데이터가 없습니다.", + nl: "Ingen sprogdata.", + "pt-pt": "Sem dados de idiomas.", + "pt-br": "Sem dados de idiomas.", + np: "कुनै भाषा डाटा छैन।", + el: "Δεν υπάρχουν δεδομένα γλωσσών.", + ru: "Нет данных о языках.", + "uk-ua": "Немає даних про мови.", + id: "Tidak ada data bahasa.", + ml: "ഭാഷാ ഡാറ്റയില്ല.", + my: "Tiada data bahasa.", + sk: "Žiadne údaje o jazykoch.", + tr: "Dil verisi yok.", + pl: "Brak danych dotyczących języków.", + vi: "Không có dữ liệu ngôn ngữ.", + se: "Inga språkdata.", + }, }; const wakatimeCardLocales = {