wrong answer
This commit is contained in:
parent
7f53fb3d27
commit
f87230596d
12 changed files with 427 additions and 79 deletions
|
@ -58,6 +58,7 @@ pub struct GetKanjiResult {
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct KanjiSrsInfo {
|
pub struct KanjiSrsInfo {
|
||||||
id: u32,
|
id: u32,
|
||||||
|
current_grade: u32,
|
||||||
next_answer_date: EpochMs,
|
next_answer_date: EpochMs,
|
||||||
associated_kanji: String,
|
associated_kanji: String,
|
||||||
}
|
}
|
||||||
|
@ -145,6 +146,7 @@ pub async fn get_kanji(
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = row.get("ID");
|
let id = row.get("ID");
|
||||||
|
let current_grade = row.get("CurrentGrade");
|
||||||
let next_answer_date: i64 = row.get("NextAnswerDate");
|
let next_answer_date: i64 = row.get("NextAnswerDate");
|
||||||
let next_answer_date = Ticks(next_answer_date).epoch_ms();
|
let next_answer_date = Ticks(next_answer_date).epoch_ms();
|
||||||
|
|
||||||
|
@ -152,6 +154,7 @@ pub async fn get_kanji(
|
||||||
associated_kanji.clone(),
|
associated_kanji.clone(),
|
||||||
KanjiSrsInfo {
|
KanjiSrsInfo {
|
||||||
id,
|
id,
|
||||||
|
current_grade,
|
||||||
next_answer_date,
|
next_answer_date,
|
||||||
associated_kanji,
|
associated_kanji,
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,7 +41,6 @@ $kanjiCharacterSize: 28px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,3 +61,10 @@ $kanjiCharacterSize: 28px;
|
||||||
.search-container {
|
.search-container {
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badges {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { Kanji } from "../types/Kanji";
|
||||||
import { Input, Spinner } from "@chakra-ui/react";
|
import { Input, Spinner } from "@chakra-ui/react";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import SearchBar from "./SearchBar";
|
import SearchBar from "./SearchBar";
|
||||||
|
import GradeBadge from "./utils/GradeBadge";
|
||||||
|
|
||||||
export interface KanjiListProps {
|
export interface KanjiListProps {
|
||||||
kanjiList: Kanji[];
|
kanjiList: Kanji[];
|
||||||
|
@ -30,12 +31,13 @@ export function KanjiList({
|
||||||
},
|
},
|
||||||
[setLoadingCanary],
|
[setLoadingCanary],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Infinite scroll
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (loadingCanary && !isLoadingMore) {
|
if (loadingCanary && !isLoadingMore) {
|
||||||
const observer = new IntersectionObserver((entries) => {
|
const observer = new IntersectionObserver((entries) => {
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
console.log("loading more shit");
|
|
||||||
loadMoreKanji();
|
loadMoreKanji();
|
||||||
setIsLoadingMore(true);
|
setIsLoadingMore(true);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +64,8 @@ export function KanjiList({
|
||||||
{kanji.character}
|
{kanji.character}
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem>{kanji.meanings[0].meaning}</GridItem>
|
<GridItem>{kanji.meanings[0].meaning}</GridItem>
|
||||||
<GridItem>
|
<GridItem className={styles.badges}>
|
||||||
|
<GradeBadge grade={kanji.srs_info?.current_grade} />
|
||||||
<Badge>#{kanji.most_used_rank} common</Badge>
|
<Badge>#{kanji.most_used_rank} common</Badge>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
28
src/components/utils/GradeBadge.tsx
Normal file
28
src/components/utils/GradeBadge.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { Badge } from "@chakra-ui/react";
|
||||||
|
|
||||||
|
export interface GradeBadgeProps {
|
||||||
|
grade?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function GradeBadge({ grade }: GradeBadgeProps) {
|
||||||
|
if (!grade) return null;
|
||||||
|
|
||||||
|
const badgeInfo = badgeMap.get(grade);
|
||||||
|
if (!badgeInfo) return null;
|
||||||
|
|
||||||
|
const [letter, colorScheme] = badgeInfo;
|
||||||
|
|
||||||
|
return <Badge colorScheme={colorScheme}>{letter}</Badge>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const badgeMap = new Map<number, [string | JSX.Element, string]>([
|
||||||
|
[8, [<>★</>, "green"]],
|
||||||
|
[7, ["A2", "blue"]],
|
||||||
|
[6, ["A1", "blue"]],
|
||||||
|
[5, ["B2", "yellow"]],
|
||||||
|
[4, ["B1", "yellow"]],
|
||||||
|
[3, ["C2", "orange"]],
|
||||||
|
[2, ["C1", "orange"]],
|
||||||
|
[1, ["D2", "red"]],
|
||||||
|
[0, ["D1", "red"]],
|
||||||
|
]);
|
|
@ -1,32 +0,0 @@
|
||||||
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<HTMLInputElement>) => {
|
|
||||||
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 <BaseInput value={value} onChange={onChange} {...props} />;
|
|
||||||
}
|
|
|
@ -171,6 +171,331 @@
|
||||||
["お", "オ"]
|
["お", "オ"]
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"kanaToRomaji": {
|
||||||
|
"2letter": [
|
||||||
|
["イェ", "YE"],
|
||||||
|
["いぇ", "ye"],
|
||||||
|
["ウィ", "WI"],
|
||||||
|
["うぃ", "wi"],
|
||||||
|
["ウェ", "WE"],
|
||||||
|
["うぇ", "we"],
|
||||||
|
["ヴァ", "WA"],
|
||||||
|
["ヴぁ", "wa"],
|
||||||
|
["ヴィ", "WI"],
|
||||||
|
["ヴぃ", "wi"],
|
||||||
|
["ヴェ", "WE"],
|
||||||
|
["ヴぇ", "we"],
|
||||||
|
["ヴォ", "WO"],
|
||||||
|
["ヴぉ", "wo"],
|
||||||
|
["ファ", "FA"],
|
||||||
|
["ふぁ", "fa"],
|
||||||
|
["フィ", "FI"],
|
||||||
|
["ふぃ", "fi"],
|
||||||
|
["フェ", "FE"],
|
||||||
|
["ふぇ", "fe"],
|
||||||
|
["フォ", "FO"],
|
||||||
|
["ふぉ", "fo"],
|
||||||
|
["チャ", "CHA"],
|
||||||
|
["ちゃ", "cha"],
|
||||||
|
["チュ", "CHU"],
|
||||||
|
["ちゅ", "chu"],
|
||||||
|
["チェ", "CHE"],
|
||||||
|
["ちぇ", "che"],
|
||||||
|
["チョ", "CHO"],
|
||||||
|
["ちょ", "cho"],
|
||||||
|
["シャ", "SHA"],
|
||||||
|
["しゃ", "sha"],
|
||||||
|
["シュ", "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"],
|
||||||
|
["ジャ", "JA"],
|
||||||
|
["じゃ", "ja"],
|
||||||
|
["ジィ", "JI"],
|
||||||
|
["じぃ", "ji"],
|
||||||
|
["ジュ", "JU"],
|
||||||
|
["じゅ", "ju"],
|
||||||
|
["ジェ", "JE"],
|
||||||
|
["じぇ", "je"],
|
||||||
|
["ジョ", "JO"],
|
||||||
|
["じょ", "jo"],
|
||||||
|
["ヂャ", "DYA"],
|
||||||
|
["ぢゃ", "dya"],
|
||||||
|
["ヂィ", "DYI"],
|
||||||
|
["ぢぃ", "dyi"],
|
||||||
|
["ヂュ", "DYU"],
|
||||||
|
["ぢゅ", "dyu"],
|
||||||
|
["ヂェ", "DYE"],
|
||||||
|
["ぢぇ", "dye"],
|
||||||
|
["ヂョ", "DYO"],
|
||||||
|
["ぢょ", "dyo"]
|
||||||
|
],
|
||||||
|
"1letter": [
|
||||||
|
["ア", "A"],
|
||||||
|
["あ", "a"],
|
||||||
|
["イ", "I"],
|
||||||
|
["い", "i"],
|
||||||
|
["ウ", "U"],
|
||||||
|
["う", "u"],
|
||||||
|
["エ", "E"],
|
||||||
|
["え", "e"],
|
||||||
|
["オ", "O"],
|
||||||
|
["お", "o"],
|
||||||
|
["カ", "KA"],
|
||||||
|
["か", "ka"],
|
||||||
|
["キ", "KI"],
|
||||||
|
["き", "ki"],
|
||||||
|
["ク", "KU"],
|
||||||
|
["く", "ku"],
|
||||||
|
["ケ", "KE"],
|
||||||
|
["け", "ke"],
|
||||||
|
["コ", "KO"],
|
||||||
|
["こ", "ko"],
|
||||||
|
["サ", "SA"],
|
||||||
|
["さ", "sa"],
|
||||||
|
["シ", "SI"],
|
||||||
|
["し", "si"],
|
||||||
|
["ス", "SU"],
|
||||||
|
["す", "su"],
|
||||||
|
["セ", "SE"],
|
||||||
|
["せ", "se"],
|
||||||
|
["ソ", "SO"],
|
||||||
|
["そ", "so"],
|
||||||
|
["タ", "TA"],
|
||||||
|
["た", "ta"],
|
||||||
|
["テ", "TE"],
|
||||||
|
["て", "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"],
|
||||||
|
["ヨ", "YO"],
|
||||||
|
["よ", "yo"],
|
||||||
|
["ラ", "RA"],
|
||||||
|
["ら", "ra"],
|
||||||
|
["リ", "RI"],
|
||||||
|
["り", "ri"],
|
||||||
|
["ル", "RU"],
|
||||||
|
["る", "ru"],
|
||||||
|
["レ", "RE"],
|
||||||
|
["れ", "re"],
|
||||||
|
["ロ", "RO"],
|
||||||
|
["ろ", "ro"],
|
||||||
|
["ワ", "WA"],
|
||||||
|
["わ", "wa"],
|
||||||
|
["ヲ", "WO"],
|
||||||
|
["を", "wo"],
|
||||||
|
["ガ", "GA"],
|
||||||
|
["が", "ga"],
|
||||||
|
["ギ", "GI"],
|
||||||
|
["ぎ", "gi"],
|
||||||
|
["グ", "GU"],
|
||||||
|
["ぐ", "gu"],
|
||||||
|
["ゲ", "GE"],
|
||||||
|
["げ", "ge"],
|
||||||
|
["ゴ", "GO"],
|
||||||
|
["ご", "go"],
|
||||||
|
["チ", "CHI"],
|
||||||
|
["ち", "chi"],
|
||||||
|
["ジ", "JI"],
|
||||||
|
["じ", "ji"],
|
||||||
|
["ダ", "DA"],
|
||||||
|
["だ", "da"],
|
||||||
|
["ヂ", "DI"],
|
||||||
|
["ぢ", "di"],
|
||||||
|
["ヅ", "DU"],
|
||||||
|
["づ", "du"],
|
||||||
|
["デ", "DE"],
|
||||||
|
["で", "de"],
|
||||||
|
["ド", "DO"],
|
||||||
|
["ど", "do"],
|
||||||
|
["バ", "BA"],
|
||||||
|
["ば", "ba"],
|
||||||
|
["ビ", "BI"],
|
||||||
|
["び", "bi"],
|
||||||
|
["ブ", "BU"],
|
||||||
|
["ぶ", "bu"],
|
||||||
|
["ベ", "BE"],
|
||||||
|
["べ", "be"],
|
||||||
|
["ボ", "BO"],
|
||||||
|
["ぼ", "bo"],
|
||||||
|
["ヴ", "VU"],
|
||||||
|
["ヴ", "vu"],
|
||||||
|
["パ", "PA"],
|
||||||
|
["ぱ", "pa"],
|
||||||
|
["ピ", "PI"],
|
||||||
|
["ぴ", "pi"],
|
||||||
|
["プ", "PU"],
|
||||||
|
["ぷ", "pu"],
|
||||||
|
["ペ", "PE"],
|
||||||
|
["ぺ", "pe"],
|
||||||
|
["ポ", "PO"],
|
||||||
|
["ぽ", "po"],
|
||||||
|
["ザ", "ZA"],
|
||||||
|
["ざ", "za"],
|
||||||
|
["ジ", "ZI"],
|
||||||
|
["じ", "zi"],
|
||||||
|
["ズ", "ZU"],
|
||||||
|
["ず", "zu"],
|
||||||
|
["ゼ", "ZE"],
|
||||||
|
["ぜ", "ze"],
|
||||||
|
["ゾ", "ZO"],
|
||||||
|
["ぞ", "zo"],
|
||||||
|
["フ", "FU"],
|
||||||
|
["ふ", "fu"],
|
||||||
|
["ァ", "A"],
|
||||||
|
["ぁ", "a"],
|
||||||
|
["ィ", "I"],
|
||||||
|
["ぃ", "i"],
|
||||||
|
["ゥ", "U"],
|
||||||
|
["ぅ", "u"],
|
||||||
|
["ェ", "E"],
|
||||||
|
["ぇ", "e"],
|
||||||
|
["ォ", "O"],
|
||||||
|
["ぉ", "o"],
|
||||||
|
["ン", "N"],
|
||||||
|
["ん", "n"],
|
||||||
|
["シ", "SHI"],
|
||||||
|
["し", "shi"],
|
||||||
|
["ツ", "TSU"],
|
||||||
|
["つ", "tsu"],
|
||||||
|
["ヅ", "DU"],
|
||||||
|
["づ", "du"],
|
||||||
|
["ヂ", "DI"],
|
||||||
|
["ぢ", "di"],
|
||||||
|
["ヮ", "WA"],
|
||||||
|
["ゎ", "wa"],
|
||||||
|
["ヵ", "KA"],
|
||||||
|
["ヵ", "ka"],
|
||||||
|
["ヶ", "KE"],
|
||||||
|
["ヶ", "ke"],
|
||||||
|
["ャ", "YA"],
|
||||||
|
["ゃ", "ya"],
|
||||||
|
["ィ", "YI"],
|
||||||
|
["ぃ", "yi"],
|
||||||
|
["ュ", "YU"],
|
||||||
|
["ゅ", "yu"],
|
||||||
|
["ェ", "YE"],
|
||||||
|
["ぇ", "ye"],
|
||||||
|
["ョ", "YO"],
|
||||||
|
["ょ", "yo"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
"romajiToKana": {
|
"romajiToKana": {
|
||||||
"4letter": [
|
"4letter": [
|
||||||
["XTSU", "ッ"],
|
["XTSU", "ッ"],
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// See https://github.com/Doublevil/Houhou-SRS/blob/master/Kanji.Common/Helpers/KanaHelper.cs
|
||||||
|
|
||||||
import kanadata from "../data/kanadata.json";
|
import kanadata from "../data/kanadata.json";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -35,9 +35,10 @@ export function Component() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadMoreKanji = async () => {
|
const loadMoreKanji = async () => {
|
||||||
const result = await invoke<GetKanjiResult>("get_kanji", { options: {skip: kanjiList.length }});
|
const result = await invoke<GetKanjiResult>("get_kanji", {
|
||||||
console.log("invoked result", result);
|
options: { skip: kanjiList.length, include_srs_info: true },
|
||||||
setKanjiList([...kanjiList, ...result.kanji])
|
});
|
||||||
|
setKanjiList([...kanjiList, ...result.kanji]);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -60,4 +61,4 @@ export function Component() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.displayName = "KanjiPane";
|
Component.displayName = "KanjiPane";
|
||||||
|
|
|
@ -18,5 +18,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-box {
|
.input-box {
|
||||||
text-align: center;
|
}
|
||||||
|
|
||||||
|
.incorrect {
|
||||||
|
background-color: rgb(255, 202, 202) !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,38 +4,20 @@ import {
|
||||||
Input,
|
Input,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
InputLeftElement,
|
InputLeftElement,
|
||||||
InputRightElement,
|
|
||||||
Progress,
|
Progress,
|
||||||
Spinner,
|
Spinner,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import styles from "./SrsReviewPane.module.scss";
|
import styles from "./SrsReviewPane.module.scss";
|
||||||
import { useEffect, useState } from "react";
|
import { ChangeEvent, FormEvent, useEffect, useState } from "react";
|
||||||
import { invoke } from "@tauri-apps/api/tauri";
|
import { invoke } from "@tauri-apps/api/tauri";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { ArrowBackIcon, CheckIcon } from "@chakra-ui/icons";
|
import { ArrowBackIcon } from "@chakra-ui/icons";
|
||||||
import { FormEvent } from "react";
|
|
||||||
import ConfirmQuitModal from "../components/utils/ConfirmQuitModal";
|
import ConfirmQuitModal from "../components/utils/ConfirmQuitModal";
|
||||||
import * as _ from "lodash-es";
|
import * as _ from "lodash-es";
|
||||||
import InputBox from "../components/utils/InputBox";
|
import { romajiToKana } from "../lib/kanaHelper";
|
||||||
|
import { ReviewItem, ReviewItemType, SrsEntry } from "../types/Srs";
|
||||||
export interface SrsEntry {
|
import classNames from "classnames";
|
||||||
associated_kanji: string;
|
|
||||||
current_grade: number;
|
|
||||||
meanings: string[];
|
|
||||||
readings: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ReviewItemType {
|
|
||||||
MEANING = "MEANING",
|
|
||||||
READING = "READING",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReviewItem {
|
|
||||||
type: ReviewItemType;
|
|
||||||
challenge: string;
|
|
||||||
possibleAnswers: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const batchSize = 10;
|
const batchSize = 10;
|
||||||
|
|
||||||
|
@ -58,6 +40,7 @@ export function Component() {
|
||||||
const [anyProgress, setAnyProgress] = useState(false);
|
const [anyProgress, setAnyProgress] = useState(false);
|
||||||
const [startingSize, setStartingSize] = useState<number | null>(null);
|
const [startingSize, setStartingSize] = useState<number | null>(null);
|
||||||
const [currentAnswer, setCurrentAnswer] = useState("");
|
const [currentAnswer, setCurrentAnswer] = useState("");
|
||||||
|
const [isIncorrect, setIsIncorrect] = useState(false);
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
@ -65,7 +48,6 @@ export function Component() {
|
||||||
if (!reviewQueue) {
|
if (!reviewQueue) {
|
||||||
invoke<SrsEntry[]>("generate_review_batch")
|
invoke<SrsEntry[]>("generate_review_batch")
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
// setReviewBatch(result);
|
|
||||||
const newReviews: ReviewItem[] = result.flatMap((srsEntry) => [
|
const newReviews: ReviewItem[] = result.flatMap((srsEntry) => [
|
||||||
{
|
{
|
||||||
type: ReviewItemType.MEANING,
|
type: ReviewItemType.MEANING,
|
||||||
|
@ -89,49 +71,58 @@ export function Component() {
|
||||||
}
|
}
|
||||||
}, [reviewQueue]);
|
}, [reviewQueue]);
|
||||||
|
|
||||||
|
if (!reviewQueue) return <Spinner />;
|
||||||
|
if (reviewQueue.length == 0) return <Done />;
|
||||||
|
const nextItem = reviewQueue[0];
|
||||||
|
const possibleAnswers = new Set(nextItem.possibleAnswers);
|
||||||
|
|
||||||
const formSubmit = (evt: FormEvent) => {
|
const formSubmit = (evt: FormEvent) => {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
if (!reviewQueue) return;
|
if (!reviewQueue) return;
|
||||||
|
|
||||||
// Check the answer
|
// Check the answer
|
||||||
|
if (!possibleAnswers.has(currentAnswer)) {
|
||||||
|
setIsIncorrect(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set up for next question!
|
// Set up for next question!
|
||||||
setAnyProgress(true);
|
setAnyProgress(true);
|
||||||
|
setIsIncorrect(false);
|
||||||
setCurrentAnswer("");
|
setCurrentAnswer("");
|
||||||
const [_, ...rest] = reviewQueue;
|
const [_, ...rest] = reviewQueue;
|
||||||
setReviewQueue(rest);
|
setReviewQueue(rest);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!reviewQueue) return <Spinner />;
|
|
||||||
if (reviewQueue.length == 0) return <Done />;
|
|
||||||
const nextItem = reviewQueue[0];
|
|
||||||
|
|
||||||
const inputBox = (kanaInput: boolean) => {
|
const inputBox = (kanaInput: boolean) => {
|
||||||
|
const onChange = (evt: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
let newValue = evt.target.value;
|
||||||
|
if (kanaInput) newValue = romajiToKana(newValue) ?? newValue;
|
||||||
|
|
||||||
|
setCurrentAnswer(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const className = classNames(styles["input-box"], isIncorrect && styles["incorrect"]);
|
||||||
|
const placeholder = isIncorrect ? "Wrong! Try again..." : "Enter your answer...";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<InputLeftElement>{kanaInput ? "あ" : "A"}</InputLeftElement>
|
<InputLeftElement>{kanaInput ? "あ" : "A"}</InputLeftElement>
|
||||||
|
|
||||||
<InputBox
|
<Input
|
||||||
kanaInput={kanaInput}
|
|
||||||
value={currentAnswer}
|
value={currentAnswer}
|
||||||
setValue={setCurrentAnswer}
|
onChange={onChange}
|
||||||
autoFocus
|
autoFocus
|
||||||
className={styles["input-box"]}
|
className={className}
|
||||||
placeholder="Enter your answer..."
|
placeholder={placeholder}
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
backgroundColor={"white"}
|
backgroundColor={"white"}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<InputRightElement>
|
|
||||||
<CheckIcon color="green.500" />
|
|
||||||
</InputRightElement>
|
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderInside = () => {
|
const renderInside = () => {
|
||||||
console.log("next item", nextItem);
|
|
||||||
|
|
||||||
const kanaInput = nextItem.type == ReviewItemType.READING;
|
const kanaInput = nextItem.type == ReviewItemType.READING;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -12,6 +12,7 @@ export interface KanjiMeaning {
|
||||||
|
|
||||||
export interface KanjiSrsInfo {
|
export interface KanjiSrsInfo {
|
||||||
id: number;
|
id: number;
|
||||||
|
current_grade: number;
|
||||||
next_answer_date: number;
|
next_answer_date: number;
|
||||||
associated_kanji: string;
|
associated_kanji: string;
|
||||||
}
|
}
|
||||||
|
|
17
src/types/Srs.ts
Normal file
17
src/types/Srs.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
export interface SrsEntry {
|
||||||
|
associated_kanji: string;
|
||||||
|
current_grade: number;
|
||||||
|
meanings: string[];
|
||||||
|
readings: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ReviewItemType {
|
||||||
|
MEANING = "MEANING",
|
||||||
|
READING = "READING",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReviewItem {
|
||||||
|
type: ReviewItemType;
|
||||||
|
challenge: string;
|
||||||
|
possibleAnswers: string[];
|
||||||
|
}
|
Loading…
Reference in a new issue