From 7f53fb3d27e2bc262ffd8d00d5d663485c24844a Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sun, 11 Jun 2023 15:08:19 -0500 Subject: [PATCH] kana input --- package-lock.json | 308 +++++++++- package.json | 3 +- src/components/DashboardReviewStats.tsx | 15 +- src/components/KanjiDisplay.tsx | 3 +- .../utils}/ConditionalWrapper.tsx | 0 .../utils}/ConfirmQuitModal.tsx | 0 src/components/utils/InputBox.tsx | 32 + .../utils}/SelectOnClick.tsx | 0 src/data/kanadata.json | 562 ++++++++++++++++++ src/lib/kanaHelper.ts | 42 ++ src/panes/HomePane.tsx | 17 - src/panes/SrsReviewPane.tsx | 75 ++- vite.config.ts | 2 +- 13 files changed, 996 insertions(+), 63 deletions(-) rename src/{lib => components/utils}/ConditionalWrapper.tsx (100%) rename src/{lib => components/utils}/ConfirmQuitModal.tsx (100%) create mode 100644 src/components/utils/InputBox.tsx rename src/{lib => components/utils}/SelectOnClick.tsx (100%) create mode 100644 src/data/kanadata.json create mode 100644 src/lib/kanaHelper.ts delete mode 100644 src/panes/HomePane.tsx diff --git a/package-lock.json b/package-lock.json index c13e7e1..42ad9a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@tauri-apps/api": "^1.3.0", - "@types/lodash-es": "^4.17.7", "classnames": "^2.3.2", "date-fns": "^2.30.0", "flowbite": "^1.6.5", @@ -28,11 +27,13 @@ }, "devDependencies": { "@tauri-apps/cli": "^1.3.1", + "@types/lodash-es": "^4.17.7", "@types/node": "^18.7.10", "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", "@types/react-timeago": "^4.1.3", "@vitejs/plugin-react": "^3.0.0", + "@vitejs/plugin-react-swc": "^3.3.2", "autoprefixer": "^10.4.14", "postcss": "^8.4.24", "prettier": "^2.8.8", @@ -1829,6 +1830,200 @@ "node": ">=14" } }, + "node_modules/@swc/core": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.62.tgz", + "integrity": "sha512-J58hWY+/G8vOr4J6ZH9hLg0lMSijZtqIIf4HofZezGog/pVX6sJyBJ40dZ1ploFkDIlWTWvJyqtpesBKS73gkQ==", + "dev": true, + "hasInstallScript": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.3.62", + "@swc/core-darwin-x64": "1.3.62", + "@swc/core-linux-arm-gnueabihf": "1.3.62", + "@swc/core-linux-arm64-gnu": "1.3.62", + "@swc/core-linux-arm64-musl": "1.3.62", + "@swc/core-linux-x64-gnu": "1.3.62", + "@swc/core-linux-x64-musl": "1.3.62", + "@swc/core-win32-arm64-msvc": "1.3.62", + "@swc/core-win32-ia32-msvc": "1.3.62", + "@swc/core-win32-x64-msvc": "1.3.62" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.62.tgz", + "integrity": "sha512-MmGilibITz68LEje6vJlKzc2gUUSgzvB3wGLSjEORikTNeM7P8jXVxE4A8fgZqDeudJUm9HVWrxCV+pHDSwXhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.62.tgz", + "integrity": "sha512-Xl93MMB3sCWVlYWuQIB+v6EQgzoiuQYK5tNt9lsHoIEVu2zLdkQjae+5FUHZb1VYqCXIiWcULFfVz0R4Sjb7JQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.62.tgz", + "integrity": "sha512-nJsp6O7kCtAjTTMcIjVB0g5y1JNiYAa5q630eiwrnaHUusEFoANDdORI3Z9vXeikMkng+6yIv9/V8Rb093xLjQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.62.tgz", + "integrity": "sha512-XGsV93vpUAopDt5y6vPwbK1Nc/MlL55L77bAZUPIiosWD1cWWPHNtNSpriE6+I+JiMHe0pqtfS/SSTk6ZkFQVw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.62.tgz", + "integrity": "sha512-ESUmJjSlTTkoBy9dMG49opcNn8BmviqStMhwyeD1G8XRnmRVCZZgoBOKdvCXmJhw8bQXDhZumeaTUB+OFUKVXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.62.tgz", + "integrity": "sha512-wnHJkt3ZBrax3SFnUHDcncG6mrSg9ZZjMhQV9Mc3JL1x1s1Gy9rGZCoBNnV/BUZWTemxIBcQbANRSDut/WO+9A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.62.tgz", + "integrity": "sha512-9oRbuTC/VshB66Rgwi3pTq3sPxSTIb8k9L1vJjES+dDMKa29DAjPtWCXG/pyZ00ufpFZgkGEuAHH5uqUcr1JQg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.62.tgz", + "integrity": "sha512-zv14vlF2VRrxS061XkfzGjCYnOrEo5glKJjLK5PwUKysIoVrx/L8nAbFxjkX5cObdlyoqo+ekelyBPAO+4bS0w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.62.tgz", + "integrity": "sha512-8MC/PZQSsOP2iA/81tAfNRqMWyEqTS/8zKUI67vPuLvpx6NAjRn3E9qBv7iFqH79iqZNzqSMo3awnLrKZyFbcw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.62.tgz", + "integrity": "sha512-GJSmUJ95HKHZXAxiuPUmrcm/S3ivQvEzXhOZaIqYBIwUsm02vFZkClsV7eIKzWjso1t0+I/8MjrnUNaSWqh1rQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@tauri-apps/api": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.3.0.tgz", @@ -2023,6 +2218,7 @@ "version": "4.17.7", "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz", "integrity": "sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==", + "dev": true, "dependencies": { "@types/lodash": "*" } @@ -2106,6 +2302,18 @@ "vite": "^4.1.0-beta.0" } }, + "node_modules/@vitejs/plugin-react-swc": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.3.2.tgz", + "integrity": "sha512-VJFWY5sfoZerQRvJrh518h3AcQt6f/yTuWn4/TRB+dqmYU0NX1qz7qM5Wfd+gOQqUzQW4gxKqKN3KpE/P3+zrA==", + "dev": true, + "dependencies": { + "@swc/core": "^1.3.61" + }, + "peerDependencies": { + "vite": "^4" + } + }, "node_modules/@zag-js/element-size": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.3.2.tgz", @@ -5418,6 +5626,94 @@ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.2.tgz", "integrity": "sha512-LzqpSrMK/3JBAVBI9u3NWtOhWNw5AMQfrUFYB0+bDHTSw17z++WJLsPsxAuK+oSddsxk4d7F/JcdDPM1M5YAhA==" }, + "@swc/core": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.62.tgz", + "integrity": "sha512-J58hWY+/G8vOr4J6ZH9hLg0lMSijZtqIIf4HofZezGog/pVX6sJyBJ40dZ1ploFkDIlWTWvJyqtpesBKS73gkQ==", + "dev": true, + "requires": { + "@swc/core-darwin-arm64": "1.3.62", + "@swc/core-darwin-x64": "1.3.62", + "@swc/core-linux-arm-gnueabihf": "1.3.62", + "@swc/core-linux-arm64-gnu": "1.3.62", + "@swc/core-linux-arm64-musl": "1.3.62", + "@swc/core-linux-x64-gnu": "1.3.62", + "@swc/core-linux-x64-musl": "1.3.62", + "@swc/core-win32-arm64-msvc": "1.3.62", + "@swc/core-win32-ia32-msvc": "1.3.62", + "@swc/core-win32-x64-msvc": "1.3.62" + } + }, + "@swc/core-darwin-arm64": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.62.tgz", + "integrity": "sha512-MmGilibITz68LEje6vJlKzc2gUUSgzvB3wGLSjEORikTNeM7P8jXVxE4A8fgZqDeudJUm9HVWrxCV+pHDSwXhA==", + "dev": true, + "optional": true + }, + "@swc/core-darwin-x64": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.62.tgz", + "integrity": "sha512-Xl93MMB3sCWVlYWuQIB+v6EQgzoiuQYK5tNt9lsHoIEVu2zLdkQjae+5FUHZb1VYqCXIiWcULFfVz0R4Sjb7JQ==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm-gnueabihf": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.62.tgz", + "integrity": "sha512-nJsp6O7kCtAjTTMcIjVB0g5y1JNiYAa5q630eiwrnaHUusEFoANDdORI3Z9vXeikMkng+6yIv9/V8Rb093xLjQ==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm64-gnu": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.62.tgz", + "integrity": "sha512-XGsV93vpUAopDt5y6vPwbK1Nc/MlL55L77bAZUPIiosWD1cWWPHNtNSpriE6+I+JiMHe0pqtfS/SSTk6ZkFQVw==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm64-musl": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.62.tgz", + "integrity": "sha512-ESUmJjSlTTkoBy9dMG49opcNn8BmviqStMhwyeD1G8XRnmRVCZZgoBOKdvCXmJhw8bQXDhZumeaTUB+OFUKVXg==", + "dev": true, + "optional": true + }, + "@swc/core-linux-x64-gnu": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.62.tgz", + "integrity": "sha512-wnHJkt3ZBrax3SFnUHDcncG6mrSg9ZZjMhQV9Mc3JL1x1s1Gy9rGZCoBNnV/BUZWTemxIBcQbANRSDut/WO+9A==", + "dev": true, + "optional": true + }, + "@swc/core-linux-x64-musl": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.62.tgz", + "integrity": "sha512-9oRbuTC/VshB66Rgwi3pTq3sPxSTIb8k9L1vJjES+dDMKa29DAjPtWCXG/pyZ00ufpFZgkGEuAHH5uqUcr1JQg==", + "dev": true, + "optional": true + }, + "@swc/core-win32-arm64-msvc": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.62.tgz", + "integrity": "sha512-zv14vlF2VRrxS061XkfzGjCYnOrEo5glKJjLK5PwUKysIoVrx/L8nAbFxjkX5cObdlyoqo+ekelyBPAO+4bS0w==", + "dev": true, + "optional": true + }, + "@swc/core-win32-ia32-msvc": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.62.tgz", + "integrity": "sha512-8MC/PZQSsOP2iA/81tAfNRqMWyEqTS/8zKUI67vPuLvpx6NAjRn3E9qBv7iFqH79iqZNzqSMo3awnLrKZyFbcw==", + "dev": true, + "optional": true + }, + "@swc/core-win32-x64-msvc": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.62.tgz", + "integrity": "sha512-GJSmUJ95HKHZXAxiuPUmrcm/S3ivQvEzXhOZaIqYBIwUsm02vFZkClsV7eIKzWjso1t0+I/8MjrnUNaSWqh1rQ==", + "dev": true, + "optional": true + }, "@tauri-apps/api": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.3.0.tgz", @@ -5512,6 +5808,7 @@ "version": "4.17.7", "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz", "integrity": "sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==", + "dev": true, "requires": { "@types/lodash": "*" } @@ -5589,6 +5886,15 @@ "react-refresh": "^0.14.0" } }, + "@vitejs/plugin-react-swc": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.3.2.tgz", + "integrity": "sha512-VJFWY5sfoZerQRvJrh518h3AcQt6f/yTuWn4/TRB+dqmYU0NX1qz7qM5Wfd+gOQqUzQW4gxKqKN3KpE/P3+zrA==", + "dev": true, + "requires": { + "@swc/core": "^1.3.61" + } + }, "@zag-js/element-size": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.3.2.tgz", diff --git a/package.json b/package.json index bff6698..e452582 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,13 @@ }, "devDependencies": { "@tauri-apps/cli": "^1.3.1", - "@types/node": "^18.7.10", "@types/lodash-es": "^4.17.7", + "@types/node": "^18.7.10", "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", "@types/react-timeago": "^4.1.3", "@vitejs/plugin-react": "^3.0.0", + "@vitejs/plugin-react-swc": "^3.3.2", "autoprefixer": "^10.4.14", "postcss": "^8.4.24", "prettier": "^2.8.8", diff --git a/src/components/DashboardReviewStats.tsx b/src/components/DashboardReviewStats.tsx index 6388489..135135a 100644 --- a/src/components/DashboardReviewStats.tsx +++ b/src/components/DashboardReviewStats.tsx @@ -1,21 +1,10 @@ -import { - Button, - Grid, - GridItem, - Stat, - StatArrow, - StatGroup, - StatHelpText, - StatLabel, - StatNumber, - Tooltip, -} from "@chakra-ui/react"; +import { Button, Grid, GridItem, Stat, StatLabel, StatNumber, Tooltip } from "@chakra-ui/react"; import { ArrowRightIcon } from "@chakra-ui/icons"; import styles from "./DashboardReviewStats.module.scss"; import useSWR from "swr"; import { invoke } from "@tauri-apps/api/tauri"; import { Link } from "react-router-dom"; -import ConditionalWrapper from "../lib/ConditionalWrapper"; +import ConditionalWrapper from "./utils/ConditionalWrapper"; interface SrsStats { reviews_available: number; diff --git a/src/components/KanjiDisplay.tsx b/src/components/KanjiDisplay.tsx index 5987abb..51551d0 100644 --- a/src/components/KanjiDisplay.tsx +++ b/src/components/KanjiDisplay.tsx @@ -1,12 +1,11 @@ import { invoke } from "@tauri-apps/api/tauri"; import { GetKanjiResult } from "../panes/KanjiPane"; -import { Kanji } from "../types/Kanji"; import TimeAgo from "react-timeago"; import styles from "./KanjiDisplay.module.scss"; import useSWR from "swr"; import { Button } from "@chakra-ui/button"; import { AddIcon } from "@chakra-ui/icons"; -import SelectOnClick from "../lib/SelectOnClick"; +import SelectOnClick from "./utils/SelectOnClick"; import { Alert, AlertIcon } from "@chakra-ui/alert"; import { isValid } from "date-fns"; diff --git a/src/lib/ConditionalWrapper.tsx b/src/components/utils/ConditionalWrapper.tsx similarity index 100% rename from src/lib/ConditionalWrapper.tsx rename to src/components/utils/ConditionalWrapper.tsx diff --git a/src/lib/ConfirmQuitModal.tsx b/src/components/utils/ConfirmQuitModal.tsx similarity index 100% rename from src/lib/ConfirmQuitModal.tsx rename to src/components/utils/ConfirmQuitModal.tsx diff --git a/src/components/utils/InputBox.tsx b/src/components/utils/InputBox.tsx new file mode 100644 index 0000000..4d01857 --- /dev/null +++ b/src/components/utils/InputBox.tsx @@ -0,0 +1,32 @@ +import { Input as BaseInput, InputProps as BaseInputProps } from "@chakra-ui/react"; +import { romajiToKana } from "../../lib/kanaHelper"; +import { ChangeEvent } from "react"; + +export interface InputProps extends BaseInputProps { + kanaInput?: boolean; + setValue?: (_: string) => void; + defaultValue?: string; +} + +export default function InputBox({ + kanaInput, + + value, + setValue, + + onChange: baseOnChange, + ...props +}: InputProps) { + const onChange = (evt: ChangeEvent) => { + let newValue = evt.target.value; + console.log("hellosu", kanaInput, newValue, romajiToKana(newValue)); + + if (kanaInput == true) newValue = romajiToKana(newValue) ?? newValue; + + setValue?.(newValue); + + if (baseOnChange) baseOnChange(evt); + }; + + return ; +} diff --git a/src/lib/SelectOnClick.tsx b/src/components/utils/SelectOnClick.tsx similarity index 100% rename from src/lib/SelectOnClick.tsx rename to src/components/utils/SelectOnClick.tsx diff --git a/src/data/kanadata.json b/src/data/kanadata.json new file mode 100644 index 0000000..f1e1a89 --- /dev/null +++ b/src/data/kanadata.json @@ -0,0 +1,562 @@ +{ + "kanaToHiragana": [ + ["ッ", "っ"], + ["チ", "ち"], + ["シ", "し"], + ["ツ", "つ"], + ["ヅ", "づ"], + ["ヂ", "ぢ"], + ["ヮ", "ゎ"], + ["ャ", "ゃ"], + ["ィ", "ぃ"], + ["ュ", "ゅ"], + ["ェ", "ぇ"], + ["ョ", "ょ"], + ["カ", "か"], + ["キ", "き"], + ["ク", "く"], + ["ケ", "け"], + ["コ", "こ"], + ["サ", "さ"], + ["ス", "す"], + ["セ", "せ"], + ["ソ", "そ"], + ["タ", "た"], + ["テ", "て"], + ["ト", "と"], + ["ナ", "な"], + ["ニ", "に"], + ["ヌ", "ぬ"], + ["ネ", "ね"], + ["ノ", "の"], + ["ハ", "は"], + ["ヒ", "ひ"], + ["フ", "ふ"], + ["ヘ", "へ"], + ["ホ", "ほ"], + ["マ", "ま"], + ["ミ", "み"], + ["ム", "む"], + ["メ", "め"], + ["モ", "も"], + ["ヤ", "や"], + ["ユ", "ゆ"], + ["ヨ", "よ"], + ["ラ", "ら"], + ["リ", "り"], + ["ル", "る"], + ["レ", "れ"], + ["ロ", "ろ"], + ["ワ", "わ"], + ["ヲ", "を"], + ["ガ", "が"], + ["ギ", "ぎ"], + ["グ", "ぐ"], + ["ゲ", "げ"], + ["ゴ", "ご"], + ["ジ", "じ"], + ["ダ", "だ"], + ["デ", "で"], + ["ド", "ど"], + ["バ", "ば"], + ["ビ", "び"], + ["ブ", "ぶ"], + ["ベ", "べ"], + ["ボ", "ぼ"], + ["パ", "ぱ"], + ["ピ", "ぴ"], + ["プ", "ぷ"], + ["ペ", "ぺ"], + ["ポ", "ぽ"], + ["ザ", "ざ"], + ["ズ", "ず"], + ["ゼ", "ぜ"], + ["ゾ", "ぞ"], + ["ァ", "ぁ"], + ["ィ", "ぃ"], + ["ゥ", "ぅ"], + ["ェ", "ぇ"], + ["ォ", "ぉ"], + ["ン", "ん"], + ["ア", "あ"], + ["イ", "い"], + ["ウ", "う"], + ["エ", "え"], + ["オ", "お"] + ], + + "katakanaToHiragana": [ + ["っ", "ッ"], + ["ち", "チ"], + ["し", "シ"], + ["つ", "ツ"], + ["づ", "ヅ"], + ["ぢ", "ヂ"], + ["ゎ", "ヮ"], + ["ゃ", "ャ"], + ["ぃ", "ィ"], + ["ゅ", "ュ"], + ["ぇ", "ェ"], + ["ょ", "ョ"], + ["か", "カ"], + ["き", "キ"], + ["く", "ク"], + ["け", "ケ"], + ["こ", "コ"], + ["さ", "サ"], + ["す", "ス"], + ["せ", "セ"], + ["そ", "ソ"], + ["た", "タ"], + ["て", "テ"], + ["と", "ト"], + ["な", "ナ"], + ["に", "ニ"], + ["ぬ", "ヌ"], + ["ね", "ネ"], + ["の", "ノ"], + ["は", "ハ"], + ["ひ", "ヒ"], + ["ふ", "フ"], + ["へ", "ヘ"], + ["ほ", "ホ"], + ["ま", "マ"], + ["み", "ミ"], + ["む", "ム"], + ["め", "メ"], + ["も", "モ"], + ["や", "ヤ"], + ["ゆ", "ユ"], + ["よ", "ヨ"], + ["ら", "ラ"], + ["り", "リ"], + ["る", "ル"], + ["れ", "レ"], + ["ろ", "ロ"], + ["わ", "ワ"], + ["を", "ヲ"], + ["が", "ガ"], + ["ぎ", "ギ"], + ["ぐ", "グ"], + ["げ", "ゲ"], + ["ご", "ゴ"], + ["じ", "ジ"], + ["だ", "ダ"], + ["で", "デ"], + ["ど", "ド"], + ["ば", "バ"], + ["び", "ビ"], + ["ぶ", "ブ"], + ["べ", "ベ"], + ["ぼ", "ボ"], + ["ぱ", "パ"], + ["ぴ", "ピ"], + ["ぷ", "プ"], + ["ぺ", "ペ"], + ["ぽ", "ポ"], + ["ざ", "ザ"], + ["ず", "ズ"], + ["ぜ", "ゼ"], + ["ぞ", "ゾ"], + ["ぁ", "ァ"], + ["ぃ", "ィ"], + ["ぅ", "ゥ"], + ["ぇ", "ェ"], + ["ぉ", "ォ"], + ["ん", "ン"], + ["あ", "ア"], + ["い", "イ"], + ["う", "ウ"], + ["え", "エ"], + ["お", "オ"] + ], + + "romajiToKana": { + "4letter": [ + ["XTSU", "ッ"], + ["xtsu", "っ"], + ["LTSU", "ッ"], + ["ltsu", "っ"] + ], + "3letter": [ + ["CHA", "チャ"], + ["cha", "ちゃ"], + ["CHI", "チ"], + ["chi", "ち"], + ["CHU", "チュ"], + ["chu", "ちゅ"], + ["CHE", "チェ"], + ["che", "ちぇ"], + ["CHO", "チョ"], + ["cho", "ちょ"], + ["SHA", "シャ"], + ["sha", "しゃ"], + ["SHI", "シ"], + ["shi", "し"], + ["SHU", "シュ"], + ["shu", "しゅ"], + ["SHE", "シェ"], + ["she", "しぇ"], + ["SHO", "ショ"], + ["sho", "しょ"], + ["RYA", "リャ"], + ["rya", "りゃ"], + ["RYI", "リィ"], + ["ryi", "りぃ"], + ["RYU", "リュ"], + ["ryu", "りゅ"], + ["RYE", "リェ"], + ["rye", "りぇ"], + ["RYO", "リョ"], + ["ryo", "りょ"], + ["HYA", "ヒャ"], + ["hya", "ひゃ"], + ["HYI", "ヒィ"], + ["hyi", "ひぃ"], + ["HYU", "ヒュ"], + ["hyu", "ひゅ"], + ["HYE", "ヒェ"], + ["hye", "ひぇ"], + ["HYO", "ヒョ"], + ["hyo", "ひょ"], + ["BYA", "ビャ"], + ["bya", "びゃ"], + ["BYI", "ビィ"], + ["byi", "びぃ"], + ["BYU", "ビュ"], + ["byu", "びゅ"], + ["BYE", "ビェ"], + ["bye", "びぇ"], + ["BYO", "ビョ"], + ["byo", "びょ"], + ["PYA", "ピャ"], + ["pya", "ぴゃ"], + ["PYI", "ピィ"], + ["pyi", "ぴぃ"], + ["PYU", "ピュ"], + ["pyu", "ぴゅ"], + ["PYE", "ピェ"], + ["pye", "ぴぇ"], + ["PYO", "ピョ"], + ["pyo", "ぴょ"], + ["MYA", "ミャ"], + ["mya", "みゃ"], + ["MYI", "ミィ"], + ["myi", "みぃ"], + ["MYU", "ミュ"], + ["myu", "みゅ"], + ["MYE", "ミェ"], + ["mye", "みぇ"], + ["MYO", "ミョ"], + ["myo", "みょ"], + ["KYA", "キャ"], + ["kya", "きゃ"], + ["KYI", "キィ"], + ["kyi", "きぃ"], + ["KYU", "キュ"], + ["kyu", "きゅ"], + ["KYE", "キェ"], + ["kye", "きぇ"], + ["KYO", "キョ"], + ["kyo", "きょ"], + ["GYA", "ギャ"], + ["gya", "ぎゃ"], + ["GYI", "ギィ"], + ["gyi", "ぎぃ"], + ["GYU", "ギュ"], + ["gyu", "ぎゅ"], + ["GYE", "ギェ"], + ["gye", "ぎぇ"], + ["GYO", "ギョ"], + ["gyo", "ぎょ"], + ["NYA", "ニャ"], + ["nya", "にゃ"], + ["NYI", "ニィ"], + ["nyi", "にぃ"], + ["NYU", "ニュ"], + ["nyu", "にゅ"], + ["NYE", "ニェ"], + ["nye", "にぇ"], + ["NYO", "ニョ"], + ["nyo", "にょ"], + ["JYA", "ジャ"], + ["jya", "じゃ"], + ["JYI", "ジィ"], + ["jyi", "じぃ"], + ["JYU", "ジュ"], + ["jyu", "じゅ"], + ["JYE", "ジェ"], + ["jye", "じぇ"], + ["JYO", "ジョ"], + ["jyo", "じょ"], + ["TSU", "ツ"], + ["tsu", "つ"], + ["DZU", "ヅ"], + ["dzu", "づ"], + ["DZI", "ヂ"], + ["dzi", "ぢ"], + ["DYA", "ヂャ"], + ["dya", "ぢゃ"], + ["DYI", "ヂィ"], + ["dyi", "ぢぃ"], + ["DYU", "ヂュ"], + ["dyu", "ぢゅ"], + ["DYE", "ヂェ"], + ["dye", "ぢぇ"], + ["DYO", "ヂョ"], + ["dyo", "ぢょ"], + ["XTU", "ッ"], + ["xtu", "っ"], + ["XWA", "ヮ"], + ["xwa", "ゎ"], + ["XKA", "ヵ"], + ["xka", "ヵ"], + ["XKE", "ヶ"], + ["xke", "ヶ"], + ["XYA", "ャ"], + ["xya", "ゃ"], + ["XYI", "ィ"], + ["xyi", "ぃ"], + ["XYU", "ュ"], + ["xyu", "ゅ"], + ["XYE", "ェ"], + ["xye", "ぇ"], + ["XYO", "ョ"], + ["xyo", "ょ"], + ["cya", "ちゃ"], + ["cyu", "ちゅ"], + ["cyo", "ちょ"], + ["sya", "しゃ"], + ["syu", "しゅ"], + ["syo", "しょ"], + ["tya", "ちゃ"], + ["tyu", "ちゅ"], + ["tyo", "ちょ"], + ["TYA", "チャ"], + ["TYU", "チュ"], + ["TYO", "チョ"] + ], + "2letter": [ + ["KA", "カ"], + ["ka", "か"], + ["KI", "キ"], + ["ki", "き"], + ["KU", "ク"], + ["ku", "く"], + ["KE", "ケ"], + ["ke", "け"], + ["KO", "コ"], + ["ko", "こ"], + ["CA", "カ"], + ["ca", "か"], + ["CI", "キ"], + ["ci", "き"], + ["CU", "ク"], + ["cu", "く"], + ["CE", "ケ"], + ["ce", "け"], + ["CO", "コ"], + ["co", "こ"], + ["SA", "サ"], + ["sa", "さ"], + ["SI", "シ"], + ["si", "し"], + ["SU", "ス"], + ["su", "す"], + ["SE", "セ"], + ["se", "せ"], + ["SO", "ソ"], + ["so", "そ"], + ["TA", "タ"], + ["ta", "た"], + ["TE", "テ"], + ["ti", "ち"], + ["TI", "チ"], + ["tu", "つ"], + ["TU", "ツ"], + ["te", "て"], + ["TO", "ト"], + ["to", "と"], + ["NA", "ナ"], + ["na", "な"], + ["NI", "ニ"], + ["ni", "に"], + ["NU", "ヌ"], + ["nu", "ぬ"], + ["NE", "ネ"], + ["ne", "ね"], + ["NO", "ノ"], + ["no", "の"], + ["HA", "ハ"], + ["ha", "は"], + ["HI", "ヒ"], + ["hi", "ひ"], + ["HU", "フ"], + ["hu", "ふ"], + ["HE", "ヘ"], + ["he", "へ"], + ["HO", "ホ"], + ["ho", "ほ"], + ["MA", "マ"], + ["ma", "ま"], + ["MI", "ミ"], + ["mi", "み"], + ["MU", "ム"], + ["mu", "む"], + ["ME", "メ"], + ["me", "め"], + ["MO", "モ"], + ["mo", "も"], + ["YA", "ヤ"], + ["ya", "や"], + ["YU", "ユ"], + ["yu", "ゆ"], + ["YE", "イェ"], + ["ye", "いぇ"], + ["YO", "ヨ"], + ["yo", "よ"], + ["RA", "ラ"], + ["ra", "ら"], + ["RI", "リ"], + ["ri", "り"], + ["RU", "ル"], + ["ru", "る"], + ["RE", "レ"], + ["re", "れ"], + ["RO", "ロ"], + ["ro", "ろ"], + ["LA", "ラ"], + ["la", "ら"], + ["LI", "リ"], + ["li", "り"], + ["LU", "ル"], + ["lu", "る"], + ["LE", "レ"], + ["le", "れ"], + ["LO", "ロ"], + ["lo", "ろ"], + ["WA", "ワ"], + ["wa", "わ"], + ["WI", "ウィ"], + ["wi", "うぃ"], + ["WU", "ウ"], + ["wu", "う"], + ["WE", "ウェ"], + ["we", "うぇ"], + ["WO", "ヲ"], + ["wo", "を"], + ["GA", "ガ"], + ["ga", "が"], + ["GI", "ギ"], + ["gi", "ぎ"], + ["GU", "グ"], + ["gu", "ぐ"], + ["GE", "ゲ"], + ["ge", "げ"], + ["GO", "ゴ"], + ["go", "ご"], + ["JA", "ジャ"], + ["ja", "じゃ"], + ["JI", "ジ"], + ["ji", "じ"], + ["JU", "ジュ"], + ["ju", "じゅ"], + ["JE", "ジェ"], + ["je", "じぇ"], + ["JO", "ジョ"], + ["jo", "じょ"], + ["DA", "ダ"], + ["da", "だ"], + ["DI", "ヂ"], + ["di", "ぢ"], + ["DU", "ヅ"], + ["du", "づ"], + ["DE", "デ"], + ["de", "で"], + ["DO", "ド"], + ["do", "ど"], + ["BA", "バ"], + ["ba", "ば"], + ["BI", "ビ"], + ["bi", "び"], + ["BU", "ブ"], + ["bu", "ぶ"], + ["BE", "ベ"], + ["be", "べ"], + ["BO", "ボ"], + ["bo", "ぼ"], + ["VA", "ヴァ"], + ["va", "ヴぁ"], + ["VI", "ヴィ"], + ["vi", "ヴぃ"], + ["VU", "ヴ"], + ["vu", "ヴ"], + ["VE", "ヴェ"], + ["ve", "ヴぇ"], + ["VO", "ヴォ"], + ["vo", "ヴぉ"], + ["PA", "パ"], + ["pa", "ぱ"], + ["PI", "ピ"], + ["pi", "ぴ"], + ["PU", "プ"], + ["pu", "ぷ"], + ["PE", "ペ"], + ["pe", "ぺ"], + ["PO", "ポ"], + ["po", "ぽ"], + ["ZA", "ザ"], + ["za", "ざ"], + ["ZI", "ジ"], + ["zi", "じ"], + ["ZU", "ズ"], + ["zu", "ず"], + ["ZE", "ゼ"], + ["ze", "ぜ"], + ["ZO", "ゾ"], + ["zo", "ぞ"], + ["FA", "ファ"], + ["fa", "ふぁ"], + ["FI", "フィ"], + ["fi", "ふぃ"], + ["FU", "フ"], + ["fu", "ふ"], + ["FE", "フェ"], + ["fe", "ふぇ"], + ["FO", "フォ"], + ["fo", "ふぉ"], + ["XA", "ァ"], + ["xa", "ぁ"], + ["XI", "ィ"], + ["xi", "ぃ"], + ["XU", "ゥ"], + ["xu", "ぅ"], + ["XE", "ェ"], + ["xe", "ぇ"], + ["XO", "ォ"], + ["xo", "ぉ"], + ["XN", "ン"], + ["xn", "ん"], + ["NN", "ン"], + ["N'", "ン"], + ["nn", "ん"], + ["n'", "ん"] + ], + "1letter": [ + ["A", "ア"], + ["a", "あ"], + ["I", "イ"], + ["i", "い"], + ["U", "ウ"], + ["u", "う"], + ["E", "エ"], + ["e", "え"], + ["O", "オ"], + ["o", "お"] + ], + "replaceN": [ + ["N", "ン"], + ["n", "ん"] + ] + } +} diff --git a/src/lib/kanaHelper.ts b/src/lib/kanaHelper.ts new file mode 100644 index 0000000..5624004 --- /dev/null +++ b/src/lib/kanaHelper.ts @@ -0,0 +1,42 @@ +import kanadata from "../data/kanadata.json"; + +/** + * Specifically converts a romaji string to kana. + * The result may be hiragana, katakana or mixed, depending on the case + * of the input romaji. + * + * @param romaji Input romaji string. + * @param isLive Set to true to specify that the conversion is done in live (while the user is writing). Disables certain functions. + * @returns Output kana string. + */ +export function romajiToKana(romaji: string, isLive = false): string | null { + let s = romaji.trim(); + if (s == "") return null; + + // Replace the double vowels for katakana. + const doubleVowelRegex = /([AEIOU])\1/g; + s = s.replaceAll(doubleVowelRegex, "$1ー"); + + // Replace the double consonants. + + // Then, replace - by ー. + s = s.replaceAll("-", "ー"); + s = s.replaceAll("_", "ー"); + + // Then, replace 4 letter characters: + for (const [find, repl] of kanadata.romajiToKana["4letter"]) s = s.replaceAll(find, repl); + + // Then, replace 3 letter characters: + for (const [find, repl] of kanadata.romajiToKana["3letter"]) s = s.replaceAll(find, repl); + + // Then, replace 2 letter characters: + for (const [find, repl] of kanadata.romajiToKana["2letter"]) s = s.replaceAll(find, repl); + + // Then, replace 1 letter characters: + for (const [find, repl] of kanadata.romajiToKana["1letter"]) s = s.replaceAll(find, repl); + + if (!isLive) + for (const [find, repl] of kanadata.romajiToKana["replaceN"]) s = s.replaceAll(find, repl); + + return s; +} diff --git a/src/panes/HomePane.tsx b/src/panes/HomePane.tsx deleted file mode 100644 index 3899667..0000000 --- a/src/panes/HomePane.tsx +++ /dev/null @@ -1,17 +0,0 @@ -export default function HomePane() { - return ( -
-

Houhou

- - - Source - -
- ); -} diff --git a/src/panes/SrsReviewPane.tsx b/src/panes/SrsReviewPane.tsx index a213cf8..6af4986 100644 --- a/src/panes/SrsReviewPane.tsx +++ b/src/panes/SrsReviewPane.tsx @@ -3,6 +3,7 @@ import { Container, Input, InputGroup, + InputLeftElement, InputRightElement, Progress, Spinner, @@ -14,8 +15,9 @@ import { invoke } from "@tauri-apps/api/tauri"; import { Link, useNavigate } from "react-router-dom"; import { ArrowBackIcon, CheckIcon } from "@chakra-ui/icons"; import { FormEvent } from "react"; -import ConfirmQuitModal from "../lib/ConfirmQuitModal"; +import ConfirmQuitModal from "../components/utils/ConfirmQuitModal"; import * as _ from "lodash-es"; +import InputBox from "../components/utils/InputBox"; export interface SrsEntry { associated_kanji: string; @@ -25,8 +27,8 @@ export interface SrsEntry { } export enum ReviewItemType { - MEANING, - READING, + MEANING = "MEANING", + READING = "READING", } export interface ReviewItem { @@ -100,15 +102,38 @@ export function Component() { setReviewQueue(rest); }; + if (!reviewQueue) return ; + if (reviewQueue.length == 0) return ; + const nextItem = reviewQueue[0]; + + const inputBox = (kanaInput: boolean) => { + return ( + + {kanaInput ? "あ" : "A"} + + + + + + + + ); + }; + const renderInside = () => { - if (!reviewQueue) return ; - - if (reviewQueue.length == 0) return ; - - const nextItem = reviewQueue[0]; - console.log("next item", nextItem); + const kanaInput = nextItem.type == ReviewItemType.READING; + return ( <> {startingSize && ( @@ -123,27 +148,15 @@ export function Component() {

{nextItem.challenge}

-
- Debug -
{JSON.stringify(nextItem, null, 2)}
-
-
- - setCurrentAnswer(evt.target.value)} - /> + { + { + [ReviewItemType.MEANING]: "What is the meaning?", + [ReviewItemType.READING]: "What is the reading?", + }[nextItem.type] + } - - - - + {inputBox(kanaInput)}
); @@ -164,6 +177,12 @@ export function Component() { Back + +
+ Debug +
{JSON.stringify(nextItem, null, 2)}
+
+
{renderInside()}
diff --git a/vite.config.ts b/vite.config.ts index 86879f1..2e1d9e4 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; +import react from "@vitejs/plugin-react-swc"; // https://vitejs.dev/config/ export default defineConfig(async () => ({