diff --git a/package.json b/package.json index 52ab0ec..b77c3ff 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@astrojs/svelte": "^5.0.3", "@citation-js/plugin-bibtex": "^0.7.8", "@js-temporal/polyfill": "^0.4.4", - "astro": "^4.3.0", + "astro": "^4.3.2", "astro-pagefind": "^1.4.0", "chart.js": "^4.4.1", "citation-js": "^0.7.8", @@ -33,7 +33,7 @@ "remark-parse": "^11.0.0", "remark-rehype": "^11.1.0", "reveal.js": "^5.0.4", - "svelte": "5.0.0-next.44", + "svelte": "5.0.0-next.45", "unified": "^11.0.4", "unist-util-visit": "^5.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6c88e43..e8e896a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,10 +7,10 @@ settings: dependencies: '@astrojs/mdx': specifier: ^2.1.1 - version: 2.1.1(astro@4.3.0) + version: 2.1.1(astro@4.3.2) '@astrojs/svelte': specifier: ^5.0.3 - version: 5.0.3(astro@4.3.0)(svelte@5.0.0-next.44)(typescript@5.3.3)(vite@5.0.12) + version: 5.0.3(astro@4.3.2)(svelte@5.0.0-next.45)(typescript@5.3.3)(vite@5.0.12) '@citation-js/plugin-bibtex': specifier: ^0.7.8 version: 0.7.8(@citation-js/core@0.7.6) @@ -18,11 +18,11 @@ dependencies: specifier: ^0.4.4 version: 0.4.4 astro: - specifier: ^4.3.0 - version: 4.3.0(sass@1.70.0)(typescript@5.3.3) + specifier: ^4.3.2 + version: 4.3.2(sass@1.70.0)(typescript@5.3.3) astro-pagefind: specifier: ^1.4.0 - version: 1.4.0(astro@4.3.0) + version: 1.4.0(astro@4.3.2) chart.js: specifier: ^4.4.1 version: 4.4.1 @@ -72,8 +72,8 @@ dependencies: specifier: ^5.0.4 version: 5.0.4 svelte: - specifier: 5.0.0-next.44 - version: 5.0.0-next.44 + specifier: 5.0.0-next.45 + version: 5.0.0-next.45 unified: specifier: ^11.0.4 version: 11.0.4 @@ -143,7 +143,7 @@ packages: - supports-color dev: false - /@astrojs/mdx@2.1.1(astro@4.3.0): + /@astrojs/mdx@2.1.1(astro@4.3.2): resolution: {integrity: sha512-AgGFdE7HOGmoFooGvMSatkA9FiSKwyVW7ImHot/bXJ6uAbFfu6iG2ht18Cf1pT22Hda/6iSCGWusFvBv0/EnKQ==} engines: {node: '>=18.14.1'} peerDependencies: @@ -152,7 +152,7 @@ packages: '@astrojs/markdown-remark': 4.2.1 '@mdx-js/mdx': 3.0.0 acorn: 8.11.3 - astro: 4.3.0(sass@1.70.0)(typescript@5.3.3) + astro: 4.3.2(sass@1.70.0)(typescript@5.3.3) es-module-lexer: 1.4.1 estree-util-visit: 2.0.0 github-slugger: 2.0.0 @@ -176,17 +176,17 @@ packages: prismjs: 1.29.0 dev: false - /@astrojs/svelte@5.0.3(astro@4.3.0)(svelte@5.0.0-next.44)(typescript@5.3.3)(vite@5.0.12): + /@astrojs/svelte@5.0.3(astro@4.3.2)(svelte@5.0.0-next.45)(typescript@5.3.3)(vite@5.0.12): resolution: {integrity: sha512-6TUBRUxmsEczKPBT6oDUAfvzuFCmITuhZfKPT5ZtOOyj9XOVnEnj/Iobd3ajKUbpWNYX7qZVAd1KMkmJc1Nhsg==} engines: {node: '>=18.14.1'} peerDependencies: astro: ^4.0.0 svelte: ^4.0.0 || ^5.0.0-next.1 dependencies: - '@sveltejs/vite-plugin-svelte': 3.0.2(svelte@5.0.0-next.44)(vite@5.0.12) - astro: 4.3.0(sass@1.70.0)(typescript@5.3.3) - svelte: 5.0.0-next.44 - svelte2tsx: 0.6.27(svelte@5.0.0-next.44)(typescript@5.3.3) + '@sveltejs/vite-plugin-svelte': 3.0.2(svelte@5.0.0-next.45)(vite@5.0.12) + astro: 4.3.2(sass@1.70.0)(typescript@5.3.3) + svelte: 5.0.0-next.45 + svelte2tsx: 0.6.27(svelte@5.0.0-next.45)(typescript@5.3.3) transitivePeerDependencies: - supports-color - typescript @@ -1189,7 +1189,7 @@ packages: engines: {node: '>=10'} dev: false - /@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.0.2)(svelte@5.0.0-next.44)(vite@5.0.12): + /@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.0.2)(svelte@5.0.0-next.45)(vite@5.0.12): resolution: {integrity: sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==} engines: {node: ^18.0.0 || >=20} peerDependencies: @@ -1197,28 +1197,28 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 vite: ^5.0.0 dependencies: - '@sveltejs/vite-plugin-svelte': 3.0.2(svelte@5.0.0-next.44)(vite@5.0.12) + '@sveltejs/vite-plugin-svelte': 3.0.2(svelte@5.0.0-next.45)(vite@5.0.12) debug: 4.3.4 - svelte: 5.0.0-next.44 + svelte: 5.0.0-next.45 vite: 5.0.12(sass@1.70.0) transitivePeerDependencies: - supports-color dev: false - /@sveltejs/vite-plugin-svelte@3.0.2(svelte@5.0.0-next.44)(vite@5.0.12): + /@sveltejs/vite-plugin-svelte@3.0.2(svelte@5.0.0-next.45)(vite@5.0.12): resolution: {integrity: sha512-MpmF/cju2HqUls50WyTHQBZUV3ovV/Uk8k66AN2gwHogNAG8wnW8xtZDhzNBsFJJuvmq1qnzA5kE7YfMJNFv2Q==} engines: {node: ^18.0.0 || >=20} peerDependencies: svelte: ^4.0.0 || ^5.0.0-next.0 vite: ^5.0.0 dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.0.2)(svelte@5.0.0-next.44)(vite@5.0.12) + '@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.0.2)(svelte@5.0.0-next.45)(vite@5.0.12) debug: 4.3.4 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.6 - svelte: 5.0.0-next.44 - svelte-hmr: 0.15.3(svelte@5.0.0-next.44) + svelte: 5.0.0-next.45 + svelte-hmr: 0.15.3(svelte@5.0.0-next.45) vite: 5.0.12(sass@1.70.0) vitefu: 0.2.5(vite@5.0.12) transitivePeerDependencies: @@ -1423,19 +1423,19 @@ packages: hasBin: true dev: false - /astro-pagefind@1.4.0(astro@4.3.0): + /astro-pagefind@1.4.0(astro@4.3.2): resolution: {integrity: sha512-WMUlS0TTqIDqygplj/cxKU+l3oI+zB2qgYNMZed5R5nXuw8HhAKATog9zazuN05TOSWxI2Ap9+9WAYnnJ+4C7A==} peerDependencies: astro: ^2.0.4 || ^3.0.0 || ^4.0.0 dependencies: '@pagefind/default-ui': 1.0.4 - astro: 4.3.0(sass@1.70.0)(typescript@5.3.3) + astro: 4.3.2(sass@1.70.0)(typescript@5.3.3) pagefind: 1.0.4 sirv: 2.0.4 dev: false - /astro@4.3.0(sass@1.70.0)(typescript@5.3.3): - resolution: {integrity: sha512-DSn7q7KJ9lmA7B3faz6uaIIRTzJduKNYRAsgXDn+wH1Jso33PFOU3ZcI4knlMAqhFW3MX8WorB8Hg6kR+waQXg==} + /astro@4.3.2(sass@1.70.0)(typescript@5.3.3): + resolution: {integrity: sha512-SJotHzKG/I32ruYWItMRJjtmNQh14mVS7kahu3XfYyxvo6nx08PGJBTSPbqPrW1sjeQPHwcpVDFx3yMMK2kaxQ==} engines: {node: '>=18.14.1', npm: '>=6.14.0'} hasBin: true dependencies: @@ -1588,8 +1588,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001582 - electron-to-chromium: 1.4.653 + caniuse-lite: 1.0.30001583 + electron-to-chromium: 1.4.656 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.22.3) dev: false @@ -1613,8 +1613,8 @@ packages: engines: {node: '>=14.16'} dev: false - /caniuse-lite@1.0.30001582: - resolution: {integrity: sha512-vsJG3V5vgfduaQGVxL53uSX/HUzxyr2eA8xCo36OLal7sRcSZbibJtLeh0qja4sFOr/QQGt4opB4tOy+eOgAxg==} + /caniuse-lite@1.0.30001583: + resolution: {integrity: sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==} dev: false /ccount@2.0.1: @@ -1926,8 +1926,8 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: false - /electron-to-chromium@1.4.653: - resolution: {integrity: sha512-wA2A2LQCqnEwQAvwADQq3KpMpNwgAUBnRmrFgRzHnPhbQUFArTR32Ab46f4p0MovDLcg4uqd4nCsN2hTltslpA==} + /electron-to-chromium@1.4.656: + resolution: {integrity: sha512-9AQB5eFTHyR3Gvt2t/NwR0le2jBSUNwCnMbUCejFWHD+so4tH40/dRLgoE+jxlPeWS43XJewyvCv+I8LPMl49Q==} dev: false /emoji-regex@10.3.0: @@ -4240,8 +4240,8 @@ packages: - supports-color dev: false - /streamx@2.15.6: - resolution: {integrity: sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==} + /streamx@2.15.7: + resolution: {integrity: sha512-NPEKS5+yjyo597eafGbKW5ujh7Sm6lDLHZQd/lRSz6S0VarpADBJItqfB4PnwpS+472oob1GX5cCY9vzfJpHUA==} requiresBuild: true dependencies: fast-fifo: 1.3.2 @@ -4358,16 +4358,16 @@ packages: engines: {node: '>= 0.4'} dev: false - /svelte-hmr@0.15.3(svelte@5.0.0-next.44): + /svelte-hmr@0.15.3(svelte@5.0.0-next.45): resolution: {integrity: sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==} engines: {node: ^12.20 || ^14.13.1 || >= 16} peerDependencies: svelte: ^3.19.0 || ^4.0.0 dependencies: - svelte: 5.0.0-next.44 + svelte: 5.0.0-next.45 dev: false - /svelte2tsx@0.6.27(svelte@5.0.0-next.44)(typescript@5.3.3): + /svelte2tsx@0.6.27(svelte@5.0.0-next.45)(typescript@5.3.3): resolution: {integrity: sha512-E1uPW1o6VsbRz+nUk3fznZ2lSmCITAJoNu8AYefWSvIwE2pSB01i5sId4RMbWNzfcwCQl1DcgGShCPcldl4rvg==} peerDependencies: svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 @@ -4375,12 +4375,12 @@ packages: dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 - svelte: 5.0.0-next.44 + svelte: 5.0.0-next.45 typescript: 5.3.3 dev: false - /svelte@5.0.0-next.44: - resolution: {integrity: sha512-VO0HOOdCOURQgZ+KodijZGXQe6zp9U53ZmQlm1Lmy7/5p7QtFUHb420eM/KHaR9g8F1uFPK4xIlRBx3q5J0t3g==} + /svelte@5.0.0-next.45: + resolution: {integrity: sha512-+Cy7+SzAOrtunlKxkPg7cpJiEuc2TM5TJTAU50OI1PkiCjYmWLvvxZYwn0ulHMRJL6vQ4CCOOMUGbs7kUoqBKg==} engines: {node: '>=18'} dependencies: '@ampproject/remapping': 2.2.1 @@ -4448,7 +4448,7 @@ packages: dependencies: b4a: 1.6.4 fast-fifo: 1.3.2 - streamx: 2.15.6 + streamx: 2.15.7 dev: false optional: true diff --git a/src/components/cards/kanji/Kanji.astro b/src/components/cards/kanji/Kanji.astro new file mode 100644 index 0000000..f819919 --- /dev/null +++ b/src/components/cards/kanji/Kanji.astro @@ -0,0 +1,9 @@ +--- +import Widget from './kanji.svelte'; +--- +
+

Kanji of the Day

+
+ +
+
diff --git a/src/components/cards/kanji/data.svelte.ts b/src/components/cards/kanji/data.svelte.ts new file mode 100644 index 0000000..a24412b --- /dev/null +++ b/src/components/cards/kanji/data.svelte.ts @@ -0,0 +1,32 @@ +export interface KKLCEntry { + entry: number; + char: string; + meanings: string[]; + on: string[]; + kun: string[]; + examples: Array< + [Array<[string, string]>, string] + >; + senses: string[]; +} + + +async function chooseKanji(): Promise { + const date = new Date().toLocaleDateString('en'); + console.log(date); + const data = new TextEncoder().encode(date); + + const hash = await crypto.subtle.digest('SHA-256', data); + + const hashArray = Array.from(new Uint8Array(hash)); + const hashValue = hashArray.reduce((acc, byte) => acc + byte, 0); + + const min = 1; + const max = 2300; + const id = min + (hashValue % (max - min + 1)); + return id; +} + +export async function fetchKanji(): Promise { + return await fetch(`/static/kanji/${await chooseKanji()}.json`).then(res => res.json()); +} diff --git a/src/components/cards/kanji/kanji.svelte b/src/components/cards/kanji/kanji.svelte new file mode 100644 index 0000000..644d035 --- /dev/null +++ b/src/components/cards/kanji/kanji.svelte @@ -0,0 +1,49 @@ + + + +
+{#await state} +
+
+
+{:then state} +
+
+ {state.char} +
+
+
+ {state.meanings.join(', ')} +
+
+ {state.on.join(', ')} +
+
+ {state.kun.join(', ')} +
+
+
+ + + {#each state.examples as [example, meaning]} + + + + + {/each} + +
+ + {#each example as [kanji, furigana]}{kanji}{furigana || ''}{/each} + + + {meaning} +
+{/await} +
diff --git a/src/pages/index.astro b/src/pages/index.astro index 569d30b..2c965da 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,6 +1,7 @@ --- import Base from "@layouts/Base.astro"; import Intro from "@components/cards/Intro.astro"; +import Kanji from "@components/cards/kanji/Kanji.astro"; import Photo from "@components/cards/Photo.astro"; import Text from "@assets/markdown/index.md"; --- @@ -11,6 +12,7 @@ import Text from "@assets/markdown/index.md"; diff --git a/src/styles/_base.scss b/src/styles/_base.scss index b048ccc..6c51ed5 100644 --- a/src/styles/_base.scss +++ b/src/styles/_base.scss @@ -21,7 +21,7 @@ main { --fs-xs: 0.833rem; --fs-sm: 1rem; --fs-md: 1.2rem; - --fs-lg: 1.44rem; + --fs-lg: 1.44rem; --fs-xl: 1.728rem; } } diff --git a/src/styles/components/_kanji.scss b/src/styles/components/_kanji.scss new file mode 100644 index 0000000..a810ac7 --- /dev/null +++ b/src/styles/components/_kanji.scss @@ -0,0 +1,102 @@ +@use 'sass:math'; + + +.daily-kanji { + + .info { + display: flex; + justify-content: flex-start; + margin-bottom: 0.5em; + gap: 1em; + } + + .info-key { + font-weight: 700; + } + + .info-char { + position: relative; + padding: 0.1em; + border: 1px dashed black; + font-family: serif; + font-size: 5rem; + line-height: 1em; + + &::before { + top: -0.01em; + left: 0.6em; + width: 0; + height: 100%; + border-right: 1px dashed #000; + } + &::after { + top: 0.6em; + left: -0.01em; + width: 100%; + height: 0; + border-top: 1px dashed #000; + } + &::before, &::after { + content: ''; + position: absolute; + display: block; + } + } + .ruby-cell { + min-width: 5em; + } + + $side: 5em; + $radius: $side / 2; + + .spinner-wrap { + display: flex; + justify-content: center; + margin-top: 1em; + } + + .spinner { + display: inline-block; + position: relative; + width: $side; + height: $side; + + div { + animation: loading 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; + transform-origin: $radius $radius; + + &::after { + content: ''; + display: block; + position: absolute; + width: 7px; + height: 7px; + border-radius: 50%; + background: #000; + margin: -4px 0 0 -4px; + } + + @for $i from 1 through 8 { + $angle: 15deg * $i; + + &:nth-child(#{$i}) { + animation-delay: -0.036s * $i; + + &::after { + top: $radius + math.sin($angle) * $radius; + left: $radius + math.cos($angle) * $radius; + } + } + } + } + } + + @keyframes loading { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } +} diff --git a/src/styles/styles.scss b/src/styles/styles.scss index e946a7d..ecd46a3 100644 --- a/src/styles/styles.scss +++ b/src/styles/styles.scss @@ -10,6 +10,7 @@ @use 'components/search'; @use 'components/link-tree'; @use 'components/bibliography'; +@use 'components/kanji'; // Partials @use 'partials/navbar';