~repos /website
git clone https://pyrossh.dev/repos/website.git
木 Personal website of pyrossh. Built with astrojs, shiki, vite.
b7547db6
—
pyrossh 1 month ago
update site
- .vscode/extensions.json +2 -1
- astro.config.mjs +3 -13
- bun.lock +46 -0
- ec.config.mjs +14 -0
- package.json +5 -1
- src/content.config.ts +15 -0
- src/layouts/Base.astro +1 -2
- src/layouts/Base.css +6 -8
- src/layouts/Repo.astro +169 -0
- src/pages/posts/[...slug].astro +0 -8
- src/pages/repos/[...slug]/commits/index.astro +4 -4
- src/pages/repos/[...slug]/files/[...file]/index.astro +57 -0
- src/pages/repos/[...slug]/files/index.astro +73 -5
- src/pages/repos/[...slug]/index.astro +4 -43
- src/pages/repos/[...slug]/index.module.css +0 -117
.vscode/extensions.json
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
"astro-build.astro-vscode",
|
|
4
4
|
"unifiedjs.vscode-mdx",
|
|
5
5
|
"tauri-apps.tauri-vscode",
|
|
6
|
-
"rust-lang.rust-analyzer"
|
|
6
|
+
"rust-lang.rust-analyzer",
|
|
7
|
+
"myriad-dreamin.tinymist"
|
|
7
8
|
],
|
|
8
9
|
"unwantedRecommendations": []
|
|
9
10
|
}
|
astro.config.mjs
CHANGED
|
@@ -2,25 +2,15 @@
|
|
|
2
2
|
import { defineConfig } from 'astro/config';
|
|
3
3
|
import icon from "astro-icon";
|
|
4
4
|
import sitemap from '@astrojs/sitemap';
|
|
5
|
+
import expressiveCode from 'astro-expressive-code';
|
|
5
6
|
|
|
6
7
|
// https://astro.build/config
|
|
7
8
|
export default defineConfig({
|
|
8
9
|
site: 'https://pyrossh.dev',
|
|
9
10
|
trailingSlash: 'never',
|
|
10
11
|
output: 'static',
|
|
11
|
-
markdown: {
|
|
12
|
-
shikiConfig: {
|
|
13
|
-
themes: {
|
|
14
|
-
|
|
12
|
+
integrations: [icon(), sitemap(), expressiveCode()],
|
|
15
|
-
dark: 'github-dark',
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
integrations: [
|
|
20
|
-
icon(),
|
|
21
|
-
sitemap(),
|
|
22
|
-
],
|
|
23
13
|
experimental: {
|
|
24
14
|
// csp: true,
|
|
25
15
|
},
|
|
26
|
-
});
|
|
16
|
+
});
|
bun.lock
CHANGED
|
@@ -7,9 +7,13 @@
|
|
|
7
7
|
"@appzic/astro-reset-css": "^1.2.0",
|
|
8
8
|
"@astrojs/rss": "^4.0.12",
|
|
9
9
|
"@astrojs/sitemap": "^3.4.1",
|
|
10
|
+
"@tauri-apps/plugin-log": "^2.7.1",
|
|
10
11
|
"astro": "^5.9.0",
|
|
11
12
|
"astro-color-scheme": "^1.1.5",
|
|
13
|
+
"astro-expressive-code": "^0.41.3",
|
|
12
14
|
"astro-icon": "^1.1.5",
|
|
15
|
+
"expressive-code-color-chips": "^0.1.2",
|
|
16
|
+
"pretty-bytes": "^7.1.0",
|
|
13
17
|
"simple-git": "^3.27.0",
|
|
14
18
|
"timeago.js": "^4.0.2",
|
|
15
19
|
},
|
|
@@ -52,6 +56,8 @@
|
|
|
52
56
|
|
|
53
57
|
"@capsizecss/unpack": ["@capsizecss/unpack@2.4.0", "", { "dependencies": { "blob-to-buffer": "^1.2.8", "cross-fetch": "^3.0.4", "fontkit": "^2.0.2" } }, "sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q=="],
|
|
54
58
|
|
|
59
|
+
"@ctrl/tinycolor": ["@ctrl/tinycolor@4.2.0", "", {}, "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A=="],
|
|
60
|
+
|
|
55
61
|
"@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="],
|
|
56
62
|
|
|
57
63
|
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ=="],
|
|
@@ -104,6 +110,14 @@
|
|
|
104
110
|
|
|
105
111
|
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.3", "", { "os": "win32", "cpu": "x64" }, "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg=="],
|
|
106
112
|
|
|
113
|
+
"@expressive-code/core": ["@expressive-code/core@0.41.3", "", { "dependencies": { "@ctrl/tinycolor": "^4.0.4", "hast-util-select": "^6.0.2", "hast-util-to-html": "^9.0.1", "hast-util-to-text": "^4.0.1", "hastscript": "^9.0.0", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-9qzohqU7O0+JwMEEgQhnBPOw5DtsQRBXhW++5fvEywsuX44vCGGof1SL5OvPElvNgaWZ4pFZAFSlkNOkGyLwSQ=="],
|
|
114
|
+
|
|
115
|
+
"@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3" } }, "sha512-rFQtmf/3N2CK3Cq/uERweMTYZnBu+CwxBdHuOftEmfA9iBE7gTVvwpbh82P9ZxkPLvc40UMhYt7uNuAZexycRQ=="],
|
|
116
|
+
|
|
117
|
+
"@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3", "shiki": "^3.2.2" } }, "sha512-RlTARoopzhFJIOVHLGvuXJ8DCEme/hjV+ZnRJBIxzxsKVpGPW4Oshqg9xGhWTYdHstTsxO663s0cdBLzZj9TQA=="],
|
|
118
|
+
|
|
119
|
+
"@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3" } }, "sha512-SN8tkIzDpA0HLAscEYD2IVrfLiid6qEdE9QLlGVSxO1KEw7qYvjpbNBQjUjMr5/jvTJ7ys6zysU2vLPHE0sb2g=="],
|
|
120
|
+
|
|
107
121
|
"@iconify-json/material-symbols": ["@iconify-json/material-symbols@1.2.39", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-spjiB1I5jPi6hV5b/QyC4zO8GRYGCbb6/DaHm754NJFqNli6bsYDpN4HYVl67XhU49rYljvJyNc/6lYEf+jokA=="],
|
|
108
122
|
|
|
109
123
|
"@iconify/tools": ["@iconify/tools@4.1.3", "", { "dependencies": { "@iconify/types": "^2.0.0", "@iconify/utils": "^2.3.0", "@types/tar": "^6.1.13", "axios": "^1.12.1", "cheerio": "1.0.0", "domhandler": "^5.0.3", "extract-zip": "^2.0.1", "local-pkg": "^0.5.1", "pathe": "^1.1.2", "svgo": "^3.3.2", "tar": "^6.2.1" } }, "sha512-guPw9jvkrCCGFUvPr+NgUcQIpQcIll38NQzUzrEMK/1vrDmeJ9jstsp/Dx5LIP2na9BUBLHKOKXA6cERTpnGFw=="],
|
|
@@ -218,6 +232,8 @@
|
|
|
218
232
|
|
|
219
233
|
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
|
|
220
234
|
|
|
235
|
+
"@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="],
|
|
236
|
+
|
|
221
237
|
"@tauri-apps/cli": ["@tauri-apps/cli@2.9.1", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.9.1", "@tauri-apps/cli-darwin-x64": "2.9.1", "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.1", "@tauri-apps/cli-linux-arm64-gnu": "2.9.1", "@tauri-apps/cli-linux-arm64-musl": "2.9.1", "@tauri-apps/cli-linux-riscv64-gnu": "2.9.1", "@tauri-apps/cli-linux-x64-gnu": "2.9.1", "@tauri-apps/cli-linux-x64-musl": "2.9.1", "@tauri-apps/cli-win32-arm64-msvc": "2.9.1", "@tauri-apps/cli-win32-ia32-msvc": "2.9.1", "@tauri-apps/cli-win32-x64-msvc": "2.9.1" }, "bin": { "tauri": "tauri.js" } }, "sha512-kKi2/WWsNXKoMdatBl4xrT7e1Ce27JvsetBVfWuIb6D3ep/Y0WO5SIr70yarXOSWam8NyDur4ipzjZkg6m7VDg=="],
|
|
222
238
|
|
|
223
239
|
"@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.9.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-sdwhtsE/6njD0AjgfYEj1JyxZH4SBmCJSXpRm6Ph5fQeuZD6MyjzjdVOrrtFguyREVQ7xn0Ujkwvbo01ULthNg=="],
|
|
@@ -242,6 +258,8 @@
|
|
|
242
258
|
|
|
243
259
|
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.9.1", "", { "os": "win32", "cpu": "x64" }, "sha512-/JHlOzpUDhjBOO9w167bcYxfJbcMQv7ykS/Y07xjtcga8np0rzUzVGWYmLMH7orKcDMC7wjhheEW1x8cbGma/Q=="],
|
|
244
260
|
|
|
261
|
+
"@tauri-apps/plugin-log": ["@tauri-apps/plugin-log@2.7.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-jdb+o0wxQc8PjnLktgGpOs9Dh1YupaOGDXzO+Y8peA1UZ1ep3eXv4E1oiJ7nIQVN0XUFDDhnn3aBszl8ijhR+A=="],
|
|
262
|
+
|
|
245
263
|
"@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
|
|
246
264
|
|
|
247
265
|
"@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
|
|
@@ -292,6 +310,8 @@
|
|
|
292
310
|
|
|
293
311
|
"astro-color-scheme": ["astro-color-scheme@1.1.5", "", {}, "sha512-enYqCiSopMkVCmL5tuXgJk9AoJKCYDpV92F0bZUbqTMWHKqPnXwWS+iJC60Rf87b33LhCyFmB2yqAZ+c4RvjGw=="],
|
|
294
312
|
|
|
313
|
+
"astro-expressive-code": ["astro-expressive-code@0.41.3", "", { "dependencies": { "rehype-expressive-code": "^0.41.3" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0" } }, "sha512-u+zHMqo/QNLE2eqYRCrK3+XMlKakv33Bzuz+56V1gs8H0y6TZ0hIi3VNbIxeTn51NLn+mJfUV/A0kMNfE4rANw=="],
|
|
314
|
+
|
|
295
315
|
"astro-icon": ["astro-icon@1.1.5", "", { "dependencies": { "@iconify/tools": "^4.0.5", "@iconify/types": "^2.0.0", "@iconify/utils": "^2.1.30" } }, "sha512-CJYS5nWOw9jz4RpGWmzNQY7D0y2ZZacH7atL2K9DeJXJVaz7/5WrxeyIxO8KASk1jCM96Q4LjRx/F3R+InjJrw=="],
|
|
296
316
|
|
|
297
317
|
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
|
@@ -306,6 +326,8 @@
|
|
|
306
326
|
|
|
307
327
|
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
|
308
328
|
|
|
329
|
+
"bcp-47-match": ["bcp-47-match@2.0.3", "", {}, "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ=="],
|
|
330
|
+
|
|
309
331
|
"blob-to-buffer": ["blob-to-buffer@1.2.9", "", {}, "sha512-BF033y5fN6OCofD3vgHmNtwZWRcq9NLyyxyILx9hfMy1sXYy4ojFl765hJ2lP0YaN2fuxPaLO2Vzzoxy0FLFFA=="],
|
|
310
332
|
|
|
311
333
|
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
|
|
@@ -374,6 +396,8 @@
|
|
|
374
396
|
|
|
375
397
|
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
|
|
376
398
|
|
|
399
|
+
"css-selector-parser": ["css-selector-parser@3.1.3", "", {}, "sha512-gJMigczVZqYAk0hPVzx/M4Hm1D9QOtqkdQk9005TNzDIUGzo5cnHEDiKUT7jGPximL/oYb+LIitcHFQ4aKupxg=="],
|
|
400
|
+
|
|
377
401
|
"css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="],
|
|
378
402
|
|
|
379
403
|
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
|
|
@@ -406,6 +430,8 @@
|
|
|
406
430
|
|
|
407
431
|
"diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="],
|
|
408
432
|
|
|
433
|
+
"direction": ["direction@2.0.1", "", { "bin": { "direction": "cli.js" } }, "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA=="],
|
|
434
|
+
|
|
409
435
|
"dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
|
|
410
436
|
|
|
411
437
|
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
|
@@ -446,6 +472,10 @@
|
|
|
446
472
|
|
|
447
473
|
"eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
|
|
448
474
|
|
|
475
|
+
"expressive-code": ["expressive-code@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3", "@expressive-code/plugin-frames": "^0.41.3", "@expressive-code/plugin-shiki": "^0.41.3", "@expressive-code/plugin-text-markers": "^0.41.3" } }, "sha512-YLnD62jfgBZYrXIPQcJ0a51Afv9h8VlWqEGK9uU2T5nL/5rb8SnA86+7+mgCZe5D34Tff5RNEA5hjNVJYHzrFg=="],
|
|
476
|
+
|
|
477
|
+
"expressive-code-color-chips": ["expressive-code-color-chips@0.1.2", "", { "peerDependencies": { "@expressive-code/core": "^0.37.1" } }, "sha512-6vGCN1KjZQhHAd4U5kxvoBgBRB8kjcdY5bjJgzzJ29mlGpSp4tt5eI8zvLzSUIxwHmu65fATdGW82tNQM2befw=="],
|
|
478
|
+
|
|
449
479
|
"exsolve": ["exsolve@1.0.7", "", {}, "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw=="],
|
|
450
480
|
|
|
451
481
|
"extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
|
|
@@ -502,16 +532,22 @@
|
|
|
502
532
|
|
|
503
533
|
"hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="],
|
|
504
534
|
|
|
535
|
+
"hast-util-has-property": ["hast-util-has-property@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA=="],
|
|
536
|
+
|
|
505
537
|
"hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="],
|
|
506
538
|
|
|
507
539
|
"hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="],
|
|
508
540
|
|
|
509
541
|
"hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="],
|
|
510
542
|
|
|
543
|
+
"hast-util-select": ["hast-util-select@6.0.4", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "bcp-47-match": "^2.0.0", "comma-separated-tokens": "^2.0.0", "css-selector-parser": "^3.0.0", "devlop": "^1.0.0", "direction": "^2.0.0", "hast-util-has-property": "^3.0.0", "hast-util-to-string": "^3.0.0", "hast-util-whitespace": "^3.0.0", "nth-check": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw=="],
|
|
544
|
+
|
|
511
545
|
"hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
|
|
512
546
|
|
|
513
547
|
"hast-util-to-parse5": ["hast-util-to-parse5@8.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw=="],
|
|
514
548
|
|
|
549
|
+
"hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="],
|
|
550
|
+
|
|
515
551
|
"hast-util-to-text": ["hast-util-to-text@4.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "hast-util-is-element": "^3.0.0", "unist-util-find-after": "^5.0.0" } }, "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A=="],
|
|
516
552
|
|
|
517
553
|
"hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="],
|
|
@@ -724,6 +760,12 @@
|
|
|
724
760
|
|
|
725
761
|
"postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
|
|
726
762
|
|
|
763
|
+
"postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="],
|
|
764
|
+
|
|
765
|
+
"postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
|
|
766
|
+
|
|
767
|
+
"pretty-bytes": ["pretty-bytes@7.1.0", "", {}, "sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw=="],
|
|
768
|
+
|
|
727
769
|
"prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
|
|
728
770
|
|
|
729
771
|
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
|
|
@@ -748,6 +790,8 @@
|
|
|
748
790
|
|
|
749
791
|
"rehype": ["rehype@13.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "rehype-parse": "^9.0.0", "rehype-stringify": "^10.0.0", "unified": "^11.0.0" } }, "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A=="],
|
|
750
792
|
|
|
793
|
+
"rehype-expressive-code": ["rehype-expressive-code@0.41.3", "", { "dependencies": { "expressive-code": "^0.41.3" } }, "sha512-8d9Py4c/V6I/Od2VIXFAdpiO2kc0SV2qTJsRAaqSIcM9aruW4ASLNe2kOEo1inXAAkIhpFzAHTc358HKbvpNUg=="],
|
|
794
|
+
|
|
751
795
|
"rehype-parse": ["rehype-parse@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-from-html": "^2.0.0", "unified": "^11.0.0" } }, "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag=="],
|
|
752
796
|
|
|
753
797
|
"rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="],
|
|
@@ -874,6 +918,8 @@
|
|
|
874
918
|
|
|
875
919
|
"unstorage": ["unstorage@1.15.0", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^4.0.3", "destr": "^2.0.3", "h3": "^1.15.0", "lru-cache": "^10.4.3", "node-fetch-native": "^1.6.6", "ofetch": "^1.4.1", "ufo": "^1.5.4" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6.0.3", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-m40eHdGY/gA6xAPqo8eaxqXgBuzQTlAKfmB1iF7oCKXE1HfwHwzDJBywK+qQGn52dta+bPlZluPF7++yR3p/bg=="],
|
|
876
920
|
|
|
921
|
+
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
|
922
|
+
|
|
877
923
|
"vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
|
|
878
924
|
|
|
879
925
|
"vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="],
|
ec.config.mjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineEcConfig } from 'astro-expressive-code';
|
|
2
|
+
import { pluginColorChips } from 'expressive-code-color-chips';
|
|
3
|
+
|
|
4
|
+
export default defineEcConfig({
|
|
5
|
+
plugins: [pluginColorChips()],
|
|
6
|
+
// themes: [],
|
|
7
|
+
styleOverrides: {
|
|
8
|
+
codeFontSize: '0.8rem',
|
|
9
|
+
uiFontSize: '0.8rem',
|
|
10
|
+
// frames: {
|
|
11
|
+
// shadowColor: '#124',
|
|
12
|
+
// },
|
|
13
|
+
},
|
|
14
|
+
})
|
package.json
CHANGED
|
@@ -17,9 +17,13 @@
|
|
|
17
17
|
"@appzic/astro-reset-css": "^1.2.0",
|
|
18
18
|
"@astrojs/rss": "^4.0.12",
|
|
19
19
|
"@astrojs/sitemap": "^3.4.1",
|
|
20
|
+
"@tauri-apps/plugin-log": "^2.7.1",
|
|
20
21
|
"astro": "^5.9.0",
|
|
21
22
|
"astro-color-scheme": "^1.1.5",
|
|
23
|
+
"astro-expressive-code": "^0.41.3",
|
|
22
24
|
"astro-icon": "^1.1.5",
|
|
25
|
+
"expressive-code-color-chips": "^0.1.2",
|
|
26
|
+
"pretty-bytes": "^7.1.0",
|
|
23
27
|
"simple-git": "^3.27.0",
|
|
24
28
|
"timeago.js": "^4.0.2"
|
|
25
29
|
},
|
|
@@ -29,4 +33,4 @@
|
|
|
29
33
|
"@tauri-apps/cli": "^2.9.1",
|
|
30
34
|
"@types/node": "^22.15.3"
|
|
31
35
|
}
|
|
32
|
-
}
|
|
36
|
+
}
|
src/content.config.ts
CHANGED
|
@@ -24,6 +24,13 @@ export const collections = {
|
|
|
24
24
|
console.log("loading repo " + repoPath)
|
|
25
25
|
const git = simpleGit(repoPath)
|
|
26
26
|
const commits = await git.log(["--branches", "--tags"]);
|
|
27
|
+
const paths = await git.raw(["ls-files"]);
|
|
28
|
+
const files = await Promise.all(paths.split("\n")
|
|
29
|
+
.filter((p) => p.length > 0)
|
|
30
|
+
.map((p) => fs.stat(`${repoPath}/${p}`)
|
|
31
|
+
.then((stat) => ({ name: p, absolutePath: `${repoPath}/${p}`, ...stat }))
|
|
32
|
+
.catch(() => null)
|
|
33
|
+
))
|
|
27
34
|
const readmeContent = await checkFileExists(readmePath) ? await renderMarkdown(await fs.readFile(readmePath, 'utf-8')) : {
|
|
28
35
|
html: '',
|
|
29
36
|
metadata: {},
|
|
@@ -44,6 +51,7 @@ export const collections = {
|
|
|
44
51
|
branches: item.refs.split(",").filter((ref: string) => ref.includes("origin/")).map((ref) => ref.replace("origin/", "")),
|
|
45
52
|
tags: item.refs.split(",").filter((ref: string) => ref.includes("tag: ")).map((ref) => ref.replace("tag: ", "")),
|
|
46
53
|
})),
|
|
54
|
+
files: files.filter((f) => f !== null),
|
|
47
55
|
},
|
|
48
56
|
rendered: readmeContent,
|
|
49
57
|
});
|
|
@@ -69,6 +77,13 @@ export const collections = {
|
|
|
69
77
|
tags: z.array(z.string()),
|
|
70
78
|
// diff: z.string(),
|
|
71
79
|
})),
|
|
80
|
+
files: z.array(z.object({
|
|
81
|
+
name: z.string(),
|
|
82
|
+
size: z.number(),
|
|
83
|
+
ext: z.string(),
|
|
84
|
+
isDirectory: z.boolean(),
|
|
85
|
+
content: z.string(),
|
|
86
|
+
})),
|
|
72
87
|
}),
|
|
73
88
|
}),
|
|
74
89
|
content: defineCollection({
|
src/layouts/Base.astro
CHANGED
|
@@ -67,9 +67,8 @@ const image = "/favicon.png";
|
|
|
67
67
|
}
|
|
68
68
|
</style>
|
|
69
69
|
<script is:inline>
|
|
70
|
-
console.log(window.__TAURI__);
|
|
71
70
|
if (window.__TAURI__) {
|
|
72
|
-
|
|
71
|
+
window.__TAURI__.log.info("Back key triggered");
|
|
73
72
|
window.__TAURI__.app.onBackButtonPress(() => {
|
|
74
73
|
if (window.history.length > 1) {
|
|
75
74
|
window.history.back();
|
src/layouts/Base.css
CHANGED
|
@@ -12,24 +12,22 @@
|
|
|
12
12
|
--color-code-bg: light-dark(hsl(0, 0%, 95%), hsl(0, 0%, 0%));
|
|
13
13
|
--color-pre-bg: light-dark(hsl(0, 0%, 95%), hsl(0, 0%, 0%));
|
|
14
14
|
--color-tag: light-dark(hsl(152, 96%, 35%), hsl(152, 96%, 44%));
|
|
15
|
+
--color-row-odd: light-dark(hsl(0, 0%, 94%), hsl(0, 0%, 10%));
|
|
16
|
+
--color-row-even: light-dark(hsl(0, 0%, 88%), hsl(0, 0%, 7%));
|
|
15
17
|
--btn-light: none;
|
|
16
18
|
--btn-dark: block;
|
|
19
|
+
|
|
17
20
|
.astro-code, .astro-code span {
|
|
18
|
-
|
|
21
|
+
background: var(--color-pre-bg) !important;
|
|
19
22
|
}
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
[data-theme="dark"] {
|
|
23
26
|
--btn-light: block;
|
|
24
27
|
--btn-dark: none;
|
|
25
|
-
|
|
28
|
+
|
|
26
|
-
.
|
|
29
|
+
.expressive-code .frame pre {
|
|
27
|
-
color: var(--shiki-dark) !important;
|
|
28
|
-
/* background-color: var(--shiki-dark-bg) !important; */
|
|
29
30
|
background: var(--color-pre-bg) !important;
|
|
30
|
-
font-style: var(--shiki-dark-font-style) !important;
|
|
31
|
-
font-weight: var(--shiki-dark-font-weight) !important;
|
|
32
|
-
text-decoration: var(--shiki-dark-text-decoration) !important;
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
33
|
|
src/layouts/Repo.astro
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { type CollectionEntry } from "astro:content";
|
|
3
|
+
import Layout from "@/layouts/Base.astro";
|
|
4
|
+
|
|
5
|
+
type Props = Pick<CollectionEntry<"repos">, "data">;
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
data: { title, description, tags, badges },
|
|
9
|
+
} = Astro.props;
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<Layout title={title} description={description}>
|
|
13
|
+
<div>
|
|
14
|
+
<div class="header">
|
|
15
|
+
<h1>
|
|
16
|
+
<a href="/">~repos</a>
|
|
17
|
+
/{title}
|
|
18
|
+
</h1>
|
|
19
|
+
<div class="badges">
|
|
20
|
+
{
|
|
21
|
+
badges!.map((badge) => (
|
|
22
|
+
<a href={badge.href} target="_blank" rel="noopener noreferrer">
|
|
23
|
+
<img src={badge.img} alt={badge.alt} />
|
|
24
|
+
</a>
|
|
25
|
+
))
|
|
26
|
+
}
|
|
27
|
+
</div>
|
|
28
|
+
<div class="tags">
|
|
29
|
+
{tags.map((tag) => <span class="tag">#{tag}</span>)}
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="info">
|
|
33
|
+
<h3>
|
|
34
|
+
<strong>git clone</strong>
|
|
35
|
+
<span>
|
|
36
|
+
https://pyrossh.dev/repos/{title}.git
|
|
37
|
+
</span>
|
|
38
|
+
</h3>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="headerExtension">
|
|
41
|
+
<h2>{description}</h2>
|
|
42
|
+
</div>
|
|
43
|
+
<hr />
|
|
44
|
+
<div class="nav">
|
|
45
|
+
<div>
|
|
46
|
+
<a href={`/repos/${title}`}>Readme</a>
|
|
47
|
+
</div>
|
|
48
|
+
<div>|</div>
|
|
49
|
+
<div>
|
|
50
|
+
<a href={`/repos/${title}/commits`}>Commits</a>
|
|
51
|
+
</div>
|
|
52
|
+
<div>|</div>
|
|
53
|
+
<div>
|
|
54
|
+
<a class="nav-link" href={`/repos/${title}/files`}>Files</a>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
<slot />
|
|
59
|
+
</Layout>
|
|
60
|
+
<style>
|
|
61
|
+
.header {
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-direction: row;
|
|
64
|
+
align-items: baseline;
|
|
65
|
+
|
|
66
|
+
@media (max-width: 720px) {
|
|
67
|
+
flex-direction: column;
|
|
68
|
+
align-items: start;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
h1 {
|
|
73
|
+
font-size: 1.6rem;
|
|
74
|
+
font-weight: 500;
|
|
75
|
+
line-height: 1;
|
|
76
|
+
margin-bottom: 0.1rem;
|
|
77
|
+
|
|
78
|
+
a {
|
|
79
|
+
color: var(--color-link);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
h2 {
|
|
84
|
+
display: flex;
|
|
85
|
+
flex: 1;
|
|
86
|
+
padding-top: 0.3rem;
|
|
87
|
+
font-size: 0.95rem;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
h3 {
|
|
91
|
+
flex: 1;
|
|
92
|
+
font-size: 1rem;
|
|
93
|
+
font-weight: 400;
|
|
94
|
+
/* padding-left: 0.3rem; */
|
|
95
|
+
|
|
96
|
+
&:first-child {
|
|
97
|
+
margin-right: 1rem;
|
|
98
|
+
|
|
99
|
+
@media (max-width: 720px) {
|
|
100
|
+
margin-right: 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
span {
|
|
105
|
+
color: var(--color-tag);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.badges {
|
|
110
|
+
flex: 1;
|
|
111
|
+
display: flex;
|
|
112
|
+
margin-left: 1rem;
|
|
113
|
+
margin-right: 1rem;
|
|
114
|
+
|
|
115
|
+
@media (max-width: 720px) {
|
|
116
|
+
margin: 0.5rem 0rem;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.tags {
|
|
121
|
+
display: flex;
|
|
122
|
+
flex-wrap: wrap;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.tag {
|
|
126
|
+
color: var(--color-tag);
|
|
127
|
+
padding: 0.15rem 0.5rem 0.5rem 0rem;
|
|
128
|
+
border-radius: 0.25rem;
|
|
129
|
+
font-size: 0.95rem;
|
|
130
|
+
font-weight: 500;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.nav {
|
|
134
|
+
display: flex;
|
|
135
|
+
align-items: center;
|
|
136
|
+
|
|
137
|
+
@media (max-width: 720px) {
|
|
138
|
+
margin-top: 0.5rem;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
div {
|
|
142
|
+
padding-right: 0.5rem;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
a {
|
|
146
|
+
font-size: 12pt;
|
|
147
|
+
padding-right: 0.5rem;
|
|
148
|
+
color: #3395ff;
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.info {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex: 1;
|
|
156
|
+
font-size: 1rem;
|
|
157
|
+
font-weight: 500;
|
|
158
|
+
background-color: var(--color-box-bg);
|
|
159
|
+
|
|
160
|
+
div {
|
|
161
|
+
display: flex;
|
|
162
|
+
flex-direction: column;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
strong {
|
|
166
|
+
font-weight: 500;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
</style>
|
src/pages/posts/[...slug].astro
CHANGED
|
@@ -92,13 +92,5 @@ const { Content } = await render(Astro.props);
|
|
|
92
92
|
padding: 0;
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
|
|
96
|
-
pre {
|
|
97
|
-
font-size: 0.8rem;
|
|
98
|
-
font-family: "monospace";
|
|
99
|
-
line-height: 1.6;
|
|
100
|
-
padding: 16px;
|
|
101
|
-
margin: 12px 0px;
|
|
102
|
-
}
|
|
103
95
|
}
|
|
104
96
|
</style>
|
src/pages/repos/[...slug]/commits/index.astro
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { type CollectionEntry, getCollection } from "astro:content";
|
|
3
|
-
import
|
|
3
|
+
import RepoLayout from "@/layouts/Repo.astro";
|
|
4
4
|
import Commit from "@/components/Commit.astro";
|
|
5
5
|
|
|
6
6
|
export async function getStaticPaths() {
|
|
@@ -12,10 +12,10 @@ export async function getStaticPaths() {
|
|
|
12
12
|
}
|
|
13
13
|
type Props = CollectionEntry<"repos">;
|
|
14
14
|
const {
|
|
15
|
-
data: {
|
|
15
|
+
data: { commits },
|
|
16
16
|
} = Astro.props;
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
<
|
|
19
|
+
<RepoLayout data={Astro.props.data}>
|
|
20
20
|
{commits.map((commit) => <Commit {...commit} message={commit.body} />)}
|
|
21
|
-
</
|
|
21
|
+
</RepoLayout>
|
src/pages/repos/[...slug]/files/[...file]/index.astro
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { type CollectionEntry, getCollection } from "astro:content";
|
|
5
|
+
import { Code } from "astro-expressive-code/components";
|
|
6
|
+
import RepoLayout from "@/layouts/Repo.astro";
|
|
7
|
+
|
|
8
|
+
export async function getStaticPaths() {
|
|
9
|
+
const repos = await getCollection("repos");
|
|
10
|
+
return repos.flatMap((repo) =>
|
|
11
|
+
repo.data.files.map((file) => ({
|
|
12
|
+
params: { slug: repo.id, file: file.name },
|
|
13
|
+
props: {
|
|
14
|
+
repo: repo,
|
|
15
|
+
file: file,
|
|
16
|
+
},
|
|
17
|
+
}))
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
type Props = {
|
|
21
|
+
repo: CollectionEntry<"repos">;
|
|
22
|
+
file: {
|
|
23
|
+
name: string;
|
|
24
|
+
size: number;
|
|
25
|
+
isDirectory: boolean;
|
|
26
|
+
absolutePath: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const { repo, file } = Astro.props;
|
|
31
|
+
const contentBuffer = await fs.readFile(file.absolutePath);
|
|
32
|
+
const name = path.basename(file.name);
|
|
33
|
+
const ext = path.extname(file.name).replace(".", "");
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
<RepoLayout data={repo.data}>
|
|
37
|
+
{
|
|
38
|
+
["png", "jpg", "jpeg", "gif", "svg"].includes(ext) ? (
|
|
39
|
+
<div>
|
|
40
|
+
<h1>{name}</h1>
|
|
41
|
+
<img
|
|
42
|
+
src={`data:image/${ext};base64,${Buffer.from(contentBuffer).toString("base64")}`}
|
|
43
|
+
alt={name}
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
) : (
|
|
47
|
+
<div>
|
|
48
|
+
<div class="name blob">{name}</div>
|
|
49
|
+
<Code
|
|
50
|
+
code={Buffer.from(contentBuffer).toString("utf-8")}
|
|
51
|
+
lang={ext}
|
|
52
|
+
wrap
|
|
53
|
+
/>
|
|
54
|
+
</div>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
</RepoLayout>
|
src/pages/repos/[...slug]/files/index.astro
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { type CollectionEntry, getCollection } from "astro:content";
|
|
3
|
+
import prettyBytes from "pretty-bytes";
|
|
3
|
-
import
|
|
4
|
+
import RepoLayout from "@/layouts/Repo.astro";
|
|
4
5
|
|
|
5
6
|
export async function getStaticPaths() {
|
|
6
7
|
const repos = await getCollection("repos");
|
|
@@ -11,10 +12,77 @@ export async function getStaticPaths() {
|
|
|
11
12
|
}
|
|
12
13
|
type Props = CollectionEntry<"repos">;
|
|
13
14
|
const {
|
|
14
|
-
data: { title, description,
|
|
15
|
+
data: { title, description, files, tags, badges },
|
|
15
16
|
} = Astro.props;
|
|
16
17
|
---
|
|
17
18
|
|
|
18
|
-
<
|
|
19
|
+
<RepoLayout data={Astro.props.data}>
|
|
20
|
+
<div class="container">
|
|
21
|
+
<ul>
|
|
22
|
+
{
|
|
23
|
+
files.map((file) => (
|
|
24
|
+
<li>
|
|
25
|
+
<div class="mode">
|
|
19
|
-
|
|
26
|
+
<span title="100644">-rw-r--r--</span>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="name">
|
|
29
|
+
<a href={`/repos/${title}/files/${file.name}`} rel="nofollow">
|
|
30
|
+
{file.name}
|
|
31
|
+
</a>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="size">
|
|
34
|
+
<span>{prettyBytes(file.size).replace(" ", "")}</span>
|
|
35
|
+
</div>
|
|
36
|
+
</li>
|
|
37
|
+
))
|
|
38
|
+
}
|
|
39
|
+
</ul>
|
|
40
|
+
</div>
|
|
20
|
-
</
|
|
41
|
+
</RepoLayout>
|
|
42
|
+
<style>
|
|
43
|
+
.container {
|
|
44
|
+
display: flex;
|
|
45
|
+
margin-top: 1rem;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
ul {
|
|
49
|
+
display: flex;
|
|
50
|
+
flex: 1;
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
font-size: 1.1rem;
|
|
53
|
+
gap: 0.5rem;
|
|
54
|
+
|
|
55
|
+
li {
|
|
56
|
+
display: flex;
|
|
57
|
+
flex: 1;
|
|
58
|
+
flex-wrap: wrap;
|
|
59
|
+
|
|
60
|
+
&:nth-child(odd) {
|
|
61
|
+
background-color: var(--color-row-odd);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&:nth-child(even) {
|
|
65
|
+
background-color: var(--color-row-even);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.mode {
|
|
71
|
+
margin-right: 1rem;
|
|
72
|
+
/* color: rgb(var(--gray)); */
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.name {
|
|
76
|
+
flex: 1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.size {
|
|
80
|
+
/* background-color: var(--color-code-bg); */
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.tree-list {
|
|
84
|
+
display: grid;
|
|
85
|
+
grid-template-columns: auto auto;
|
|
86
|
+
font-size: 1rem;
|
|
87
|
+
}
|
|
88
|
+
</style>
|
src/pages/repos/[...slug]/index.astro
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { type CollectionEntry, getCollection } from "astro:content";
|
|
3
3
|
import { render } from "astro:content";
|
|
4
|
-
import
|
|
4
|
+
import RepoLayout from "@/layouts/Repo.astro";
|
|
5
5
|
import Commit from "@/components/Commit.astro";
|
|
6
6
|
import styles from "./index.module.css";
|
|
7
7
|
|
|
@@ -15,52 +15,13 @@ export async function getStaticPaths() {
|
|
|
15
15
|
type Props = CollectionEntry<"repos">;
|
|
16
16
|
|
|
17
17
|
const {
|
|
18
|
-
data: {
|
|
18
|
+
data: { commits },
|
|
19
19
|
} = Astro.props;
|
|
20
20
|
const latestCommits = commits.slice(0, 3);
|
|
21
21
|
const { Content } = await render(Astro.props);
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
<Layout title={title} description={description}>
|
|
25
|
-
<div class={styles.header}>
|
|
26
|
-
<h1>
|
|
27
|
-
<a href="/">~repos</a>
|
|
28
|
-
/{title}
|
|
29
|
-
</h1>
|
|
30
|
-
<div class={styles.badges}>
|
|
31
|
-
{
|
|
32
|
-
badges.map((badge) => (
|
|
33
|
-
<a href={badge.href} target="_blank" rel="noopener noreferrer">
|
|
34
|
-
<img src={badge.img} alt={badge.alt} />
|
|
35
|
-
</a>
|
|
36
|
-
))
|
|
37
|
-
}
|
|
38
|
-
</div>
|
|
39
|
-
|
|
24
|
+
<RepoLayout data={Astro.props.data}>
|
|
40
|
-
{tags.map((tag) => <span class={styles.tag}>#{tag}</span>)}
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
<div class={styles.info}>
|
|
44
|
-
<h3>
|
|
45
|
-
<strong>git clone</strong>
|
|
46
|
-
<span>
|
|
47
|
-
https://pyrossh.dev/repos/{title}.git
|
|
48
|
-
</span>
|
|
49
|
-
</h3>
|
|
50
|
-
</div>
|
|
51
|
-
<div class={styles.headerExtension}>
|
|
52
|
-
<h2>{description}</h2>
|
|
53
|
-
</div>
|
|
54
|
-
<hr />
|
|
55
|
-
<div class={styles.nav}>
|
|
56
|
-
<div>
|
|
57
|
-
<a href={`/repos/${title}/commits`}>Commits</a>
|
|
58
|
-
</div>
|
|
59
|
-
<div>|</div>
|
|
60
|
-
<div>
|
|
61
|
-
<a class="nav-link" href={`/repos/${title}/files`}>Files</a>
|
|
62
|
-
</div>
|
|
63
|
-
</div>
|
|
64
25
|
<div class={styles.summary}>
|
|
65
26
|
{latestCommits.map((commit) => <Commit {...commit} />)}
|
|
66
27
|
</div>
|
|
@@ -68,4 +29,4 @@ const { Content } = await render(Astro.props);
|
|
|
68
29
|
<article>
|
|
69
30
|
<Content />
|
|
70
31
|
</article>
|
|
71
|
-
</
|
|
32
|
+
</RepoLayout>
|
src/pages/repos/[...slug]/index.module.css
CHANGED
|
@@ -1,112 +1,3 @@
|
|
|
1
|
-
.header {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: row;
|
|
4
|
-
align-items: baseline;
|
|
5
|
-
|
|
6
|
-
@media (max-width: 720px) {
|
|
7
|
-
flex-direction: column;
|
|
8
|
-
align-items: start;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
h1 {
|
|
13
|
-
font-size: 1.6rem;
|
|
14
|
-
font-weight: 500;
|
|
15
|
-
line-height: 1;
|
|
16
|
-
margin-bottom: 0.1rem;
|
|
17
|
-
|
|
18
|
-
a {
|
|
19
|
-
color: var(--color-link);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
h2 {
|
|
24
|
-
display: flex;
|
|
25
|
-
flex: 1;
|
|
26
|
-
padding-top: 0.3rem;
|
|
27
|
-
font-size: 0.95rem;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
h3 {
|
|
31
|
-
flex: 1;
|
|
32
|
-
font-size: 1rem;
|
|
33
|
-
font-weight: 400;
|
|
34
|
-
/* padding-left: 0.3rem; */
|
|
35
|
-
|
|
36
|
-
&:first-child {
|
|
37
|
-
margin-right: 1rem;
|
|
38
|
-
|
|
39
|
-
@media (max-width: 720px) {
|
|
40
|
-
margin-right: 0;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
span {
|
|
45
|
-
color: var(--color-tag);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.badges {
|
|
50
|
-
flex: 1;
|
|
51
|
-
display: flex;
|
|
52
|
-
margin-left: 1rem;
|
|
53
|
-
margin-right: 1rem;
|
|
54
|
-
|
|
55
|
-
@media (max-width: 720px) {
|
|
56
|
-
margin: 0.5rem 0rem;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.tags {
|
|
61
|
-
display: flex;
|
|
62
|
-
flex-wrap: wrap;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.tag {
|
|
66
|
-
color: var(--color-tag);
|
|
67
|
-
padding: 0.15rem 0.5rem 0.5rem 0rem;
|
|
68
|
-
border-radius: 0.25rem;
|
|
69
|
-
font-size: 0.95rem;
|
|
70
|
-
font-weight: 500;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.nav {
|
|
74
|
-
display: flex;
|
|
75
|
-
align-items: center;
|
|
76
|
-
|
|
77
|
-
@media (max-width: 720px) {
|
|
78
|
-
margin-top: 0.5rem;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
div {
|
|
82
|
-
padding-right: 0.5rem;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
a {
|
|
86
|
-
font-size: 12pt;
|
|
87
|
-
padding-right: 0.5rem;
|
|
88
|
-
color: #3395ff;
|
|
89
|
-
cursor: pointer;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.info {
|
|
94
|
-
display: flex;
|
|
95
|
-
flex: 1;
|
|
96
|
-
font-size: 1rem;
|
|
97
|
-
font-weight: 500;
|
|
98
|
-
background-color: var(--color-box-bg);
|
|
99
|
-
|
|
100
|
-
div {
|
|
101
|
-
display: flex;
|
|
102
|
-
flex-direction: column;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
strong {
|
|
106
|
-
font-weight: 500;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
1
|
.summary {
|
|
111
2
|
display: grid;
|
|
112
3
|
grid-template-columns: auto;
|
|
@@ -168,14 +59,6 @@ article {
|
|
|
168
59
|
}
|
|
169
60
|
}
|
|
170
61
|
|
|
171
|
-
pre {
|
|
172
|
-
font-size: 0.8rem;
|
|
173
|
-
font-family: "monospace";
|
|
174
|
-
line-height: 1.6;
|
|
175
|
-
padding: 16px;
|
|
176
|
-
margin: 12px 0px;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
62
|
blockquote {
|
|
180
63
|
padding-left: 0.5rem;
|
|
181
64
|
border-left: 3px solid #aaa;
|