@stats-forge/github-stats-forge-core 0.0.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -10
- package/build/api/api-result.d.ts +6 -7
- package/build/api/api-result.d.ts.map +1 -1
- package/build/api/api-result.js +4 -5
- package/build/api/contributed-to.d.ts +23 -0
- package/build/api/contributed-to.d.ts.map +1 -0
- package/build/api/contributed-to.js +43 -0
- package/build/api/gist.d.ts +8 -22
- package/build/api/gist.d.ts.map +1 -1
- package/build/api/gist.js +14 -36
- package/build/api/handler.d.ts +16 -0
- package/build/api/handler.d.ts.map +1 -0
- package/build/api/handler.js +29 -0
- package/build/api/index.d.ts +13 -12
- package/build/api/index.d.ts.map +1 -1
- package/build/api/index.js +1 -0
- package/build/api/params.d.ts +21 -12
- package/build/api/params.d.ts.map +1 -1
- package/build/api/params.js +41 -19
- package/build/api/pin.d.ts +11 -31
- package/build/api/pin.d.ts.map +1 -1
- package/build/api/pin.js +35 -63
- package/build/api/stats.d.ts +15 -16
- package/build/api/stats.d.ts.map +1 -1
- package/build/api/stats.js +60 -99
- package/build/api/top-langs.d.ts +13 -18
- package/build/api/top-langs.d.ts.map +1 -1
- package/build/api/top-langs.js +35 -72
- package/build/api/wakatime.d.ts +11 -17
- package/build/api/wakatime.d.ts.map +1 -1
- package/build/api/wakatime.js +27 -64
- package/build/calculateRank.d.ts +0 -9
- package/build/calculateRank.d.ts.map +1 -1
- package/build/calculateRank.js +12 -17
- package/build/cards/contributed-to.d.ts +19 -0
- package/build/cards/contributed-to.d.ts.map +1 -0
- package/build/cards/contributed-to.js +242 -0
- package/build/cards/gist.d.ts +3 -4
- package/build/cards/gist.d.ts.map +1 -1
- package/build/cards/gist.js +38 -43
- package/build/cards/options.d.ts +1 -1
- package/build/cards/repo.d.ts +14 -5
- package/build/cards/repo.d.ts.map +1 -1
- package/build/cards/repo.js +93 -103
- package/build/cards/stats.d.ts +18 -11
- package/build/cards/stats.d.ts.map +1 -1
- package/build/cards/stats.js +191 -222
- package/build/cards/top-languages.d.ts +18 -33
- package/build/cards/top-languages.d.ts.map +1 -1
- package/build/cards/top-languages.js +196 -387
- package/build/cards/wakatime.d.ts +17 -8
- package/build/cards/wakatime.d.ts.map +1 -1
- package/build/cards/wakatime.js +133 -187
- package/build/common/Card.d.ts +20 -59
- package/build/common/Card.d.ts.map +1 -1
- package/build/common/Card.js +131 -198
- package/build/common/I18n.d.ts +1 -7
- package/build/common/I18n.d.ts.map +1 -1
- package/build/common/I18n.js +7 -8
- package/build/common/brand.d.ts +76 -0
- package/build/common/brand.d.ts.map +1 -0
- package/build/common/brand.js +73 -0
- package/build/common/color.d.ts +4 -17
- package/build/common/color.d.ts.map +1 -1
- package/build/common/color.js +67 -49
- package/build/common/config.d.ts +4 -14
- package/build/common/config.d.ts.map +1 -1
- package/build/common/config.js +3 -16
- package/build/common/constants.d.ts +6 -2
- package/build/common/constants.d.ts.map +1 -1
- package/build/common/constants.js +5 -1
- package/build/common/date.d.ts +50 -5
- package/build/common/date.d.ts.map +1 -1
- package/build/common/date.js +104 -4
- package/build/common/emojiMap.d.ts +8 -0
- package/build/common/emojiMap.d.ts.map +1 -0
- package/build/common/emojiMap.js +10 -0
- package/build/common/emojiMap.json +1915 -0
- package/build/common/error.d.ts +1 -10
- package/build/common/error.d.ts.map +1 -1
- package/build/common/error.js +1 -10
- package/build/common/fmt.d.ts +3 -15
- package/build/common/fmt.d.ts.map +1 -1
- package/build/common/fmt.js +7 -35
- package/build/common/http.d.ts +2 -7
- package/build/common/http.d.ts.map +1 -1
- package/build/common/http.js +8 -17
- package/build/common/icons.d.ts +20 -20
- package/build/common/icons.d.ts.map +1 -1
- package/build/common/icons.js +108 -67
- package/build/common/languageColors.d.ts +0 -1
- package/build/common/languageColors.d.ts.map +1 -1
- package/build/common/languageColors.js +1 -4
- package/build/common/languageColors.json +18 -2
- package/build/common/ops.d.ts +11 -17
- package/build/common/ops.d.ts.map +1 -1
- package/build/common/ops.js +22 -39
- package/build/common/render.d.ts +34 -82
- package/build/common/render.d.ts.map +1 -1
- package/build/common/render.js +225 -259
- package/build/common/retryer.d.ts +2 -7
- package/build/common/retryer.d.ts.map +1 -1
- package/build/common/retryer.js +4 -11
- package/build/fetchers/contributed-to.d.ts +62 -0
- package/build/fetchers/contributed-to.d.ts.map +1 -0
- package/build/fetchers/contributed-to.js +184 -0
- package/build/fetchers/gist.d.ts +2 -5
- package/build/fetchers/gist.d.ts.map +1 -1
- package/build/fetchers/gist.js +1 -5
- package/build/fetchers/graphql-error.d.ts +13 -0
- package/build/fetchers/graphql-error.d.ts.map +1 -0
- package/build/fetchers/graphql-error.js +29 -0
- package/build/fetchers/index.d.ts +13 -12
- package/build/fetchers/index.d.ts.map +1 -1
- package/build/fetchers/index.js +1 -0
- package/build/fetchers/repo.d.ts +2 -11
- package/build/fetchers/repo.d.ts.map +1 -1
- package/build/fetchers/repo.js +20 -33
- package/build/fetchers/stats.d.ts +16 -40
- package/build/fetchers/stats.d.ts.map +1 -1
- package/build/fetchers/stats.js +89 -271
- package/build/fetchers/top-languages.d.ts +2 -9
- package/build/fetchers/top-languages.d.ts.map +1 -1
- package/build/fetchers/top-languages.js +16 -47
- package/build/fetchers/types.d.ts +25 -1
- package/build/fetchers/types.d.ts.map +1 -1
- package/build/fetchers/wakatime.d.ts +2 -6
- package/build/fetchers/wakatime.d.ts.map +1 -1
- package/build/fetchers/wakatime.js +1 -5
- package/build/graphql/contributionsCollection.d.ts +9 -0
- package/build/graphql/contributionsCollection.d.ts.map +1 -0
- package/build/graphql/contributionsCollection.js +12 -0
- package/build/graphql/contributionsDocument.d.ts +6 -6
- package/build/graphql/contributionsDocument.d.ts.map +1 -1
- package/build/graphql/contributionsDocument.js +8 -16
- package/build/graphql/generated/contributed-to.d.ts +22 -0
- package/build/graphql/generated/contributed-to.d.ts.map +1 -0
- package/build/graphql/generated/contributed-to.js +11 -0
- package/build/graphql/generated/gist.d.ts +1 -1
- package/build/graphql/generated/repo.d.ts +1 -1
- package/build/graphql/generated/stats.d.ts +16 -4
- package/build/graphql/generated/stats.d.ts.map +1 -1
- package/build/graphql/generated/stats.js +2 -2
- package/build/graphql/generated/top-languages.d.ts +2 -2
- package/build/graphql/graphqlDocument.d.ts +1 -2
- package/build/graphql/graphqlDocument.d.ts.map +1 -1
- package/build/graphql/graphqlDocument.js +0 -1
- package/build/graphql/reposContributedToDocument.d.ts +4 -5
- package/build/graphql/reposContributedToDocument.d.ts.map +1 -1
- package/build/graphql/reposContributedToDocument.js +11 -7
- package/build/markup/css.d.ts +35 -0
- package/build/markup/css.d.ts.map +1 -0
- package/build/markup/css.js +64 -0
- package/build/markup/element.d.ts +41 -0
- package/build/markup/element.d.ts.map +1 -0
- package/build/markup/element.js +127 -0
- package/build/markup/html.d.ts +13 -0
- package/build/markup/html.d.ts.map +1 -0
- package/build/markup/html.js +27 -0
- package/build/markup/index.d.ts +9 -0
- package/build/markup/index.d.ts.map +1 -0
- package/build/markup/index.js +6 -0
- package/build/markup/serialize.d.ts +16 -0
- package/build/markup/serialize.d.ts.map +1 -0
- package/build/markup/serialize.js +17 -0
- package/build/themes/index.d.ts +332 -333
- package/build/themes/index.d.ts.map +1 -1
- package/build/themes/index.js +1 -1
- package/build/translations.d.ts +66 -7
- package/build/translations.d.ts.map +1 -1
- package/build/translations.js +686 -629
- package/package.json +17 -26
- package/src/api/api-result.ts +10 -9
- package/src/api/contributed-to.ts +84 -0
- package/src/api/gist.ts +22 -46
- package/src/api/handler.ts +42 -0
- package/src/api/index.ts +13 -12
- package/src/api/params.ts +74 -29
- package/src/api/pin.ts +38 -65
- package/src/api/stats.ts +81 -118
- package/src/api/top-langs.ts +38 -80
- package/src/api/wakatime.ts +35 -73
- package/src/calculateRank.ts +12 -23
- package/src/cards/contributed-to.ts +373 -0
- package/src/cards/gist.ts +55 -49
- package/src/cards/options.ts +1 -1
- package/src/cards/repo.ts +134 -120
- package/src/cards/stats.ts +262 -252
- package/src/cards/top-languages.ts +315 -422
- package/src/cards/wakatime.ts +207 -225
- package/src/common/Card.ts +207 -214
- package/src/common/I18n.ts +7 -8
- package/src/common/brand.ts +109 -0
- package/src/common/color.ts +80 -57
- package/src/common/config.ts +5 -18
- package/src/common/constants.ts +8 -2
- package/src/common/date.ts +135 -5
- package/src/common/emojiMap.json +1915 -0
- package/src/common/emojiMap.ts +13 -0
- package/src/common/error.ts +2 -11
- package/src/common/fmt.ts +7 -44
- package/src/common/http.ts +9 -15
- package/src/common/icons.ts +122 -42
- package/src/common/languageColors.json +18 -2
- package/src/common/languageColors.ts +1 -4
- package/src/common/ops.ts +31 -48
- package/src/common/render.ts +334 -284
- package/src/common/retryer.ts +8 -15
- package/src/fetchers/contributed-to.ts +271 -0
- package/src/fetchers/gist.ts +8 -12
- package/src/fetchers/graphql-error.ts +36 -0
- package/src/fetchers/index.ts +15 -12
- package/src/fetchers/repo.ts +27 -40
- package/src/fetchers/stats.ts +157 -366
- package/src/fetchers/top-languages.ts +27 -55
- package/src/fetchers/types.ts +27 -1
- package/src/fetchers/wakatime.ts +5 -9
- package/src/graphql/contributionsCollection.ts +18 -0
- package/src/graphql/contributionsDocument.ts +14 -19
- package/src/graphql/generated/contributed-to.ts +25 -0
- package/src/graphql/generated/gist.ts +1 -1
- package/src/graphql/generated/repo.ts +1 -1
- package/src/graphql/generated/stats.ts +21 -8
- package/src/graphql/generated/top-languages.ts +2 -2
- package/src/graphql/graphqlDocument.ts +1 -2
- package/src/graphql/queries/contributed-to.graphql +8 -0
- package/src/graphql/queries/stats.graphql +14 -2
- package/src/graphql/reposContributedToDocument.ts +16 -15
- package/src/markup/css.ts +118 -0
- package/src/markup/element.ts +246 -0
- package/src/markup/html.ts +34 -0
- package/src/markup/index.ts +9 -0
- package/src/markup/serialize.ts +27 -0
- package/src/themes/index.ts +1 -1
- package/src/translations.ts +699 -629
- package/build/cards/index.d.ts +0 -11
- package/build/cards/index.d.ts.map +0 -1
- package/build/cards/index.js +0 -7
- package/build/common/html.d.ts +0 -8
- package/build/common/html.d.ts.map +0 -1
- package/build/common/html.js +0 -14
- package/build/index.d.ts +0 -15
- package/build/index.d.ts.map +0 -1
- package/build/index.js +0 -10
- package/src/_emoji-name-map.d.ts +0 -10
- package/src/_github-username-regex.d.ts +0 -4
- package/src/cards/index.ts +0 -21
- package/src/common/html.ts +0 -17
- package/src/index.ts +0 -18
package/build/api/wakatime.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as z from 'zod/mini';
|
|
2
|
-
import {
|
|
2
|
+
import { renderWakatimeCard } from '../cards/wakatime.js';
|
|
3
3
|
import { fetchWakatimeStats } from '../fetchers/wakatime.js';
|
|
4
|
-
import {
|
|
5
|
-
import { booleanParam, enumParam, listParam, localeParam, looseIntParam, numberParam,
|
|
4
|
+
import { cardHandler } from './handler.js';
|
|
5
|
+
import { booleanParam, enumParam, listParam, localeParam, looseIntParam, numberParam, rawParam, safeParam, } from './params.js';
|
|
6
6
|
/** What the wakatime endpoint accepts, on top of the shared color params. */
|
|
7
7
|
const wakatimeQuery = z.object({
|
|
8
8
|
username: safeParam,
|
|
@@ -13,12 +13,12 @@ const wakatimeQuery = z.object({
|
|
|
13
13
|
hide_progress: booleanParam,
|
|
14
14
|
custom_title: rawParam,
|
|
15
15
|
locale: localeParam,
|
|
16
|
-
layout: enumParam(
|
|
16
|
+
layout: enumParam(renderWakatimeCard.OPTIONS.layout),
|
|
17
17
|
langs_count: looseIntParam,
|
|
18
18
|
hide: listParam,
|
|
19
19
|
api_domain: rawParam,
|
|
20
20
|
border_radius: numberParam,
|
|
21
|
-
display_format: enumParam(
|
|
21
|
+
display_format: enumParam(renderWakatimeCard.OPTIONS.display_format),
|
|
22
22
|
disable_animations: booleanParam,
|
|
23
23
|
});
|
|
24
24
|
/**
|
|
@@ -26,66 +26,29 @@ const wakatimeQuery = z.object({
|
|
|
26
26
|
*
|
|
27
27
|
* WakaTime needs no GitHub token, so the config is read only for the transport it carries.
|
|
28
28
|
*
|
|
29
|
-
* @param query Raw query params, plus any of the shared color params.
|
|
30
|
-
* @param query.username WakaTime username.
|
|
31
|
-
* @param query.hide_border Whether to hide the card border.
|
|
32
|
-
* @param query.card_width Card width.
|
|
33
|
-
* @param query.line_height Line height between the languages.
|
|
34
|
-
* @param query.hide_title Whether to hide the card title.
|
|
35
|
-
* @param query.hide_progress Whether to hide the progress bars.
|
|
36
|
-
* @param query.custom_title Card title.
|
|
37
|
-
* @param query.locale Language the card is rendered in.
|
|
38
|
-
* @param query.layout How the languages are laid out.
|
|
39
|
-
* @param query.langs_count Number of languages to show.
|
|
40
|
-
* @param query.hide Comma-separated languages to hide.
|
|
41
|
-
* @param query.api_domain WakaTime instance the stats are read from.
|
|
42
|
-
* @param query.border_radius Card border radius.
|
|
43
|
-
* @param query.display_format Whether values are shown as time or percentages.
|
|
44
|
-
* @param query.disable_animations Whether to disable the card animations.
|
|
45
|
-
* @param config Deployment config supplying the transport.
|
|
46
29
|
* @returns The rendered card, or a rendered error.
|
|
47
30
|
*/
|
|
48
|
-
const renderWakatime = async (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
colors
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
card_width,
|
|
68
|
-
hide,
|
|
69
|
-
line_height,
|
|
70
|
-
hide_progress,
|
|
71
|
-
border_radius,
|
|
72
|
-
locale,
|
|
73
|
-
layout,
|
|
74
|
-
langs_count,
|
|
75
|
-
display_format,
|
|
76
|
-
disable_animations,
|
|
77
|
-
}),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
catch (err) {
|
|
81
|
-
return errorResult(err, colors);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
31
|
+
const renderWakatime = cardHandler(wakatimeQuery, async ({ username, hide_border, card_width, line_height, hide_title, hide_progress, custom_title, locale, layout, langs_count, hide, api_domain, border_radius, display_format, disable_animations, }, colors, config) => {
|
|
32
|
+
const stats = await fetchWakatimeStats({ username, api_domain }, config);
|
|
33
|
+
return renderWakatimeCard(stats, {
|
|
34
|
+
...colors,
|
|
35
|
+
custom_title,
|
|
36
|
+
hide_title,
|
|
37
|
+
hide_border,
|
|
38
|
+
card_width,
|
|
39
|
+
hide,
|
|
40
|
+
line_height,
|
|
41
|
+
hide_progress,
|
|
42
|
+
border_radius,
|
|
43
|
+
locale,
|
|
44
|
+
layout,
|
|
45
|
+
langs_count,
|
|
46
|
+
display_format,
|
|
47
|
+
disable_animations,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
84
50
|
/**
|
|
85
|
-
* The card,
|
|
86
|
-
* A UI reads them off the function it calls
|
|
51
|
+
* The card, and the values each of its options accepts, keyed by the option's own name.
|
|
52
|
+
* A UI reads them off the function it calls: `wakatime.OPTIONS.layout`.
|
|
87
53
|
*/
|
|
88
|
-
export const wakatime = Object.assign(renderWakatime, {
|
|
89
|
-
LAYOUTS: WAKATIME_LAYOUTS,
|
|
90
|
-
DISPLAY_FORMATS,
|
|
91
|
-
});
|
|
54
|
+
export const wakatime = Object.assign(renderWakatime, { OPTIONS: renderWakatimeCard.OPTIONS });
|
package/build/calculateRank.d.ts
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Calculates the users rank.
|
|
3
3
|
*
|
|
4
|
-
* @param params Parameters on which the user's rank depends.
|
|
5
|
-
* @param params.all_commits Whether `include_all_commits` was used.
|
|
6
|
-
* @param params.commits Number of commits.
|
|
7
|
-
* @param params.prs The number of pull requests.
|
|
8
|
-
* @param params.issues The number of issues.
|
|
9
|
-
* @param params.reviews The number of reviews.
|
|
10
|
-
* @param params.repos Total number of repos (accepted for compatibility, unused in the calculation).
|
|
11
|
-
* @param params.stars The number of stars.
|
|
12
|
-
* @param params.followers The number of followers.
|
|
13
4
|
* @returns The users rank.
|
|
14
5
|
*/
|
|
15
6
|
declare function calculateRank({ all_commits, commits, prs, issues, reviews, stars, followers, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calculateRank.d.ts","sourceRoot":"","sources":["../src/calculateRank.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"calculateRank.d.ts","sourceRoot":"","sources":["../src/calculateRank.ts"],"names":[],"mappings":"AAmBA;;;;GAIG;AACH,iBAAS,aAAa,CAAC,EACrB,WAAW,EACX,OAAO,EACP,GAAG,EACH,MAAM,EACN,OAAO,EACP,KAAK,EACL,SAAS,GACV,EAAE;IACD,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAoCxC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/build/calculateRank.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Calculates the exponential cdf.
|
|
3
3
|
*
|
|
4
|
-
* @param x The value.
|
|
5
4
|
* @returns The exponential cdf.
|
|
6
5
|
*/
|
|
7
6
|
function exponential_cdf(x) {
|
|
@@ -10,7 +9,6 @@ function exponential_cdf(x) {
|
|
|
10
9
|
/**
|
|
11
10
|
* Calculates the log normal cdf.
|
|
12
11
|
*
|
|
13
|
-
* @param x The value.
|
|
14
12
|
* @returns The log normal cdf.
|
|
15
13
|
*/
|
|
16
14
|
function log_normal_cdf(x) {
|
|
@@ -20,24 +18,21 @@ function log_normal_cdf(x) {
|
|
|
20
18
|
/**
|
|
21
19
|
* Calculates the users rank.
|
|
22
20
|
*
|
|
23
|
-
* @param params Parameters on which the user's rank depends.
|
|
24
|
-
* @param params.all_commits Whether `include_all_commits` was used.
|
|
25
|
-
* @param params.commits Number of commits.
|
|
26
|
-
* @param params.prs The number of pull requests.
|
|
27
|
-
* @param params.issues The number of issues.
|
|
28
|
-
* @param params.reviews The number of reviews.
|
|
29
|
-
* @param params.repos Total number of repos (accepted for compatibility, unused in the calculation).
|
|
30
|
-
* @param params.stars The number of stars.
|
|
31
|
-
* @param params.followers The number of followers.
|
|
32
21
|
* @returns The users rank.
|
|
33
22
|
*/
|
|
34
23
|
function calculateRank({ all_commits, commits, prs, issues, reviews, stars, followers, }) {
|
|
35
|
-
const COMMITS_MEDIAN = all_commits ? 1000 : 250
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const
|
|
24
|
+
const COMMITS_MEDIAN = all_commits ? 1000 : 250;
|
|
25
|
+
const COMMITS_WEIGHT = 2;
|
|
26
|
+
const PRS_MEDIAN = 50;
|
|
27
|
+
const PRS_WEIGHT = 3;
|
|
28
|
+
const ISSUES_MEDIAN = 25;
|
|
29
|
+
const ISSUES_WEIGHT = 1;
|
|
30
|
+
const REVIEWS_MEDIAN = 2;
|
|
31
|
+
const REVIEWS_WEIGHT = 1;
|
|
32
|
+
const STARS_MEDIAN = 50;
|
|
33
|
+
const STARS_WEIGHT = 4;
|
|
34
|
+
const FOLLOWERS_MEDIAN = 10;
|
|
35
|
+
const FOLLOWERS_WEIGHT = 1;
|
|
41
36
|
const TOTAL_WEIGHT = COMMITS_WEIGHT + PRS_WEIGHT + ISSUES_WEIGHT + REVIEWS_WEIGHT + STARS_WEIGHT + FOLLOWERS_WEIGHT;
|
|
42
37
|
const THRESHOLDS = [1, 12.5, 25, 37.5, 50, 62.5, 75, 87.5, 100];
|
|
43
38
|
const LEVELS = ['S', 'A+', 'A', 'A-', 'B+', 'B', 'B-', 'C+', 'C'];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ContributedToData } from '../fetchers/types.ts';
|
|
2
|
+
import type { CardOptions, CommonCardOptions } from './options.ts';
|
|
3
|
+
declare const MIN_CARD_WIDTH = 340;
|
|
4
|
+
interface ContributedToCardOptions extends CommonCardOptions {
|
|
5
|
+
locale: string;
|
|
6
|
+
hide_title: boolean;
|
|
7
|
+
card_width: number;
|
|
8
|
+
custom_title: string;
|
|
9
|
+
disable_animations: boolean;
|
|
10
|
+
hide_years: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Renders the repositories a user contributed to, ranked by contributions.
|
|
14
|
+
*
|
|
15
|
+
* @returns Contributed-to card SVG string.
|
|
16
|
+
*/
|
|
17
|
+
declare const renderContributedToCard: (data: ContributedToData, options?: CardOptions<ContributedToCardOptions>) => string;
|
|
18
|
+
export { renderContributedToCard, MIN_CARD_WIDTH };
|
|
19
|
+
//# sourceMappingURL=contributed-to.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contributed-to.d.ts","sourceRoot":"","sources":["../../src/cards/contributed-to.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAmB,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAK/E,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGnE,QAAA,MAAM,cAAc,MAAM,CAAC;AA8B3B,UAAU,wBAAyB,SAAQ,iBAAiB;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,UAAU,EAAE,OAAO,CAAC;CACrB;AAmKD;;;;GAIG;AACH,QAAA,MAAM,uBAAuB,SACrB,iBAAiB,YACd,WAAW,CAAC,wBAAwB,CAAC,KAC7C,MAkJF,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { CARD_ICON, CARD_WIDTH, FONT_SIZE, firefoxFontSize, font } from '../common/brand.js';
|
|
2
|
+
import { Card } from '../common/Card.js';
|
|
3
|
+
import { getLightDarkColors } from '../common/color.js';
|
|
4
|
+
import { formatYears } from '../common/date.js';
|
|
5
|
+
import { kFormatter } from '../common/fmt.js';
|
|
6
|
+
import { I18n } from '../common/I18n.js';
|
|
7
|
+
import { clampValue } from '../common/ops.js';
|
|
8
|
+
import { createProgressNode, measureText } from '../common/render.js';
|
|
9
|
+
import { atRule, el, rule } from '../markup/index.js';
|
|
10
|
+
import { contributedToCardLocales } from '../translations.js';
|
|
11
|
+
const CARD_DEFAULT_WIDTH = CARD_WIDTH.wide;
|
|
12
|
+
const MIN_CARD_WIDTH = 340;
|
|
13
|
+
/** Padding the card keeps at its edges; matches `Card`'s own `paddingX`. */
|
|
14
|
+
const CARD_PADDING = 25;
|
|
15
|
+
const TITLE_FONT_SIZE = FONT_SIZE.title;
|
|
16
|
+
/** What `Card`'s title layout reserves for the prefix icon, so the title text starts past it. */
|
|
17
|
+
const TITLE_ICON_COLUMN = 25;
|
|
18
|
+
const NAME_FONT_SIZE = FONT_SIZE.meta;
|
|
19
|
+
/** Room kept at the right edge for the contribution count. */
|
|
20
|
+
const COUNT_WIDTH = 46;
|
|
21
|
+
const BAR_WIDTH = 130;
|
|
22
|
+
const COLUMN_GAP = 12;
|
|
23
|
+
/** Baseline of the first row, measured from the top of the card body. */
|
|
24
|
+
const FIRST_ROW_Y = 10;
|
|
25
|
+
const ROW_HEIGHT = 38;
|
|
26
|
+
/** A row with no year marks under it needs only its own line. */
|
|
27
|
+
const ROW_HEIGHT_NO_YEARS = 24;
|
|
28
|
+
/** How far the year marks sit below their row's baseline. */
|
|
29
|
+
const YEAR_STRIP_Y = 8;
|
|
30
|
+
const YEAR_MARK_SIZE = 7;
|
|
31
|
+
const YEAR_MARK_GAP = 3;
|
|
32
|
+
/** Gap between the last row and the footer's own baseline. */
|
|
33
|
+
const FOOTER_GAP = 12;
|
|
34
|
+
/** Where `Card` puts the body while the title is shown; `setHideTitle` adjusts the height by the same 30. */
|
|
35
|
+
const BODY_OFFSET_Y = 55;
|
|
36
|
+
const BOTTOM_PADDING = 18;
|
|
37
|
+
/**
|
|
38
|
+
* The title, naming the account unless that makes it too wide for the card.
|
|
39
|
+
*
|
|
40
|
+
* A login is up to 39 characters, which at the title's size overruns the default width
|
|
41
|
+
* by half again — so the plain wording is the fallback rather than a truncated login.
|
|
42
|
+
*
|
|
43
|
+
* @returns The default title, which `custom_title` still overrides.
|
|
44
|
+
*/
|
|
45
|
+
const defaultTitleFor = (i18n, contentWidth) => {
|
|
46
|
+
const named = i18n.t('contributedtocard.title');
|
|
47
|
+
return measureText(named, TITLE_FONT_SIZE) <= contentWidth
|
|
48
|
+
? named
|
|
49
|
+
: i18n.t('contributedtocard.title-unnamed');
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Shortens a name to fit its column, ending it with an ellipsis when it does not.
|
|
53
|
+
*
|
|
54
|
+
* @returns The name as it is drawn.
|
|
55
|
+
*/
|
|
56
|
+
const truncateName = (name, maxWidth) => {
|
|
57
|
+
if (measureText(name, NAME_FONT_SIZE) <= maxWidth) {
|
|
58
|
+
return name;
|
|
59
|
+
}
|
|
60
|
+
let trimmed = name;
|
|
61
|
+
while (trimmed.length > 1 && measureText(`${trimmed}…`, NAME_FONT_SIZE) > maxWidth) {
|
|
62
|
+
trimmed = trimmed.slice(0, -1);
|
|
63
|
+
}
|
|
64
|
+
return `${trimmed}…`;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* The marks under a repository's name, one per contribution year of the account,
|
|
68
|
+
* filled for the years that repository got a contribution.
|
|
69
|
+
*
|
|
70
|
+
* The step shrinks to fit, so a long-lived account keeps the strip inside its column
|
|
71
|
+
* rather than running it under the bar.
|
|
72
|
+
*
|
|
73
|
+
* @returns The strip, positioned relative to its row's baseline.
|
|
74
|
+
*/
|
|
75
|
+
const createYearStrip = (repoYears, years, columnWidth) => {
|
|
76
|
+
const contributed = new Set(repoYears);
|
|
77
|
+
const step = Math.min(YEAR_MARK_SIZE + YEAR_MARK_GAP, Math.floor(columnWidth / years.length));
|
|
78
|
+
const size = Math.max(step - YEAR_MARK_GAP, 3);
|
|
79
|
+
return el('g', { 'data-testid': 'year-strip', transform: `translate(0, ${YEAR_STRIP_Y})` }, years.map((year, index) => el('rect', {
|
|
80
|
+
'data-testid': contributed.has(year) ? 'year-on' : 'year-off',
|
|
81
|
+
class: contributed.has(year) ? 'year-on' : 'year-off',
|
|
82
|
+
x: index * step,
|
|
83
|
+
y: 0,
|
|
84
|
+
width: size,
|
|
85
|
+
height: size,
|
|
86
|
+
rx: 1,
|
|
87
|
+
ry: 1,
|
|
88
|
+
})));
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* One repository: its name, a bar for its share of the top repository's contributions,
|
|
92
|
+
* and the count itself.
|
|
93
|
+
*
|
|
94
|
+
* @returns The row, positioned by its own transform.
|
|
95
|
+
*/
|
|
96
|
+
const createRepoRow = ({ repo, index, maxContributions, years, nameWidth, contentWidth, rowHeight, }) => el('g', {
|
|
97
|
+
class: 'stagger',
|
|
98
|
+
style: `animation-delay: ${450 + index * 150}ms`,
|
|
99
|
+
transform: `translate(0, ${FIRST_ROW_Y + index * rowHeight})`,
|
|
100
|
+
}, el('text', { class: 'repo-name', 'data-testid': 'repo-name', x: 0, y: 0 }, truncateName(repo.nameWithOwner, nameWidth)), createProgressNode({
|
|
101
|
+
x: nameWidth + COLUMN_GAP,
|
|
102
|
+
y: -9,
|
|
103
|
+
width: BAR_WIDTH,
|
|
104
|
+
progress: (repo.contributions / maxContributions) * 100,
|
|
105
|
+
delay: 450 + index * 150,
|
|
106
|
+
}), el('text', {
|
|
107
|
+
class: 'count',
|
|
108
|
+
'data-testid': 'repo-contributions',
|
|
109
|
+
x: contentWidth,
|
|
110
|
+
y: 0,
|
|
111
|
+
'text-anchor': 'end',
|
|
112
|
+
}, kFormatter(repo.contributions)), years.length > 0 && createYearStrip(repo.years, years, nameWidth));
|
|
113
|
+
/**
|
|
114
|
+
* The line under the rows: how much of the walk the card is showing, and over what years.
|
|
115
|
+
*
|
|
116
|
+
* Never dropped, because the card shows a slice of the repositories
|
|
117
|
+
* and a rank means nothing without the total it was taken from.
|
|
118
|
+
*
|
|
119
|
+
* @returns The footer text.
|
|
120
|
+
*/
|
|
121
|
+
const footerText = ({ i18n, shown, totalRepos, years, }) => {
|
|
122
|
+
const parts = [
|
|
123
|
+
i18n.t(shown < totalRepos ? 'contributedtocard.footer-top' : 'contributedtocard.footer-all'),
|
|
124
|
+
];
|
|
125
|
+
const [firstYear] = years;
|
|
126
|
+
const lastYear = years.at(-1);
|
|
127
|
+
if (firstYear !== undefined && lastYear !== undefined) {
|
|
128
|
+
parts.push(formatYears(firstYear, lastYear));
|
|
129
|
+
}
|
|
130
|
+
return parts.join(' · ');
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Renders the repositories a user contributed to, ranked by contributions.
|
|
134
|
+
*
|
|
135
|
+
* @returns Contributed-to card SVG string.
|
|
136
|
+
*/
|
|
137
|
+
const renderContributedToCard = (data, options = {}) => {
|
|
138
|
+
const { locale, hide_title = false, hide_border = false, card_width, custom_title, disable_animations = false, hide_years = false, border_radius, theme = 'default', } = options;
|
|
139
|
+
const { login, repos, totalRepos } = data;
|
|
140
|
+
const years = hide_years ? [] : data.years;
|
|
141
|
+
const width = card_width && !Number.isNaN(card_width)
|
|
142
|
+
? clampValue(card_width, MIN_CARD_WIDTH, Number.MAX_SAFE_INTEGER)
|
|
143
|
+
: CARD_DEFAULT_WIDTH;
|
|
144
|
+
const contentWidth = width - 2 * CARD_PADDING;
|
|
145
|
+
const nameWidth = contentWidth - COUNT_WIDTH - BAR_WIDTH - 2 * COLUMN_GAP;
|
|
146
|
+
const rowHeight = years.length > 0 ? ROW_HEIGHT : ROW_HEIGHT_NO_YEARS;
|
|
147
|
+
// the count is a share of the busiest repository, so the first bar is always full
|
|
148
|
+
const maxContributions = Math.max(...repos.map((repo) => repo.contributions), 1);
|
|
149
|
+
const rows = repos.map((repo, index) => createRepoRow({
|
|
150
|
+
repo,
|
|
151
|
+
index,
|
|
152
|
+
maxContributions,
|
|
153
|
+
years,
|
|
154
|
+
nameWidth,
|
|
155
|
+
contentWidth,
|
|
156
|
+
rowHeight,
|
|
157
|
+
}));
|
|
158
|
+
const i18n = new I18n({
|
|
159
|
+
locale,
|
|
160
|
+
translations: contributedToCardLocales({ login, shown: repos.length, totalRepos }),
|
|
161
|
+
});
|
|
162
|
+
const footer = footerText({ i18n, shown: repos.length, totalRepos, years });
|
|
163
|
+
const footerY = FIRST_ROW_Y + Math.max(repos.length, 1) * rowHeight + FOOTER_GAP;
|
|
164
|
+
const height = BODY_OFFSET_Y + footerY + BOTTOM_PADDING;
|
|
165
|
+
const { lightColors, darkColors } = getLightDarkColors({ ...options, theme });
|
|
166
|
+
const card = new Card({
|
|
167
|
+
customTitle: custom_title,
|
|
168
|
+
defaultTitle: defaultTitleFor(i18n, contentWidth - TITLE_ICON_COLUMN),
|
|
169
|
+
titlePrefixIcon: CARD_ICON.contributedTo,
|
|
170
|
+
width,
|
|
171
|
+
height,
|
|
172
|
+
border_radius,
|
|
173
|
+
colors: { light: lightColors, dark: darkColors },
|
|
174
|
+
});
|
|
175
|
+
if (disable_animations) {
|
|
176
|
+
card.disableAnimations();
|
|
177
|
+
}
|
|
178
|
+
card.setHideBorder(hide_border);
|
|
179
|
+
card.setHideTitle(hide_title);
|
|
180
|
+
card.setCSS({
|
|
181
|
+
light: ({ textColor, titleColor, iconColor, progBarBgColor }) => [
|
|
182
|
+
atRule('@keyframes growWidthAnimation', rule('from', { width: 0 }), rule('to', { width: '100%' })),
|
|
183
|
+
rule('.repo-name', {
|
|
184
|
+
font: font('regular', 'meta'),
|
|
185
|
+
fill: textColor,
|
|
186
|
+
}),
|
|
187
|
+
rule('.count', {
|
|
188
|
+
font: font('semibold', 'meta'),
|
|
189
|
+
fill: textColor,
|
|
190
|
+
'font-variant-numeric': 'tabular-nums',
|
|
191
|
+
}),
|
|
192
|
+
rule('.footer', {
|
|
193
|
+
font: font('regular', 'micro'),
|
|
194
|
+
fill: textColor,
|
|
195
|
+
opacity: 0.7,
|
|
196
|
+
}),
|
|
197
|
+
firefoxFontSize(['.repo-name', '.count'], 'small'),
|
|
198
|
+
rule('.year-on', { fill: titleColor }),
|
|
199
|
+
// a year with no contribution reads off the text color, not `progBarBgColor`:
|
|
200
|
+
// on a dark theme that color is a light grey, and the empty marks came out looking filled
|
|
201
|
+
rule('.year-off', { fill: textColor, opacity: 0.25 }),
|
|
202
|
+
rule('.progress-background', { fill: progBarBgColor }),
|
|
203
|
+
rule('.lang-progress', {
|
|
204
|
+
fill: titleColor,
|
|
205
|
+
animation: 'growWidthAnimation 0.6s ease-in-out forwards',
|
|
206
|
+
}),
|
|
207
|
+
rule('.stagger', { opacity: 0, animation: 'fadeInAnimation 0.3s ease-in-out forwards' }),
|
|
208
|
+
rule('.icon', { fill: iconColor, display: 'block' }),
|
|
209
|
+
],
|
|
210
|
+
dark: ({ textColor, titleColor, iconColor, progBarBgColor }) => [
|
|
211
|
+
rule('.repo-name', { fill: textColor }),
|
|
212
|
+
rule('.count', { fill: textColor }),
|
|
213
|
+
rule('.footer', { fill: textColor }),
|
|
214
|
+
rule('.year-on', { fill: titleColor }),
|
|
215
|
+
// a year with no contribution reads off the text color, not `progBarBgColor`:
|
|
216
|
+
// on a dark theme that color is a light grey, and the empty marks came out looking filled
|
|
217
|
+
rule('.year-off', { fill: textColor, opacity: 0.25 }),
|
|
218
|
+
rule('.progress-background', { fill: progBarBgColor }),
|
|
219
|
+
rule('.lang-progress', { fill: titleColor }),
|
|
220
|
+
rule('.icon', { fill: iconColor }),
|
|
221
|
+
],
|
|
222
|
+
});
|
|
223
|
+
// `role="img"` hides the inner text from assistive tech, so everything the card
|
|
224
|
+
// shows has to be repeated here — the year marks included, since they carry
|
|
225
|
+
// information no other element on the card does.
|
|
226
|
+
card.setAccessibilityLabel({
|
|
227
|
+
title: card.title,
|
|
228
|
+
desc: [
|
|
229
|
+
...repos.map((repo) => {
|
|
230
|
+
const inYears = hide_years
|
|
231
|
+
? ''
|
|
232
|
+
: `, ${i18n.t('contributedtocard.years')}: ${repo.years.join(', ')}`;
|
|
233
|
+
return `${repo.nameWithOwner}: ${repo.contributions} ${i18n.t('contributedtocard.contributions')}${inYears}`;
|
|
234
|
+
}),
|
|
235
|
+
footer,
|
|
236
|
+
].join('; '),
|
|
237
|
+
});
|
|
238
|
+
return card.render(el('g', { 'data-testid': 'contributed-to-body', transform: `translate(${CARD_PADDING}, 0)` }, repos.length === 0
|
|
239
|
+
? el('text', { class: 'repo-name', 'data-testid': 'no-repos', x: 0, y: FIRST_ROW_Y }, i18n.t('contributedtocard.no-contributions'))
|
|
240
|
+
: rows, el('text', { class: 'footer', 'data-testid': 'footer', x: 0, y: footerY }, footer)));
|
|
241
|
+
};
|
|
242
|
+
export { renderContributedToCard, MIN_CARD_WIDTH };
|
package/build/cards/gist.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import type { GistData } from '../fetchers/types.
|
|
2
|
-
import type { CardOptions, CommonCardOptions } from './options.
|
|
1
|
+
import type { GistData } from '../fetchers/types.ts';
|
|
2
|
+
import type { CardOptions, CommonCardOptions } from './options.ts';
|
|
3
3
|
interface GistCardOptions extends CommonCardOptions {
|
|
4
|
+
locale: string;
|
|
4
5
|
show_owner: boolean;
|
|
5
6
|
browser_rendering: boolean;
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
8
9
|
* Render gist card.
|
|
9
10
|
*
|
|
10
|
-
* @param gistData Gist data.
|
|
11
|
-
* @param options Gist card options.
|
|
12
11
|
* @returns Gist card.
|
|
13
12
|
*/
|
|
14
13
|
declare const renderGistCard: (gistData: GistData, options?: CardOptions<GistCardOptions>) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gist.d.ts","sourceRoot":"","sources":["../../src/cards/gist.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gist.d.ts","sourceRoot":"","sources":["../../src/cards/gist.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAKrD,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAWnE,UAAU,eAAgB,SAAQ,iBAAiB;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,QAAA,MAAM,cAAc,aAAc,QAAQ,YAAW,WAAW,CAAC,eAAe,CAAC,KAAQ,MA+HxF,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
package/build/cards/gist.js
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CARD_ICON, CARD_WIDTH, FONT_SIZE, font } from '../common/brand.js';
|
|
2
|
+
import { Card } from '../common/Card.js';
|
|
2
3
|
import { getLightDarkColors } from '../common/color.js';
|
|
3
|
-
import { kFormatter
|
|
4
|
-
import {
|
|
4
|
+
import { kFormatter } from '../common/fmt.js';
|
|
5
|
+
import { I18n } from '../common/I18n.js';
|
|
5
6
|
import { icons } from '../common/icons.js';
|
|
6
7
|
import { getLanguageColor } from '../common/languageColors.js';
|
|
7
8
|
import { parseEmojis } from '../common/ops.js';
|
|
8
|
-
import { countWrappedLines, createLanguageNode, flexLayout, iconWithLabel, measureText, wrappedTextNode, wrappedTextStyles, } from '../common/render.js';
|
|
9
|
+
import { countWrappedLines, wrapTextMultiline, createLanguageNode, flexLayout, iconWithLabel, measureText, wrappedTextNode, wrappedTextStyles, } from '../common/render.js';
|
|
10
|
+
import { el, rule } from '../markup/index.js';
|
|
11
|
+
import { gistCardLocales } from '../translations.js';
|
|
9
12
|
const ICON_SIZE = 16;
|
|
10
|
-
const CARD_DEFAULT_WIDTH =
|
|
13
|
+
const CARD_DEFAULT_WIDTH = CARD_WIDTH.standard;
|
|
11
14
|
const X_OFFSET = 25;
|
|
12
15
|
const HEADER_MAX_LENGTH = 35;
|
|
13
16
|
const DESCRIPTION_BOX_WIDTH = CARD_DEFAULT_WIDTH - 2 * X_OFFSET;
|
|
14
|
-
const DESCRIPTION_FONT_SIZE =
|
|
17
|
+
const DESCRIPTION_FONT_SIZE = FONT_SIZE.meta;
|
|
15
18
|
const DESCRIPTION_LINE_HEIGHT_PX = 16;
|
|
16
19
|
const DESCRIPTION_MAX_LINES = 10;
|
|
17
20
|
/**
|
|
18
21
|
* Render gist card.
|
|
19
22
|
*
|
|
20
|
-
* @param gistData Gist data.
|
|
21
|
-
* @param options Gist card options.
|
|
22
23
|
* @returns Gist card.
|
|
23
24
|
*/
|
|
24
25
|
const renderGistCard = (gistData, options = {}) => {
|
|
25
26
|
const { name, nameWithOwner, description, language, starsCount, forksCount } = gistData;
|
|
26
|
-
const { theme = 'default_repocard', border_radius, show_owner = false, browser_rendering = false, hide_border = false, } = options;
|
|
27
|
+
const { locale, theme = 'default_repocard', border_radius, show_owner = false, browser_rendering = false, hide_border = false, } = options;
|
|
27
28
|
const { lightColors, darkColors } = getLightDarkColors({ ...options, theme });
|
|
28
|
-
const
|
|
29
|
+
const i18n = new I18n({ locale, translations: gistCardLocales });
|
|
30
|
+
const desc = parseEmojis(description || i18n.t('gistcard.no-description'));
|
|
29
31
|
let descriptionLines;
|
|
30
32
|
let descriptionSvg;
|
|
31
33
|
if (browser_rendering) {
|
|
@@ -49,12 +51,7 @@ const renderGistCard = (gistData, options = {}) => {
|
|
|
49
51
|
const linesLimit = 10;
|
|
50
52
|
const multiLineDescription = wrapTextMultiline(desc, DESCRIPTION_BOX_WIDTH, DESCRIPTION_FONT_SIZE, linesLimit);
|
|
51
53
|
descriptionLines = multiLineDescription.length;
|
|
52
|
-
descriptionSvg = multiLineDescription
|
|
53
|
-
.map((line) => `<tspan dy="1.2em" x="${X_OFFSET}">${encodeHTML(line)}</tspan>`)
|
|
54
|
-
.join('');
|
|
55
|
-
descriptionSvg = `<text class="description" x="${X_OFFSET}" y="-5">
|
|
56
|
-
${descriptionSvg}
|
|
57
|
-
</text>`;
|
|
54
|
+
descriptionSvg = el('text', { class: 'description', x: X_OFFSET, y: -5 }, multiLineDescription.map((line) => el('tspan', { dy: '1.2em', x: X_OFFSET }, line)));
|
|
58
55
|
}
|
|
59
56
|
const lineHeight = descriptionLines > 3 ? 12 : 10;
|
|
60
57
|
const height = (descriptionLines > 1 ? 120 : 110) + descriptionLines * lineHeight;
|
|
@@ -62,7 +59,7 @@ const renderGistCard = (gistData, options = {}) => {
|
|
|
62
59
|
const totalForks = kFormatter(forksCount);
|
|
63
60
|
const svgStars = iconWithLabel(icons.star, totalStars, 'starsCount', ICON_SIZE);
|
|
64
61
|
const svgForks = iconWithLabel(icons.fork, totalForks, 'forksCount', ICON_SIZE);
|
|
65
|
-
const languageName = language || '
|
|
62
|
+
const languageName = language || i18n.t('gistcard.unspecified-language');
|
|
66
63
|
const languageColor = getLanguageColor(languageName);
|
|
67
64
|
const svgLanguage = createLanguageNode(languageName, languageColor);
|
|
68
65
|
const starAndForkCount = flexLayout({
|
|
@@ -73,47 +70,45 @@ const renderGistCard = (gistData, options = {}) => {
|
|
|
73
70
|
ICON_SIZE + measureText(`${totalForks}`, 12),
|
|
74
71
|
],
|
|
75
72
|
gap: 25,
|
|
76
|
-
})
|
|
73
|
+
});
|
|
77
74
|
const header = show_owner ? nameWithOwner : name;
|
|
78
75
|
const card = new Card({
|
|
79
76
|
defaultTitle: header.length > HEADER_MAX_LENGTH ? `${header.slice(0, HEADER_MAX_LENGTH)}...` : header,
|
|
80
|
-
titlePrefixIcon:
|
|
77
|
+
titlePrefixIcon: CARD_ICON.gist,
|
|
81
78
|
width: CARD_DEFAULT_WIDTH,
|
|
82
79
|
height,
|
|
83
80
|
border_radius,
|
|
84
81
|
colors: { light: lightColors, dark: darkColors },
|
|
85
82
|
});
|
|
86
83
|
card.setCSS({
|
|
87
|
-
light: ({ textColor, iconColor }) =>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
84
|
+
light: ({ textColor, iconColor }) => [
|
|
85
|
+
rule('.description', {
|
|
86
|
+
font: font('regular', 'meta'),
|
|
87
|
+
fill: textColor,
|
|
88
|
+
...(browser_rendering ? wrappedTextStyles(textColor) : {}),
|
|
89
|
+
}),
|
|
90
|
+
rule('.gray', { font: font('regular', 'small'), fill: textColor }),
|
|
91
|
+
rule('.icon', { fill: iconColor }),
|
|
92
|
+
],
|
|
93
|
+
dark: ({ textColor, iconColor }) => [
|
|
94
|
+
rule('.description', {
|
|
95
|
+
fill: textColor,
|
|
96
|
+
...(browser_rendering ? wrappedTextStyles(textColor) : {}),
|
|
97
|
+
}),
|
|
98
|
+
rule('.gray', { fill: textColor }),
|
|
99
|
+
rule('.icon', { fill: iconColor }),
|
|
100
|
+
],
|
|
103
101
|
});
|
|
104
102
|
card.setHideBorder(hide_border);
|
|
105
103
|
// `role="img"` hides the inner text from assistive tech, so everything the card
|
|
106
104
|
// shows has to be repeated here.
|
|
107
105
|
card.setAccessibilityLabel({
|
|
108
106
|
title: card.title,
|
|
109
|
-
desc: `${desc}.
|
|
107
|
+
desc: `${desc}. ${i18n.t('gistcard.language')}: ${languageName}, ${i18n.t('gistcard.stars')}: ${totalStars}, ${i18n.t('gistcard.forks')}: ${totalForks}`,
|
|
110
108
|
});
|
|
111
|
-
return card.render(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
${starAndForkCount}
|
|
116
|
-
</g>
|
|
117
|
-
`);
|
|
109
|
+
return card.render([
|
|
110
|
+
descriptionSvg,
|
|
111
|
+
el('g', { transform: `translate(30, ${height - 75})` }, starAndForkCount),
|
|
112
|
+
]);
|
|
118
113
|
};
|
|
119
114
|
export { renderGistCard };
|
package/build/cards/options.d.ts
CHANGED
package/build/cards/repo.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RepositoryData } from '../fetchers/types.
|
|
2
|
-
import type { CardOptions, CommonCardOptions } from './options.
|
|
1
|
+
import type { RepositoryData } from '../fetchers/types.ts';
|
|
2
|
+
import type { CardOptions, CommonCardOptions } from './options.ts';
|
|
3
3
|
interface RepoCardOptions extends CommonCardOptions {
|
|
4
4
|
locale: string;
|
|
5
5
|
show_owner: boolean;
|
|
@@ -16,10 +16,19 @@ interface RepoCardOptions extends CommonCardOptions {
|
|
|
16
16
|
/**
|
|
17
17
|
* Renders repository card details.
|
|
18
18
|
*
|
|
19
|
-
* @param repo Repository data.
|
|
20
|
-
* @param options Card options.
|
|
21
19
|
* @returns Repository card SVG object.
|
|
22
20
|
*/
|
|
23
|
-
declare const
|
|
21
|
+
declare const renderCard: (repo: RepositoryData, options?: CardOptions<RepoCardOptions>) => string;
|
|
22
|
+
/**
|
|
23
|
+
* The card, and the values each of its options accepts, keyed by the option's own name.
|
|
24
|
+
* They ride on the renderer so a list cannot be found without what draws it;
|
|
25
|
+
* the api handler forwards them onto its own export, which is what a UI reads.
|
|
26
|
+
*/
|
|
27
|
+
declare const renderRepoCard: typeof renderCard & {
|
|
28
|
+
OPTIONS: {
|
|
29
|
+
show: readonly ["prs_authored", "prs_commented", "prs_reviewed", "issues_authored", "issues_commented"];
|
|
30
|
+
number_format: readonly ["short", "long"];
|
|
31
|
+
};
|
|
32
|
+
};
|
|
24
33
|
export { renderRepoCard };
|
|
25
34
|
//# sourceMappingURL=repo.d.ts.map
|