Compare commits
10 commits
1f99fc17f5
...
4df091aab5
| Author | SHA1 | Date | |
|---|---|---|---|
| 4df091aab5 | |||
| 92a7c6fbac | |||
|
|
729828bedc | ||
|
|
7907ec7af5 | ||
|
|
5a0a6c8e6e | ||
|
|
d952ca43a0 | ||
|
|
1b4d159f99 | ||
|
|
f36aacda77 | ||
|
|
ae8c323604 | ||
|
|
e44df108b4 |
26
bun.lock
|
|
@ -10,18 +10,18 @@
|
||||||
"@astrojs/rss": "^4.0.11",
|
"@astrojs/rss": "^4.0.11",
|
||||||
"@astrojs/sitemap": "^3.2.1",
|
"@astrojs/sitemap": "^3.2.1",
|
||||||
"@expressive-code/plugin-collapsible-sections": "^0.40.1",
|
"@expressive-code/plugin-collapsible-sections": "^0.40.1",
|
||||||
"@expressive-code/plugin-line-numbers": "^0.40.1",
|
"@expressive-code/plugin-line-numbers": "^0.41.2",
|
||||||
"@tailwindcss/vite": "^4.0.3",
|
"@tailwindcss/vite": "^4.0.3",
|
||||||
"@types/react": "^19.0.8",
|
"@types/react": "^19.0.8",
|
||||||
"@types/react-dom": "^19.0.3",
|
"@types/react-dom": "^19.0.3",
|
||||||
"astro": "^5.2.3",
|
"astro": "^5.2.3",
|
||||||
"astro-expressive-code": "^0.40.1",
|
"astro-expressive-code": "^0.40.1",
|
||||||
"astro-google-analytics": "^1.0.3",
|
"astro-google-analytics": "^1.0.3",
|
||||||
"astro-og-canvas": "^0.5.6",
|
"astro-og-canvas": "^0.7.0",
|
||||||
"astro-robots-txt": "^1.0.0",
|
"astro-robots-txt": "^1.0.0",
|
||||||
"canvaskit-wasm": "^0.39.1",
|
"canvaskit-wasm": "^0.40.0",
|
||||||
"lefthook": "^1.10.10",
|
"lefthook": "^1.10.10",
|
||||||
"lucide-react": "^0.474.0",
|
"lucide-react": "^0.525.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"tailwindcss": "^4.0.3",
|
"tailwindcss": "^4.0.3",
|
||||||
|
|
@ -197,7 +197,7 @@
|
||||||
|
|
||||||
"@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.40.1", "https://registry.npmmirror.com/@expressive-code/plugin-frames/-/plugin-frames-0.40.1.tgz", { "dependencies": { "@expressive-code/core": "^0.40.1" } }, "sha512-qV7BIdTQ9nJ/eLHaJlzMvUq5aqAoZKO3PLFzBVop/q0d0m5rWpwWncIQ8qkufQDabmq2m38PRRWxKgx5FkJ2Rg=="],
|
"@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.40.1", "https://registry.npmmirror.com/@expressive-code/plugin-frames/-/plugin-frames-0.40.1.tgz", { "dependencies": { "@expressive-code/core": "^0.40.1" } }, "sha512-qV7BIdTQ9nJ/eLHaJlzMvUq5aqAoZKO3PLFzBVop/q0d0m5rWpwWncIQ8qkufQDabmq2m38PRRWxKgx5FkJ2Rg=="],
|
||||||
|
|
||||||
"@expressive-code/plugin-line-numbers": ["@expressive-code/plugin-line-numbers@0.40.1", "https://registry.npmmirror.com/@expressive-code/plugin-line-numbers/-/plugin-line-numbers-0.40.1.tgz", { "dependencies": { "@expressive-code/core": "^0.40.1" } }, "sha512-9SgO73lamP46SuRlPkFAFGYKPy+MCzXAyT+VUeNA95g+CUVrNx0ySevEWAATQ9JmVUp4vNETbssJdMJb7Xcqiw=="],
|
"@expressive-code/plugin-line-numbers": ["@expressive-code/plugin-line-numbers@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3" } }, "sha512-eig82a4CRC3XgVPQ2S/TMDcLiHJokOCD/mAdNVImpD3segVewxfjGgtj5DXQRo0E0q6f0R0EH34YzTFl5CEPqg=="],
|
||||||
|
|
||||||
"@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.40.1", "https://registry.npmmirror.com/@expressive-code/plugin-shiki/-/plugin-shiki-0.40.1.tgz", { "dependencies": { "@expressive-code/core": "^0.40.1", "shiki": "^1.26.1" } }, "sha512-N5oXhLv5DwLGXmLwJtwMzrfnZPWJl4pHRR5mfDoqK1+NxptdVaaQ0nEjgw13Y5ID/O5Bbze5YcOyph2K52BBrQ=="],
|
"@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.40.1", "https://registry.npmmirror.com/@expressive-code/plugin-shiki/-/plugin-shiki-0.40.1.tgz", { "dependencies": { "@expressive-code/core": "^0.40.1", "shiki": "^1.26.1" } }, "sha512-N5oXhLv5DwLGXmLwJtwMzrfnZPWJl4pHRR5mfDoqK1+NxptdVaaQ0nEjgw13Y5ID/O5Bbze5YcOyph2K52BBrQ=="],
|
||||||
|
|
||||||
|
|
@ -503,7 +503,7 @@
|
||||||
|
|
||||||
"astro-google-analytics": ["astro-google-analytics@1.0.3", "https://registry.npmmirror.com/astro-google-analytics/-/astro-google-analytics-1.0.3.tgz", {}, "sha512-5bD7jA15yxVaUFVVEFG6KKMphYJ4AKP4+HSqCVBpTBnqh8LL0giTdAHpG9KJs3JaFbGQUTWP5Pqt8+twz7f55Q=="],
|
"astro-google-analytics": ["astro-google-analytics@1.0.3", "https://registry.npmmirror.com/astro-google-analytics/-/astro-google-analytics-1.0.3.tgz", {}, "sha512-5bD7jA15yxVaUFVVEFG6KKMphYJ4AKP4+HSqCVBpTBnqh8LL0giTdAHpG9KJs3JaFbGQUTWP5Pqt8+twz7f55Q=="],
|
||||||
|
|
||||||
"astro-og-canvas": ["astro-og-canvas@0.5.6", "https://registry.npmmirror.com/astro-og-canvas/-/astro-og-canvas-0.5.6.tgz", { "dependencies": { "canvaskit-wasm": "^0.39.1", "deterministic-object-hash": "^2.0.2", "entities": "^4.4.0" }, "peerDependencies": { "astro": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, "sha512-w75UErZdRxYyoVnTz4IXn6T869PBrwYQEjPecWVaev9faYCHC3Uk7R47KCO3u+MSDkc8tCENz4ghVDrLImx9SA=="],
|
"astro-og-canvas": ["astro-og-canvas@0.7.2", "", { "dependencies": { "canvaskit-wasm": "^0.40.0", "deterministic-object-hash": "^2.0.2", "entities": "^7.0.0" }, "peerDependencies": { "astro": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, "sha512-i7sWbdpl2MMF7wUZqSfzMnhW4c7GQz6s7T4BUJ7E06MqasZRHjJytn0n6D0JJkGDeTpZnU7E00A6Ffx0pRB4kg=="],
|
||||||
|
|
||||||
"astro-robots-txt": ["astro-robots-txt@1.0.0", "https://registry.npmmirror.com/astro-robots-txt/-/astro-robots-txt-1.0.0.tgz", { "dependencies": { "valid-filename": "^4.0.0", "zod": "^3.22.2" } }, "sha512-6JQSLid4gMhoWjOm85UHLkgrw0+hHIjnJVIUqxjU2D6feKlVyYukMNYjH44ZDZBK1P8hNxd33PgWlHzCASvedA=="],
|
"astro-robots-txt": ["astro-robots-txt@1.0.0", "https://registry.npmmirror.com/astro-robots-txt/-/astro-robots-txt-1.0.0.tgz", { "dependencies": { "valid-filename": "^4.0.0", "zod": "^3.22.2" } }, "sha512-6JQSLid4gMhoWjOm85UHLkgrw0+hHIjnJVIUqxjU2D6feKlVyYukMNYjH44ZDZBK1P8hNxd33PgWlHzCASvedA=="],
|
||||||
|
|
||||||
|
|
@ -549,7 +549,7 @@
|
||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001696", "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz", {}, "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001696", "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz", {}, "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ=="],
|
||||||
|
|
||||||
"canvaskit-wasm": ["canvaskit-wasm@0.39.1", "https://registry.npmmirror.com/canvaskit-wasm/-/canvaskit-wasm-0.39.1.tgz", { "dependencies": { "@webgpu/types": "0.1.21" } }, "sha512-Gy3lCmhUdKq+8bvDrs9t8+qf7RvcjuQn+we7vTVVyqgOVO1UVfHpsnBxkTZw+R4ApEJ3D5fKySl9TU11hmjl/A=="],
|
"canvaskit-wasm": ["canvaskit-wasm@0.40.0", "", { "dependencies": { "@webgpu/types": "0.1.21" } }, "sha512-Od2o+ZmoEw9PBdN/yCGvzfu0WVqlufBPEWNG452wY7E9aT8RBE+ChpZF526doOlg7zumO4iCS+RAeht4P0Gbpw=="],
|
||||||
|
|
||||||
"ccount": ["ccount@2.0.1", "https://registry.npmmirror.com/ccount/-/ccount-2.0.1.tgz", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
|
"ccount": ["ccount@2.0.1", "https://registry.npmmirror.com/ccount/-/ccount-2.0.1.tgz", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
|
||||||
|
|
||||||
|
|
@ -667,7 +667,7 @@
|
||||||
|
|
||||||
"enhanced-resolve": ["enhanced-resolve@5.18.0", "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ=="],
|
"enhanced-resolve": ["enhanced-resolve@5.18.0", "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ=="],
|
||||||
|
|
||||||
"entities": ["entities@4.5.0", "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
"entities": ["entities@7.0.0", "", {}, "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ=="],
|
||||||
|
|
||||||
"es-abstract": ["es-abstract@1.23.9", "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.23.9.tgz", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.3", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.0", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-regex": "^1.2.1", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.0", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.18" } }, "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA=="],
|
"es-abstract": ["es-abstract@1.23.9", "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.23.9.tgz", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.3", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.0", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-regex": "^1.2.1", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.0", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.18" } }, "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA=="],
|
||||||
|
|
||||||
|
|
@ -1037,7 +1037,7 @@
|
||||||
|
|
||||||
"lru-cache": ["lru-cache@10.4.3", "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"lru-cache": ["lru-cache@10.4.3", "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
"lucide-react": ["lucide-react@0.474.0", "https://registry.npmmirror.com/lucide-react/-/lucide-react-0.474.0.tgz", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA=="],
|
"lucide-react": ["lucide-react@0.525.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ=="],
|
||||||
|
|
||||||
"magic-string": ["magic-string@0.30.17", "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
"magic-string": ["magic-string@0.30.17", "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||||
|
|
||||||
|
|
@ -1615,6 +1615,8 @@
|
||||||
|
|
||||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "https://registry.npmmirror.com/globals/-/globals-14.0.0.tgz", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
"@eslint/eslintrc/globals": ["globals@14.0.0", "https://registry.npmmirror.com/globals/-/globals-14.0.0.tgz", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||||
|
|
||||||
|
"@expressive-code/plugin-line-numbers/@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=="],
|
||||||
|
|
||||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "https://registry.npmmirror.com/@humanwhocodes/retry/-/retry-0.3.1.tgz", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "https://registry.npmmirror.com/@humanwhocodes/retry/-/retry-0.3.1.tgz", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||||
|
|
||||||
"@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
"@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
@ -1633,10 +1635,14 @@
|
||||||
|
|
||||||
"cliui/wrap-ansi": ["wrap-ansi@7.0.0", "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
"cliui/wrap-ansi": ["wrap-ansi@7.0.0", "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
||||||
|
|
||||||
|
"dom-serializer/entities": ["entities@4.5.0", "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||||
|
|
||||||
"eslint-plugin-astro/postcss-selector-parser": ["postcss-selector-parser@7.0.0", "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ=="],
|
"eslint-plugin-astro/postcss-selector-parser": ["postcss-selector-parser@7.0.0", "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ=="],
|
||||||
|
|
||||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|
||||||
|
"htmlparser2/entities": ["entities@4.5.0", "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||||
|
|
||||||
"load-yaml-file/js-yaml": ["js-yaml@3.14.1", "https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="],
|
"load-yaml-file/js-yaml": ["js-yaml@3.14.1", "https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="],
|
||||||
|
|
||||||
"mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
|
"mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
|
||||||
|
|
@ -1647,6 +1653,8 @@
|
||||||
|
|
||||||
"parse-entities/@types/unist": ["@types/unist@2.0.11", "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
|
"parse-entities/@types/unist": ["@types/unist@2.0.11", "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
|
||||||
|
|
||||||
|
"parse5/entities": ["entities@4.5.0", "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||||
|
|
||||||
"pkg-dir/find-up": ["find-up@4.1.0", "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
|
"pkg-dir/find-up": ["find-up@4.1.0", "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
|
||||||
|
|
||||||
"postcss-nested/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
|
"postcss-nested/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,18 @@
|
||||||
"@astrojs/rss": "^4.0.11",
|
"@astrojs/rss": "^4.0.11",
|
||||||
"@astrojs/sitemap": "^3.2.1",
|
"@astrojs/sitemap": "^3.2.1",
|
||||||
"@expressive-code/plugin-collapsible-sections": "^0.40.1",
|
"@expressive-code/plugin-collapsible-sections": "^0.40.1",
|
||||||
"@expressive-code/plugin-line-numbers": "^0.40.1",
|
"@expressive-code/plugin-line-numbers": "^0.41.2",
|
||||||
"@tailwindcss/vite": "^4.0.3",
|
"@tailwindcss/vite": "^4.0.3",
|
||||||
"@types/react": "^19.0.8",
|
"@types/react": "^19.0.8",
|
||||||
"@types/react-dom": "^19.0.3",
|
"@types/react-dom": "^19.0.3",
|
||||||
"astro": "^5.2.3",
|
"astro": "^5.2.3",
|
||||||
"astro-expressive-code": "^0.40.1",
|
"astro-expressive-code": "^0.40.1",
|
||||||
"astro-google-analytics": "^1.0.3",
|
"astro-google-analytics": "^1.0.3",
|
||||||
"astro-og-canvas": "^0.5.6",
|
"astro-og-canvas": "^0.7.0",
|
||||||
"astro-robots-txt": "^1.0.0",
|
"astro-robots-txt": "^1.0.0",
|
||||||
"canvaskit-wasm": "^0.39.1",
|
"canvaskit-wasm": "^0.40.0",
|
||||||
"lefthook": "^1.10.10",
|
"lefthook": "^1.10.10",
|
||||||
"lucide-react": "^0.474.0",
|
"lucide-react": "^0.525.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"tailwindcss": "^4.0.3",
|
"tailwindcss": "^4.0.3",
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
BIN
public/images/page-meta/general/404.png
Normal file
|
After Width: | Height: | Size: 873 KiB |
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
import Twikoo from "~/components/astro/twikoo.astro"
|
|
||||||
import { common } from "~/config"
|
|
||||||
---
|
|
||||||
|
|
||||||
{common.comments.enabled && common.comments.twikoo.enabled && <Twikoo />}
|
|
||||||
|
|
@ -1,25 +1,24 @@
|
||||||
---
|
<!-- ---
|
||||||
const currentYear = new Date().getFullYear()
|
const currentYear = new Date().getFullYear()
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer class="flex flex-wrap items-center gap-1 py-10">
|
<footer class="flex flex-wrap items-center gap-1 py-10 opacity-25">
|
||||||
<p>© {currentYear}</p>
|
<p>© {currentYear}</p>
|
||||||
|
|
||||||
{
|
{
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
text: "Designed By",
|
text: "By",
|
||||||
link: "https://sunguoqi.com",
|
link: "https://lio.to/bluesky",
|
||||||
label: "Guoqi Sun",
|
label: "@lio.cat",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "Powered By",
|
text: "Based on",
|
||||||
link: "https://github.com/sun0225SUN/astro-air",
|
link: "https://github.com/sun0225SUN/astro-air",
|
||||||
label: "Astro Air",
|
label: "Astro Air",
|
||||||
},
|
},
|
||||||
].map((item, index) => (
|
].map((item, index) => (
|
||||||
<>
|
<>
|
||||||
{index > 0 && <p class="mx-1">|</p>}
|
|
||||||
<p>{item.text}</p>
|
<p>{item.text}</p>
|
||||||
<a
|
<a
|
||||||
href={item.link}
|
href={item.link}
|
||||||
|
|
@ -30,4 +29,4 @@ const currentYear = new Date().getFullYear()
|
||||||
</>
|
</>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</footer>
|
</footer> -->
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
import { Rss } from "lucide-react"
|
import { Rss } from "lucide-react"
|
||||||
import { LanguageToggle } from "~/components/react/language-toggle"
|
import { LanguageToggle } from "~/components/react/language-toggle"
|
||||||
import { ThemeToggle } from "~/components/react/theme-toggle"
|
import { ThemeToggle } from "~/components/react/theme-toggle"
|
||||||
import { en, zh } from "~/config"
|
import { de, en } from "~/config"
|
||||||
import { getLangFromUrl } from "~/i18n/utils"
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
|
|
||||||
const lang = getLangFromUrl(Astro.url)
|
const lang = getLangFromUrl(Astro.url)
|
||||||
const config = lang === "zh" ? zh : en
|
const config = lang === "de" ? de : en
|
||||||
---
|
---
|
||||||
|
|
||||||
<header class="flex h-24 w-full items-center justify-between">
|
<header class="flex h-24 w-full items-center justify-between">
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
---
|
---
|
||||||
|
import IntroContentDe from "~/config/de/intro.mdx"
|
||||||
import IntroContentEn from "~/config/en/intro.mdx"
|
import IntroContentEn from "~/config/en/intro.mdx"
|
||||||
import IntroContentZh from "~/config/zh/intro.mdx"
|
|
||||||
import { getLangFromUrl } from "~/i18n/utils"
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
|
|
||||||
const lang = getLangFromUrl(Astro.url)
|
const lang = getLangFromUrl(Astro.url)
|
||||||
const IntroContent = lang === "zh" ? IntroContentZh : IntroContentEn
|
const IntroContent = lang === "de" ? IntroContentDe : IntroContentEn
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="my-10">
|
<div class="my-10">
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
---
|
---
|
||||||
import { en, zh } from "~/config"
|
import { de, en } from "~/config"
|
||||||
import { getLangFromUrl, useTranslations } from "~/i18n/utils"
|
import { getLangFromUrl, useTranslations } from "~/i18n/utils"
|
||||||
|
|
||||||
const lang = getLangFromUrl(Astro.url)
|
const lang = getLangFromUrl(Astro.url)
|
||||||
const t = useTranslations(lang)
|
const t = useTranslations(lang)
|
||||||
|
|
||||||
const { home, archive, custom, links, about } =
|
const { home, archive, custom, links, about } =
|
||||||
lang === "zh" ? zh.navigation : en.navigation
|
lang === "de" ? de.navigation : en.navigation
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="mb-10 mt-4 flex gap-4 overflow-x-auto whitespace-nowrap text-lg [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
class="mt-4 mb-10 flex gap-4 overflow-x-auto text-lg whitespace-nowrap [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
home && (
|
home && (
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
<div id="tcomment"></div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import twikoo from "twikoo"
|
|
||||||
import { common, defaultLanguage } from "~/config"
|
|
||||||
import "~/styles/twikoo.css"
|
|
||||||
|
|
||||||
function initTwikoo() {
|
|
||||||
twikoo({
|
|
||||||
envId: common.comments.twikoo.envId,
|
|
||||||
el: "#tcomment",
|
|
||||||
lang: defaultLanguage === "zh" ? "zh-CN" : "en-GB",
|
|
||||||
}).then(() => {
|
|
||||||
console.log("comment loading success")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
initTwikoo()
|
|
||||||
|
|
||||||
document.addEventListener("astro:page-load", () => {
|
|
||||||
initTwikoo()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
@ -5,8 +5,8 @@ export function LanguageToggle() {
|
||||||
const currentPath = window.location.pathname
|
const currentPath = window.location.pathname
|
||||||
|
|
||||||
const newPath = currentPath.includes("/en")
|
const newPath = currentPath.includes("/en")
|
||||||
? currentPath.replace("/en", "/zh")
|
? currentPath.replace("/en", "/de")
|
||||||
: currentPath.replace("/zh", "/en")
|
: currentPath.replace("/de", "/en")
|
||||||
|
|
||||||
window.location.href = newPath
|
window.location.href = newPath
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
src/config/de/intro.mdx
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
export const age = new Date().getFullYear() - 2002
|
||||||
|
|
||||||
|
<p>
|
||||||
|
they/them (er/ihm) ⋅ {age}yo digital sorcerer und pixel wizard ⋅ self-hoster ⋅
|
||||||
|
liebt automation
|
||||||
|
</p>
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
<div class="flex flex-col gap-2">
|
export const age = new Date().getFullYear() - 2002
|
||||||
<p>
|
|
||||||
🖥️ Front-end developer (React)|📸 Photography enthusiast (Nikon)|🛸 Travel
|
<p>
|
||||||
explorer (experiencer)|🚴 Cycling freestyler (Java SILURO6-TOP 6)|🍎
|
they/them ⋅ {age}yo digital sorcerer and pixel wizard ⋅ self-hoster ⋅ loves
|
||||||
Technology product enthusiast (Apple & Xiaomi)
|
automation
|
||||||
</p>
|
</p>
|
||||||
<p>💬 Try, fail, retry. That's the rhythm of growth.</p>
|
|
||||||
</div>
|
|
||||||
|
|
|
||||||
|
|
@ -3,22 +3,22 @@ import { Github, Twitter } from "lucide-react"
|
||||||
export const defaultLanguage: string = "en"
|
export const defaultLanguage: string = "en"
|
||||||
|
|
||||||
export const common = {
|
export const common = {
|
||||||
domain: "https://astro-air.guoqi.dev",
|
domain: "https://lio.cat",
|
||||||
meta: {
|
meta: {
|
||||||
favicon: "/avatar.png",
|
favicon: "/avatar.png",
|
||||||
url: "https://blog.sunguoqi.com",
|
url: "https://lio.cat",
|
||||||
},
|
},
|
||||||
googleAnalyticsId: "",
|
googleAnalyticsId: "",
|
||||||
social: [
|
social: [
|
||||||
{
|
{
|
||||||
icon: Twitter,
|
icon: Twitter,
|
||||||
label: "X",
|
label: "X",
|
||||||
link: "https://x.com/sun0225SUN",
|
link: "https://lio.to/twitter",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: Github,
|
icon: Github,
|
||||||
label: "GitHub",
|
label: "GitHub",
|
||||||
link: "https://github.com/sun0225SUN",
|
link: "https://lio.to/github",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
rss: true,
|
rss: true,
|
||||||
|
|
@ -26,94 +26,89 @@ export const common = {
|
||||||
home: true,
|
home: true,
|
||||||
archive: true,
|
archive: true,
|
||||||
custom: [
|
custom: [
|
||||||
{
|
// {
|
||||||
label: "CamLife",
|
// label: "CamLife",
|
||||||
link: "https://camlife.cn",
|
// link: "https://camlife.cn",
|
||||||
},
|
// },
|
||||||
],
|
],
|
||||||
links: true,
|
links: false,
|
||||||
about: true,
|
about: false,
|
||||||
},
|
},
|
||||||
latestPosts: 8,
|
latestPosts: 8,
|
||||||
comments: {
|
comments: {
|
||||||
enabled: true,
|
enabled: false,
|
||||||
twikoo: {
|
twikoo: {
|
||||||
enabled: true,
|
enabled: false,
|
||||||
// replace with your own envId
|
// replace with your own envId
|
||||||
envId: import.meta.env.PUBLIC_TWIKOO_ENV_ID ?? "",
|
envId: import.meta.env.PUBLIC_TWIKOO_ENV_ID ?? "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const zh = {
|
export const de = {
|
||||||
...common,
|
...common,
|
||||||
siteName: "小孙同学",
|
siteName: "Lio",
|
||||||
meta: {
|
meta: {
|
||||||
...common.meta,
|
...common.meta,
|
||||||
title: "小孙同学",
|
title: "Lio",
|
||||||
slogan: "一个浪漫的理性主义者",
|
slogan: "fangmarks",
|
||||||
description: "读书、摄影、编程、旅行",
|
description: "digital sorcerer and pixel wizard",
|
||||||
},
|
},
|
||||||
navigation: {
|
navigation: {
|
||||||
...common.navigation,
|
...common.navigation,
|
||||||
custom: [
|
custom: [
|
||||||
{
|
// {
|
||||||
label: "影集",
|
// label: "影集",
|
||||||
link: "https://camlife.cn",
|
// link: "https://camlife.cn",
|
||||||
},
|
// },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
pageMeta: {
|
pageMeta: {
|
||||||
archive: {
|
archive: {
|
||||||
title: "归档",
|
title: "归档",
|
||||||
description: "小孙同学的所有文章",
|
description: "小孙同学的所有文章",
|
||||||
ogImage: "/images/page-meta/zh/archive.png",
|
ogImage: "/images/page-meta/de/archive.png",
|
||||||
},
|
},
|
||||||
links: {
|
links: {
|
||||||
title: "朋友们",
|
title: "朋友们",
|
||||||
description: "小孙同学的和他朋友们",
|
description: "小孙同学的和他朋友们",
|
||||||
ogImage: "/images/page-meta/zh/links.png",
|
ogImage: "/images/page-meta/de/links.png",
|
||||||
},
|
},
|
||||||
about: {
|
about: {
|
||||||
title: "关于我",
|
title: "关于我",
|
||||||
description: "小孙同学的自我介绍",
|
description: "小孙同学的自我介绍",
|
||||||
ogImage: "/images/page-meta/zh/about.png",
|
ogImage: "/images/page-meta/de/about.png",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const en = {
|
export const en = {
|
||||||
...common,
|
...common,
|
||||||
siteName: "Guoqi Sun",
|
siteName: "Lio",
|
||||||
meta: {
|
meta: {
|
||||||
...common.meta,
|
...common.meta,
|
||||||
title: "Guoqi Sun",
|
title: "Lio",
|
||||||
slogan: "A Romantic Rationalist",
|
slogan: "fangmarks",
|
||||||
description: "Reading, Photography, Programming, Traveling",
|
description: "digital sorcerer and pixel wizard",
|
||||||
},
|
},
|
||||||
navigation: {
|
navigation: {
|
||||||
...common.navigation,
|
...common.navigation,
|
||||||
custom: [
|
custom: [
|
||||||
{
|
// {
|
||||||
label: "CamLife",
|
// label: "CamLife",
|
||||||
link: "https://camlife.cn",
|
// link: "https://camlife.cn",
|
||||||
},
|
// },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
pageMeta: {
|
pageMeta: {
|
||||||
archive: {
|
archive: {
|
||||||
title: "All Posts",
|
title: "All Posts",
|
||||||
description: "Here are Guoqi Sun's all posts",
|
description: "All of Lio's posts",
|
||||||
ogImage: "/images/page-meta/en/archive.png",
|
ogImage: "/images/page-meta/en/archive.png",
|
||||||
},
|
},
|
||||||
links: {
|
|
||||||
title: "My Friends",
|
|
||||||
description: "Here are Guoqi Sun's friends",
|
|
||||||
ogImage: "/images/page-meta/en/links.png",
|
|
||||||
},
|
|
||||||
about: {
|
about: {
|
||||||
title: "About Me",
|
title: "About",
|
||||||
description: "Here is Guoqi Sun's self-introduction",
|
description: "About Lio",
|
||||||
ogImage: "/images/page-meta/en/about.png",
|
ogImage: "/images/page-meta/en/about.png",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<div class="flex flex-col gap-2">
|
|
||||||
<p>
|
|
||||||
🖥️ 前端小学生|📸 摄影爱好者|🛸 旅行探索家|🚴 骑行蹭风选手|🍎
|
|
||||||
科技产品发烧友
|
|
||||||
</p>
|
|
||||||
<p>💬 路虽远行则将至,事虽难做则必成!</p>
|
|
||||||
</div>
|
|
||||||
|
|
@ -16,12 +16,12 @@ const enPostsCollection = defineCollection({
|
||||||
schema: postSchema,
|
schema: postSchema,
|
||||||
})
|
})
|
||||||
|
|
||||||
const zhPostsCollection = defineCollection({
|
const dePostsCollection = defineCollection({
|
||||||
loader: glob({ pattern: "**/*.{md,mdx}", base: "src/content/posts/zh" }),
|
loader: glob({ pattern: "**/*.{md,mdx}", base: "src/content/posts/de" }),
|
||||||
schema: postSchema,
|
schema: postSchema,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const collections = {
|
export const collections = {
|
||||||
enPosts: enPostsCollection,
|
enPosts: enPostsCollection,
|
||||||
zhPosts: zhPostsCollection,
|
dePosts: dePostsCollection,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
src/content/posts/de/post-1.md
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
title: "My First Blog Post"
|
||||||
|
pubDate: 2020-07-01
|
||||||
|
description: "This is the first post of my new Astro blog."
|
||||||
|
ogImage: "https://sunguoqi.com/me.png"
|
||||||
|
author: "Astro Learner"
|
||||||
|
image:
|
||||||
|
url: "https://docs.astro.build/assets/rose.webp"
|
||||||
|
alt: "The Astro logo on a dark background with a pink glow."
|
||||||
|
tags: ["astro", "blogging", "learning-in-public"]
|
||||||
|
---
|
||||||
|
|
||||||
|
Welcome to my _new blog_ about learning Astro! Here, I will share my learning journey as I build a new website.
|
||||||
|
|
||||||
|
## What I've accomplished
|
||||||
|
|
||||||
|
1. **Installing Astro**: First, I created a new Astro project and set up my online accounts.
|
||||||
|
|
||||||
|
2. **Making Pages**: I then learned how to make pages by creating new `.astro` files and placing them in the `src/pages/` folder.
|
||||||
|
|
||||||
|
3. **Making Blog Posts**: This is my first blog post! I now have Astro pages and Markdown posts!
|
||||||
|
|
||||||
|
## What's next
|
||||||
|
|
||||||
|
I will finish the Astro tutorial, and then keep adding more posts. Watch this space for more to come.
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
title: My Second Blog Post
|
|
||||||
author: Astro Learner
|
|
||||||
description: "After learning some Astro, I couldn't stop!"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/arc.webp"
|
|
||||||
alt: "The Astro logo on a dark background with a purple gradient arc."
|
|
||||||
pubDate: 2020-07-08
|
|
||||||
tags: ["astro", "blogging", "learning-in-public", "successes"]
|
|
||||||
---
|
|
||||||
|
|
||||||
After a successful first week learning Astro, I decided to try some more. I wrote and imported a small component from memory!
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
title: My Third Blog Post
|
|
||||||
author: Astro Learner
|
|
||||||
description: "I had some challenges, but asking in the community really helped!"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/rays.webp"
|
|
||||||
alt: "The Astro logo on a dark background with rainbow rays."
|
|
||||||
pubDate: 2021-07-15
|
|
||||||
tags: ["astro", "learning-in-public", "setbacks", "community"]
|
|
||||||
---
|
|
||||||
|
|
||||||
It wasn't always smooth sailing, but I'm enjoying building with Astro. And, the [Discord community](https://astro.build/chat) is really friendly and helpful!
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
title: "Building a Personal Blog with Astro"
|
|
||||||
author: Astro Learner
|
|
||||||
description: "Sharing my experience and insights on building a personal blog with Astro"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/full-logo-light.png"
|
|
||||||
alt: "Astro logo with full text"
|
|
||||||
pubDate: 2022-07-22
|
|
||||||
tags: ["astro", "blogging", "web-development", "tech-sharing"]
|
|
||||||
---
|
|
||||||
|
|
||||||
Over the past few weeks, I've been building my personal blog using Astro. Astro is a modern static site generator that offers excellent performance and a great development experience.
|
|
||||||
|
|
||||||
## Why Astro?
|
|
||||||
|
|
||||||
1. **Lightning-fast page loads**: Astro uses innovative partial hydration techniques
|
|
||||||
2. **Great developer experience**: Supports components from React, Vue, Svelte, and more
|
|
||||||
3. **Powerful Markdown support**: Makes writing content a breeze
|
|
||||||
|
|
||||||
## Learnings from the Development Process
|
|
||||||
|
|
||||||
Through this project, I've not only learned how to use Astro but also gained a deeper understanding of many modern frontend development concepts. I plan to continue improving this blog and adding more features.
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
title: "Customizing Your Astro Blog Theme"
|
|
||||||
author: Astro Learner
|
|
||||||
description: "Learn how to customize your Astro blog theme with Tailwind CSS"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/rays.webp"
|
|
||||||
alt: "Astro rays on a dark background"
|
|
||||||
pubDate: 2022-07-29
|
|
||||||
tags: ["astro", "css", "tailwind", "design"]
|
|
||||||
---
|
|
||||||
|
|
||||||
Today I'll share how I customized my Astro blog theme using Tailwind CSS. The combination of Astro and Tailwind makes styling incredibly efficient.
|
|
||||||
|
|
||||||
## Key Customizations
|
|
||||||
|
|
||||||
1. **Color Scheme**: Created a custom dark/light mode theme
|
|
||||||
2. **Typography**: Set up a consistent type scale
|
|
||||||
3. **Layout**: Implemented responsive design patterns
|
|
||||||
4. **Components**: Styled reusable UI components
|
|
||||||
|
|
||||||
## Tips for Theme Development
|
|
||||||
|
|
||||||
- Start with a clear design system
|
|
||||||
- Use Tailwind's configuration file for custom values
|
|
||||||
- Leverage CSS variables for dynamic theming
|
|
||||||
- Test across different devices and screen sizes
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
title: "Adding Dynamic Features to Static Astro Sites"
|
|
||||||
author: Astro Learner
|
|
||||||
description: "Exploring ways to add dynamic features to Astro's static pages"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/arc.webp"
|
|
||||||
alt: "Astro arc on dark background"
|
|
||||||
pubDate: 2023-08-05
|
|
||||||
tags: ["astro", "javascript", "dynamic-content", "web-development"]
|
|
||||||
---
|
|
||||||
|
|
||||||
While Astro excels at static site generation, sometimes we need dynamic features. Here's how to add interactivity without sacrificing performance.
|
|
||||||
|
|
||||||
## Dynamic Features Added
|
|
||||||
|
|
||||||
1. **Search Functionality**: Implemented client-side search
|
|
||||||
2. **Comment System**: Integrated with a third-party service
|
|
||||||
3. **Like Button**: Added interactive reactions
|
|
||||||
4. **View Counter**: Track page views
|
|
||||||
|
|
||||||
## Implementation Details
|
|
||||||
|
|
||||||
The key is using Astro's partial hydration to only load JavaScript where needed. This keeps the site fast while adding necessary dynamic features.
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
title: "Adding Internationalization to Astro"
|
|
||||||
author: Astro Learner
|
|
||||||
description: "A guide to implementing i18n in your Astro website"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/full-logo-light.png"
|
|
||||||
alt: "Astro logo"
|
|
||||||
pubDate: 2024-08-19
|
|
||||||
tags: ["astro", "i18n", "localization", "web-development"]
|
|
||||||
---
|
|
||||||
|
|
||||||
Making your website accessible to a global audience is important. Here's how to implement internationalization in Astro.
|
|
||||||
|
|
||||||
## Implementation Steps
|
|
||||||
|
|
||||||
1. **Setup**: Installing necessary i18n packages
|
|
||||||
2. **Content Structure**: Organizing content for multiple languages
|
|
||||||
3. **Language Switching**: Adding a language toggle
|
|
||||||
4. **URL Management**: Handling language-specific routes
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
- Keep translations in separate files
|
|
||||||
- Use ISO language codes
|
|
||||||
- Implement fallback languages
|
|
||||||
- Consider right-to-left languages
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
title: "Deploying Your Astro Site"
|
|
||||||
author: Astro Learner
|
|
||||||
description: "A comprehensive guide to deploying your Astro site to various platforms"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/arc.webp"
|
|
||||||
alt: "Astro deployment illustration"
|
|
||||||
pubDate: 2024-08-26
|
|
||||||
tags: ["astro", "deployment", "hosting", "CI CD"]
|
|
||||||
---
|
|
||||||
|
|
||||||
Ready to share your Astro site with the world? Let's explore different deployment options and best practices.
|
|
||||||
|
|
||||||
## Deployment Platforms
|
|
||||||
|
|
||||||
1. **Netlify**: Perfect for static sites
|
|
||||||
2. **Vercel**: Great for serverless functions
|
|
||||||
3. **GitHub Pages**: Ideal for project sites
|
|
||||||
4. **Self-hosted**: Maximum control
|
|
||||||
|
|
||||||
## Deployment Process
|
|
||||||
|
|
||||||
We'll walk through the setup process for each platform, including configuration files, environment variables, and continuous deployment workflows.
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
---
|
|
||||||
title: "我的第一篇博客文章"
|
|
||||||
pubDate: 2020-07-01
|
|
||||||
updatedDate: 2020-07-01
|
|
||||||
description: "这是我 Astro 博客的第一篇文章。"
|
|
||||||
author: "Astro 学习者"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/rose.webp"
|
|
||||||
alt: "在黑色背景上带有粉色光晕的 Astro 标志。"
|
|
||||||
tags: ["astro", "博客", "公开学习"]
|
|
||||||
---
|
|
||||||
|
|
||||||
export const title = "mdx"
|
|
||||||
|
|
||||||
## {title}
|
|
||||||
|
|
||||||
欢迎来到我学习关于 Astro 的新博客!在这里,我将分享我建立新网站的学习历程。
|
|
||||||
|
|
||||||
## 我做了什么
|
|
||||||
|
|
||||||
1. **安装 Astro**:首先,我创建了一个新的 Astro 项目并设置好了我的在线账号。
|
|
||||||
|
|
||||||
2. **制作页面**:然后我学习了如何通过创建新的 `.astro` 文件并将它们保存在 `src/pages/` 文件夹里来制作页面。
|
|
||||||
|
|
||||||
3. **发表博客文章**:这是我的第一篇博客文章!我现在有用 Astro 编写的页面和用 Markdown 写的文章了!
|
|
||||||
|
|
||||||
## 下一步计划
|
|
||||||
|
|
||||||
我将完成 Astro 教程,然后继续编写更多内容。关注我以获取更多信息。
|
|
||||||
|
|
||||||
```python
|
|
||||||
print("Hello, World!")
|
|
||||||
```
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
title: 我的第二篇博客文章
|
|
||||||
author: Astro 学习者
|
|
||||||
description: "在学习了一些 Astro 之后,我无法停止!"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/arc.webp"
|
|
||||||
alt: "在深色背景上带有紫色渐变弧形的 Astro 标志。"
|
|
||||||
pubDate: 2020-07-08
|
|
||||||
tags: ["astro", "博客", "公开学习", "成功"]
|
|
||||||
---
|
|
||||||
|
|
||||||
在成功的第一周学习 Astro 之后,我决定再试试。我从记忆中编写并导入了一个小组件!
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
title: 我的第三篇博客文章
|
|
||||||
author: Astro 学习者
|
|
||||||
description: "我遇到了一些挑战,但在社区中提问真的帮助了我!"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/rays.webp"
|
|
||||||
alt: "在黑色背景上带有彩虹光线的 Astro 标志。"
|
|
||||||
pubDate: 2021-07-15
|
|
||||||
tags: ["astro", "公开学习", "挫折", "社区"]
|
|
||||||
---
|
|
||||||
|
|
||||||
事情并不总是一帆风顺,但我很享受使用 Astro 构建的过程。而且,[Discord 社区](https://astro.build/chat)真的很友好和乐于助人!
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
title: "使用 Astro 构建个人博客"
|
|
||||||
author: Astro 学习者
|
|
||||||
description: "分享我使用 Astro 构建个人博客的经验和见解"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/full-logo-light.png"
|
|
||||||
alt: "带有完整文本的 Astro 徽标"
|
|
||||||
pubDate: 2022-07-22
|
|
||||||
tags: ["astro", "博客", "网页开发", "技术分享"]
|
|
||||||
---
|
|
||||||
|
|
||||||
在过去的几周里,我一直在使用 Astro 构建我的个人博客。Astro 是一个现代静态网站生成器,提供出色的性能和良好的开发体验。
|
|
||||||
|
|
||||||
## 为什么选择 Astro?
|
|
||||||
|
|
||||||
1. **闪电般快速的页面加载**:Astro 使用创新的部分水合技术
|
|
||||||
2. **出色的开发者体验**:支持来自 React、Vue、Svelte 等的组件
|
|
||||||
3. **强大的 Markdown 支持**:让写作内容变得轻而易举
|
|
||||||
|
|
||||||
## 开发过程中的学习
|
|
||||||
|
|
||||||
通过这个项目,我不仅学会了如何使用 Astro,还对许多现代前端开发概念有了更深入的理解。我计划继续改进这个博客并添加更多功能。
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
title: "自定义你的 Astro 博客主题"
|
|
||||||
author: Astro 学习者
|
|
||||||
description: "学习如何使用 Tailwind CSS 自定义你的 Astro 博客主题"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/rays.webp"
|
|
||||||
alt: "黑色背景上的 Astro 光线"
|
|
||||||
pubDate: 2022-07-29
|
|
||||||
tags: ["astro", "css", "tailwind", "设计"]
|
|
||||||
---
|
|
||||||
|
|
||||||
今天我将分享如何使用 Tailwind CSS 自定义我的 Astro 博客主题。Astro 和 Tailwind 的结合使得样式设计变得非常高效。
|
|
||||||
|
|
||||||
## 关键自定义
|
|
||||||
|
|
||||||
1. **颜色方案**: 创建了一个自定义的暗/亮模式主题
|
|
||||||
2. **排版**: 设置了一致的字体比例
|
|
||||||
3. **布局**: 实现了响应式设计模式
|
|
||||||
4. **组件**: 样式化可重用的 UI 组件
|
|
||||||
|
|
||||||
## 主题开发提示
|
|
||||||
|
|
||||||
- 从清晰的设计系统开始
|
|
||||||
- 使用 Tailwind 的配置文件进行自定义值
|
|
||||||
- 利用 CSS 变量进行动态主题
|
|
||||||
- 在不同设备和屏幕尺寸上进行测试
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
title: "为静态 Astro 网站添加动态功能"
|
|
||||||
author: Astro Learner
|
|
||||||
description: "探索为 Astro 的静态页面添加动态功能的方法"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/arc.webp"
|
|
||||||
alt: "黑色背景上的 Astro 弧形图"
|
|
||||||
pubDate: 2023-08-05
|
|
||||||
tags: ["astro", "javascript", "动态内容", "网页开发"]
|
|
||||||
---
|
|
||||||
|
|
||||||
虽然 Astro 在静态网站生成方面表现出色,但有时我们需要动态功能。以下是如何在不牺牲性能的情况下添加交互性。
|
|
||||||
|
|
||||||
## 添加的动态功能
|
|
||||||
|
|
||||||
1. **搜索功能**:实现了客户端搜索
|
|
||||||
2. **评论系统**:与第三方服务集成
|
|
||||||
3. **点赞按钮**:添加了互动反应
|
|
||||||
4. **浏览计数器**:跟踪页面浏览量
|
|
||||||
|
|
||||||
## 实施细节
|
|
||||||
|
|
||||||
关键是使用 Astro 的部分水合,只在需要的地方加载 JavaScript。这使得网站保持快速,同时添加必要的动态功能。
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
title: "为 Astro 添加国际化"
|
|
||||||
author: Astro Learner
|
|
||||||
description: "在您的 Astro 网站中实现 i18n 的指南"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/full-logo-light.png"
|
|
||||||
alt: "Astro 标志"
|
|
||||||
pubDate: 2024-08-19
|
|
||||||
tags: ["astro", "i18n", "本地化", "网页开发"]
|
|
||||||
---
|
|
||||||
|
|
||||||
让您的网站能够接触到全球受众是很重要的。以下是如何在 Astro 中实现国际化的方法。
|
|
||||||
|
|
||||||
## 实施步骤
|
|
||||||
|
|
||||||
1. **设置**:安装必要的 i18n 包
|
|
||||||
2. **内容结构**:为多种语言组织内容
|
|
||||||
3. **语言切换**:添加语言切换功能
|
|
||||||
4. **URL 管理**:处理特定语言的路由
|
|
||||||
|
|
||||||
## 最佳实践
|
|
||||||
|
|
||||||
- 将翻译保存在单独的文件中
|
|
||||||
- 使用 ISO 语言代码
|
|
||||||
- 实现后备语言
|
|
||||||
- 考虑从右到左的语言
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
title: "部署您的 Astro 网站"
|
|
||||||
author: Astro 学习者
|
|
||||||
description: "全面指南,帮助您将 Astro 网站部署到各种平台"
|
|
||||||
image:
|
|
||||||
url: "https://docs.astro.build/assets/arc.webp"
|
|
||||||
alt: "Astro 部署插图"
|
|
||||||
pubDate: 2024-08-26
|
|
||||||
tags: ["astro", "i18n", "本地化", "网页开发"]
|
|
||||||
---
|
|
||||||
|
|
||||||
准备好与世界分享您的 Astro 网站了吗?让我们探索不同的部署选项和最佳实践。
|
|
||||||
|
|
||||||
## 部署平台
|
|
||||||
|
|
||||||
1. **Netlify**: 适合静态网站
|
|
||||||
2. **Vercel**: 适合无服务器函数
|
|
||||||
3. **GitHub Pages**: 理想的项目网站
|
|
||||||
4. **自托管**: 最大的控制权
|
|
||||||
|
|
||||||
## 部署过程
|
|
||||||
|
|
||||||
我们将逐步介绍每个平台的设置过程,包括配置文件、环境变量和持续部署工作流。
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
export const languages = {
|
export const languages = {
|
||||||
en: "English",
|
en: "English",
|
||||||
zh: "简体中文",
|
de: "Deutsch",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultLang = "en"
|
export const defaultLang = "en"
|
||||||
|
|
||||||
export const langs = ["en", "zh"]
|
export const langs = ["en", "de"]
|
||||||
|
|
||||||
export const ui = {
|
export const ui = {
|
||||||
en: {
|
en: {
|
||||||
|
|
@ -19,15 +19,15 @@ export const ui = {
|
||||||
"tag.title": "Tag:",
|
"tag.title": "Tag:",
|
||||||
"tag.no_posts": "No posts found for tag",
|
"tag.no_posts": "No posts found for tag",
|
||||||
},
|
},
|
||||||
zh: {
|
de: {
|
||||||
"nav.home": "首页",
|
"nav.home": "Start",
|
||||||
"nav.about": "关于",
|
"nav.about": "Über mich",
|
||||||
"nav.archive": "归档",
|
"nav.archive": "Archiv",
|
||||||
"nav.links": "友链",
|
"nav.links": "Links",
|
||||||
"links.title": "朋友们",
|
"links.title": "Freunde",
|
||||||
"blog.latest": "近期文章",
|
"blog.latest": "Letzte Posts",
|
||||||
"archive.title": "所有文章",
|
"archive.title": "Alle Posts",
|
||||||
"tag.title": "标签:",
|
"tag.title": "Tag:",
|
||||||
"tag.no_posts": "没有找到标签为的文章",
|
"tag.no_posts": "Für diesen Tag wurden keine Posts gefunden",
|
||||||
},
|
},
|
||||||
} as const
|
} as const
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
---
|
---
|
||||||
import "~/styles/globals.css"
|
|
||||||
import { NoiseBackground } from "~/components/react/noise-background"
|
import { NoiseBackground } from "~/components/react/noise-background"
|
||||||
import { getLangFromUrl } from "~/i18n/utils"
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
import { GoogleAnalytics } from "astro-google-analytics"
|
import { GoogleAnalytics } from "astro-google-analytics"
|
||||||
import { en, zh } from "~/config"
|
import { en, de } from "~/config"
|
||||||
import { ClientRouter } from "astro:transitions"
|
import { ClientRouter } from "astro:transitions"
|
||||||
|
|
||||||
|
import "~/styles/tailwind.css"
|
||||||
|
import "~/styles/view-transition.css"
|
||||||
|
|
||||||
const lang = getLangFromUrl(Astro.url)
|
const lang = getLangFromUrl(Astro.url)
|
||||||
|
|
||||||
const { title, description, ogImage } = Astro.props
|
const { title, description, ogImage } = Astro.props
|
||||||
|
|
@ -13,7 +15,7 @@ const { title, description, ogImage } = Astro.props
|
||||||
const ogImageURL = new URL(ogImage, Astro.site).href
|
const ogImageURL = new URL(ogImage, Astro.site).href
|
||||||
const permalink = new URL(Astro.url.pathname, Astro.site).href
|
const permalink = new URL(Astro.url.pathname, Astro.site).href
|
||||||
|
|
||||||
const config = lang === "zh" ? zh : en
|
const config = lang === "de" ? de : en
|
||||||
---
|
---
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
import Comments from "~/components/astro/comments.astro"
|
// import Comments from "~/components/astro/comments.astro"
|
||||||
import Header from "~/components/astro/header.astro"
|
import Header from "~/components/astro/header.astro"
|
||||||
import Navigation from "~/components/astro/nav.astro"
|
import Navigation from "~/components/astro/nav.astro"
|
||||||
import BaseLayout from "~/layouts/base.astro"
|
import BaseLayout from "~/layouts/base.astro"
|
||||||
|
|
@ -19,8 +19,8 @@ const openGraphImage = !ogImage ? `/og/${filename}.png` : ogImage
|
||||||
<Header />
|
<Header />
|
||||||
<Navigation />
|
<Navigation />
|
||||||
<slot />
|
<slot />
|
||||||
<div class="mt-20">
|
<!-- <div class="mt-20">
|
||||||
{needComment && <Comments />}
|
{needComment && <Comments />}
|
||||||
</div>
|
</div> -->
|
||||||
</main>
|
</main>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,8 @@ import MainLayout from "~/layouts/main.astro"
|
||||||
<MainLayout title="404" description="Error 404 page not found." noindex={true}>
|
<MainLayout title="404" description="Error 404 page not found." noindex={true}>
|
||||||
<section class="flex min-h-[60vh] items-center justify-center">
|
<section class="flex min-h-[60vh] items-center justify-center">
|
||||||
<div class="mx-auto max-w-xl px-4 text-center">
|
<div class="mx-auto max-w-xl px-4 text-center">
|
||||||
<h1 class="text-9xl font-bold text-gray-900 dark:text-gray-100">404</h1>
|
<img class="block" src="/images/page-meta/general/404.png" />
|
||||||
|
|
||||||
<div class="mt-4 text-gray-600 dark:text-gray-400">
|
<div class="mt-4 text-gray-600 dark:text-gray-400">
|
||||||
<div class="h2 mb-4">Oops! Page not found</div>
|
|
||||||
<p class="text-lg">
|
<p class="text-lg">
|
||||||
The page you're looking for doesn't exist or has been moved.
|
The page you're looking for doesn't exist or has been moved.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
import { en, zh } from "~/config"
|
import { de, en } from "~/config"
|
||||||
|
import AboutContentDe from "~/config/de/about.mdx"
|
||||||
import AboutContentEn from "~/config/en/about.mdx"
|
import AboutContentEn from "~/config/en/about.mdx"
|
||||||
import AboutContentZh from "~/config/zh/about.mdx"
|
|
||||||
import { getLangFromUrl } from "~/i18n/utils"
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
import MainLayout from "~/layouts/main.astro"
|
import MainLayout from "~/layouts/main.astro"
|
||||||
import { getLanguagePaths } from "~/utils/langs"
|
import { getLanguagePaths } from "~/utils/langs"
|
||||||
|
|
@ -11,8 +11,8 @@ export function getStaticPaths() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const lang = getLangFromUrl(Astro.url)
|
const lang = getLangFromUrl(Astro.url)
|
||||||
const pageMeta = lang === "zh" ? zh.pageMeta : en.pageMeta
|
const pageMeta = lang === "de" ? de.pageMeta : en.pageMeta
|
||||||
const AboutContent = lang === "zh" ? AboutContentZh : AboutContentEn
|
const AboutContent = lang === "de" ? AboutContentDe : AboutContentEn
|
||||||
---
|
---
|
||||||
|
|
||||||
<MainLayout
|
<MainLayout
|
||||||
|
|
@ -21,7 +21,7 @@ const AboutContent = lang === "zh" ? AboutContentZh : AboutContentEn
|
||||||
ogImage={pageMeta.about.ogImage}
|
ogImage={pageMeta.about.ogImage}
|
||||||
needComment={true}
|
needComment={true}
|
||||||
>
|
>
|
||||||
<div class="prose max-w-3xl dark:prose-invert">
|
<div class="prose dark:prose-invert max-w-3xl">
|
||||||
<AboutContent />
|
<AboutContent />
|
||||||
</div>
|
</div>
|
||||||
</MainLayout>
|
</MainLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
---
|
---
|
||||||
import PostList from "~/components/astro/post-list.astro"
|
import PostList from "~/components/astro/post-list.astro"
|
||||||
import { en, zh } from "~/config"
|
import { de, en } from "~/config"
|
||||||
import { getLangFromUrl } from "~/i18n/utils"
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
import MainLayout from "~/layouts/main.astro"
|
import MainLayout from "~/layouts/main.astro"
|
||||||
import { getPostsByLocale } from "~/utils"
|
import { getPostsByLocale } from "~/utils"
|
||||||
import { getLanguagePaths } from "~/utils/langs"
|
import { getLanguagePaths } from "~/utils/langs"
|
||||||
|
|
||||||
const lang = getLangFromUrl(Astro.url)
|
const lang = getLangFromUrl(Astro.url)
|
||||||
const pageMeta = lang === "zh" ? zh.pageMeta : en.pageMeta
|
const pageMeta = lang === "de" ? de.pageMeta : en.pageMeta
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export function getStaticPaths() {
|
||||||
return getLanguagePaths()
|
return getLanguagePaths()
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
---
|
|
||||||
import LinkCard from "~/components/astro/link-card.astro"
|
|
||||||
import { en, zh } from "~/config"
|
|
||||||
import LinksContentEn from "~/config/en/links.mdx"
|
|
||||||
import { links } from "~/config/links"
|
|
||||||
import LinksContentZh from "~/config/zh/links.mdx"
|
|
||||||
import { getLangFromUrl, useTranslations } from "~/i18n/utils"
|
|
||||||
import MainLayout from "~/layouts/main.astro"
|
|
||||||
import { getLanguagePaths } from "~/utils/langs"
|
|
||||||
|
|
||||||
export function getStaticPaths() {
|
|
||||||
return getLanguagePaths()
|
|
||||||
}
|
|
||||||
|
|
||||||
const lang = getLangFromUrl(Astro.url)
|
|
||||||
const t = useTranslations(lang)
|
|
||||||
const LinksContent = lang === "zh" ? LinksContentZh : LinksContentEn
|
|
||||||
const pageMeta = lang === "zh" ? zh.pageMeta : en.pageMeta
|
|
||||||
---
|
|
||||||
|
|
||||||
<MainLayout
|
|
||||||
title={pageMeta.links.title}
|
|
||||||
description={pageMeta.links.description}
|
|
||||||
ogImage={pageMeta.links.ogImage}
|
|
||||||
needComment={true}
|
|
||||||
>
|
|
||||||
<h3 class="my-10 text-center text-xl font-bold">{t("links.title")}</h3>
|
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
||||||
{links.map((link) => <LinkCard {...link} />)}
|
|
||||||
</div>
|
|
||||||
<div class="prose max-w-3xl dark:prose-invert">
|
|
||||||
<LinksContent />
|
|
||||||
</div>
|
|
||||||
</MainLayout>
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
import { render } from "astro:content"
|
import { render } from "astro:content"
|
||||||
import Comments from "~/components/astro/comments.astro"
|
|
||||||
import { langs } from "~/i18n/ui"
|
import { langs } from "~/i18n/ui"
|
||||||
import { getLangFromUrl } from "~/i18n/utils"
|
import { getLangFromUrl } from "~/i18n/utils"
|
||||||
import MainLayout from "~/layouts/main.astro"
|
import MainLayout from "~/layouts/main.astro"
|
||||||
|
|
@ -31,7 +30,7 @@ const { Content } = await render(post)
|
||||||
---
|
---
|
||||||
|
|
||||||
<MainLayout {...post.data}>
|
<MainLayout {...post.data}>
|
||||||
<article class="prose w-full max-w-3xl overflow-hidden dark:prose-invert">
|
<article class="prose dark:prose-invert w-full max-w-3xl overflow-hidden">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<h2 class="!my-0 text-3xl font-semibold">{post.data.title}</h2>
|
<h2 class="!my-0 text-3xl font-semibold">{post.data.title}</h2>
|
||||||
<div class="my-3 text-gray-500 dark:text-white/80">
|
<div class="my-3 text-gray-500 dark:text-white/80">
|
||||||
|
|
@ -53,8 +52,4 @@ const { Content } = await render(post)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<div class="my-10">
|
|
||||||
<Comments />
|
|
||||||
</div>
|
|
||||||
</MainLayout>
|
</MainLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import rss from "@astrojs/rss"
|
import rss from "@astrojs/rss"
|
||||||
import { en, zh } from "~/config"
|
import { de, en } from "~/config"
|
||||||
import { getPostsByLocale } from "~/utils"
|
import { getPostsByLocale } from "~/utils"
|
||||||
import { getLanguagePaths } from "~/utils/langs"
|
import { getLanguagePaths } from "~/utils/langs"
|
||||||
|
|
||||||
|
|
@ -10,8 +10,8 @@ export function getStaticPaths() {
|
||||||
export async function GET(request: { url: URL }) {
|
export async function GET(request: { url: URL }) {
|
||||||
const isEn = request.url.pathname.includes("en")
|
const isEn = request.url.pathname.includes("en")
|
||||||
|
|
||||||
const lang = isEn ? "en" : "zh"
|
const lang = isEn ? "en" : "de"
|
||||||
const config = isEn ? en : zh
|
const config = isEn ? en : de
|
||||||
|
|
||||||
const posts = await getPostsByLocale(lang)
|
const posts = await getPostsByLocale(lang)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import rss from "@astrojs/rss"
|
import rss from "@astrojs/rss"
|
||||||
import { defaultLanguage, en, zh } from "~/config"
|
import { de, defaultLanguage, en } from "~/config"
|
||||||
import { getPostsByLocale } from "~/utils"
|
import { getPostsByLocale } from "~/utils"
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const posts = await getPostsByLocale(defaultLanguage)
|
const posts = await getPostsByLocale(defaultLanguage)
|
||||||
const config = defaultLanguage === "en" ? en : zh
|
const config = defaultLanguage === "en" ? en : de
|
||||||
|
|
||||||
return rss({
|
return rss({
|
||||||
title: config.meta.title,
|
title: config.meta.title,
|
||||||
|
|
|
||||||
3
src/styles/tailwind.css
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
@import "tailwindcss";
|
||||||
|
@plugin "@tailwindcss/typography";
|
||||||
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
@import "tailwindcss";
|
|
||||||
@custom-variant dark (&:where(.dark, .dark *));
|
|
||||||
|
|
||||||
/* Theme toggle effect */
|
/* Theme toggle effect */
|
||||||
/* https://theme-toggle.rdsx.dev/ */
|
/* https://theme-toggle.rdsx.dev/ */
|
||||||
/* https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API */
|
/* https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API */
|
||||||
|
|
@ -22,7 +22,7 @@ export const getPostsByLocale = async (locale: string) => {
|
||||||
const posts =
|
const posts =
|
||||||
locale === "en"
|
locale === "en"
|
||||||
? await getCollection("enPosts")
|
? await getCollection("enPosts")
|
||||||
: await getCollection("zhPosts")
|
: await getCollection("dePosts")
|
||||||
return posts.sort(
|
return posts.sort(
|
||||||
(a: any, b: any) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
|
(a: any, b: any) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||