From 4829ab953107d451969133ebb165eb890c1dfe10 Mon Sep 17 00:00:00 2001 From: goddonebianu Date: Thu, 9 Oct 2025 11:23:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AE=B0=E5=BF=86=E5=AD=97?= =?UTF-8?q?=E6=AF=8D=E8=A1=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/alphabets/english.json | 132 +++++ public/alphabets/esperanto.json | 142 +++++ public/alphabets/japanese.json | 554 ++++++++++++++++++ public/alphabets/uyghur.json | 162 +++++ public/changelog.txt | 3 +- ...24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg | 1 + ...24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg | 1 + ...24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg | 1 + src/app/alphabet/MemoryCard.tsx | 46 ++ src/app/alphabet/page.tsx | 70 +++ src/app/page.tsx | 5 + src/app/word-board/WordBoard.tsx | 2 +- src/app/word-board/page.tsx | 2 +- src/config/images.ts | 5 +- src/interfaces.ts | 13 + src/interfaces/Word.ts | 5 - 16 files changed, 1135 insertions(+), 9 deletions(-) create mode 100644 public/alphabets/english.json create mode 100644 public/alphabets/esperanto.json create mode 100644 public/alphabets/japanese.json create mode 100644 public/alphabets/uyghur.json create mode 100644 public/images/close_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg create mode 100644 public/images/more_horiz_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg create mode 100644 public/images/refresh_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg create mode 100644 src/app/alphabet/MemoryCard.tsx create mode 100644 src/app/alphabet/page.tsx create mode 100644 src/interfaces.ts delete mode 100644 src/interfaces/Word.ts diff --git a/public/alphabets/english.json b/public/alphabets/english.json new file mode 100644 index 0000000..4c069e9 --- /dev/null +++ b/public/alphabets/english.json @@ -0,0 +1,132 @@ +[ + { + "letter": "a", + "letter_name_ipa": "[eɪ]", + "letter_sound_ipa": "[æ], [eɪ], [ɑː], [ə]" + }, + { + "letter": "b", + "letter_name_ipa": "[biː]", + "letter_sound_ipa": "[b]" + }, + { + "letter": "c", + "letter_name_ipa": "[siː]", + "letter_sound_ipa": "[k], [s]" + }, + { + "letter": "d", + "letter_name_ipa": "[diː]", + "letter_sound_ipa": "[d]" + }, + { + "letter": "e", + "letter_name_ipa": "[iː]", + "letter_sound_ipa": "[ɛ], [iː], [ə]" + }, + { + "letter": "f", + "letter_name_ipa": "[ɛf]", + "letter_sound_ipa": "[f]" + }, + { + "letter": "g", + "letter_name_ipa": "[dʒiː]", + "letter_sound_ipa": "[ɡ], [dʒ]" + }, + { + "letter": "h", + "letter_name_ipa": "[eɪtʃ]", + "letter_sound_ipa": "[h]" + }, + { + "letter": "i", + "letter_name_ipa": "[aɪ]", + "letter_sound_ipa": "[ɪ], [aɪ]" + }, + { + "letter": "j", + "letter_name_ipa": "[dʒeɪ]", + "letter_sound_ipa": "[dʒ]" + }, + { + "letter": "k", + "letter_name_ipa": "[keɪ]", + "letter_sound_ipa": "[k]" + }, + { + "letter": "l", + "letter_name_ipa": "[ɛl]", + "letter_sound_ipa": "[l]" + }, + { + "letter": "m", + "letter_name_ipa": "[ɛm]", + "letter_sound_ipa": "[m]" + }, + { + "letter": "n", + "letter_name_ipa": "[ɛn]", + "letter_sound_ipa": "[n]" + }, + { + "letter": "o", + "letter_name_ipa": "[oʊ]", + "letter_sound_ipa": "[ɒ], [oʊ], [ʌ]" + }, + { + "letter": "p", + "letter_name_ipa": "[piː]", + "letter_sound_ipa": "[p]" + }, + { + "letter": "q", + "letter_name_ipa": "[kjuː]", + "letter_sound_ipa": "[k]" + }, + { + "letter": "r", + "letter_name_ipa": "[ɑːr]", + "letter_sound_ipa": "[r]" + }, + { + "letter": "s", + "letter_name_ipa": "[ɛs]", + "letter_sound_ipa": "[s], [z]" + }, + { + "letter": "t", + "letter_name_ipa": "[tiː]", + "letter_sound_ipa": "[t]" + }, + { + "letter": "u", + "letter_name_ipa": "[juː]", + "letter_sound_ipa": "[ʌ], [juː], [ʊ]" + }, + { + "letter": "v", + "letter_name_ipa": "[viː]", + "letter_sound_ipa": "[v]" + }, + { + "letter": "w", + "letter_name_ipa": "[ˈdʌbəl.juː]", + "letter_sound_ipa": "[w]" + }, + { + "letter": "x", + "letter_name_ipa": "[ɛks]", + "letter_sound_ipa": "[ks], [ɡz]" + }, + { + "letter": "y", + "letter_name_ipa": "[waɪ]", + "letter_sound_ipa": "[j], [aɪ], [ɪ]" + }, + { + "letter": "z", + "letter_name_ipa": "[zɛd] or [ziː]", + "letter_sound_ipa": "[z]" + } +] \ No newline at end of file diff --git a/public/alphabets/esperanto.json b/public/alphabets/esperanto.json new file mode 100644 index 0000000..1ac28d6 --- /dev/null +++ b/public/alphabets/esperanto.json @@ -0,0 +1,142 @@ +[ + { + "letter": "a", + "letter_name_ipa": "[a]", + "letter_sound_ipa": "[a]" + }, + { + "letter": "b", + "letter_name_ipa": "[bo]", + "letter_sound_ipa": "[b]" + }, + { + "letter": "c", + "letter_name_ipa": "[t͡so]", + "letter_sound_ipa": "[t͡s]" + }, + { + "letter": "ĉ", + "letter_name_ipa": "[t͡ʃo]", + "letter_sound_ipa": "[t͡ʃ]" + }, + { + "letter": "d", + "letter_name_ipa": "[do]", + "letter_sound_ipa": "[d]" + }, + { + "letter": "e", + "letter_name_ipa": "[e]", + "letter_sound_ipa": "[e]" + }, + { + "letter": "f", + "letter_name_ipa": "[fo]", + "letter_sound_ipa": "[f]" + }, + { + "letter": "g", + "letter_name_ipa": "[ɡo]", + "letter_sound_ipa": "[ɡ]" + }, + { + "letter": "ĝ", + "letter_name_ipa": "[d͡ʒo]", + "letter_sound_ipa": "[d͡ʒ]" + }, + { + "letter": "h", + "letter_name_ipa": "[ho]", + "letter_sound_ipa": "[h]" + }, + { + "letter": "ĥ", + "letter_name_ipa": "[xo]", + "letter_sound_ipa": "[x]" + }, + { + "letter": "i", + "letter_name_ipa": "[i]", + "letter_sound_ipa": "[i]" + }, + { + "letter": "j", + "letter_name_ipa": "[jo]", + "letter_sound_ipa": "[j]" + }, + { + "letter": "ĵ", + "letter_name_ipa": "[ʒo]", + "letter_sound_ipa": "[ʒ]" + }, + { + "letter": "k", + "letter_name_ipa": "[ko]", + "letter_sound_ipa": "[k]" + }, + { + "letter": "l", + "letter_name_ipa": "[lo]", + "letter_sound_ipa": "[l]" + }, + { + "letter": "m", + "letter_name_ipa": "[mo]", + "letter_sound_ipa": "[m]" + }, + { + "letter": "n", + "letter_name_ipa": "[no]", + "letter_sound_ipa": "[n]" + }, + { + "letter": "o", + "letter_name_ipa": "[o]", + "letter_sound_ipa": "[o]" + }, + { + "letter": "p", + "letter_name_ipa": "[po]", + "letter_sound_ipa": "[p]" + }, + { + "letter": "r", + "letter_name_ipa": "[ro]", + "letter_sound_ipa": "[r]" + }, + { + "letter": "s", + "letter_name_ipa": "[so]", + "letter_sound_ipa": "[s]" + }, + { + "letter": "ŝ", + "letter_name_ipa": "[ʃo]", + "letter_sound_ipa": "[ʃ]" + }, + { + "letter": "t", + "letter_name_ipa": "[to]", + "letter_sound_ipa": "[t]" + }, + { + "letter": "u", + "letter_name_ipa": "[u]", + "letter_sound_ipa": "[u]" + }, + { + "letter": "ŭ", + "letter_name_ipa": "[u̯o]", + "letter_sound_ipa": "[u̯]" + }, + { + "letter": "v", + "letter_name_ipa": "[vo]", + "letter_sound_ipa": "[v]" + }, + { + "letter": "z", + "letter_name_ipa": "[zo]", + "letter_sound_ipa": "[z]" + } +] \ No newline at end of file diff --git a/public/alphabets/japanese.json b/public/alphabets/japanese.json new file mode 100644 index 0000000..e273674 --- /dev/null +++ b/public/alphabets/japanese.json @@ -0,0 +1,554 @@ +[ + { + "letter": "あ", + "letter_name_ipa": "[a]", + "letter_sound_ipa": "[a]", + "roman_letter": "a" + }, + { + "letter": "ア", + "letter_name_ipa": "[a]", + "letter_sound_ipa": "[a]", + "roman_letter": "a" + }, + { + "letter": "い", + "letter_name_ipa": "[i]", + "letter_sound_ipa": "[i]", + "roman_letter": "i" + }, + { + "letter": "イ", + "letter_name_ipa": "[i]", + "letter_sound_ipa": "[i]", + "roman_letter": "i" + }, + { + "letter": "う", + "letter_name_ipa": "[ɯ]", + "letter_sound_ipa": "[ɯ]", + "roman_letter": "u" + }, + { + "letter": "ウ", + "letter_name_ipa": "[ɯ]", + "letter_sound_ipa": "[ɯ]", + "roman_letter": "u" + }, + { + "letter": "え", + "letter_name_ipa": "[e]", + "letter_sound_ipa": "[e]", + "roman_letter": "e" + }, + { + "letter": "エ", + "letter_name_ipa": "[e]", + "letter_sound_ipa": "[e]", + "roman_letter": "e" + }, + { + "letter": "お", + "letter_name_ipa": "[o]", + "letter_sound_ipa": "[o]", + "roman_letter": "o" + }, + { + "letter": "オ", + "letter_name_ipa": "[o]", + "letter_sound_ipa": "[o]", + "roman_letter": "o" + }, + { + "letter": "か", + "letter_name_ipa": "[ka]", + "letter_sound_ipa": "[ka]", + "roman_letter": "ka" + }, + { + "letter": "カ", + "letter_name_ipa": "[ka]", + "letter_sound_ipa": "[ka]", + "roman_letter": "ka" + }, + { + "letter": "き", + "letter_name_ipa": "[ki]", + "letter_sound_ipa": "[ki]", + "roman_letter": "ki" + }, + { + "letter": "キ", + "letter_name_ipa": "[ki]", + "letter_sound_ipa": "[ki]", + "roman_letter": "ki" + }, + { + "letter": "く", + "letter_name_ipa": "[kɯ]", + "letter_sound_ipa": "[kɯ]", + "roman_letter": "ku" + }, + { + "letter": "ク", + "letter_name_ipa": "[kɯ]", + "letter_sound_ipa": "[kɯ]", + "roman_letter": "ku" + }, + { + "letter": "け", + "letter_name_ipa": "[ke]", + "letter_sound_ipa": "[ke]", + "roman_letter": "ke" + }, + { + "letter": "ケ", + "letter_name_ipa": "[ke]", + "letter_sound_ipa": "[ke]", + "roman_letter": "ke" + }, + { + "letter": "こ", + "letter_name_ipa": "[ko]", + "letter_sound_ipa": "[ko]", + "roman_letter": "ko" + }, + { + "letter": "コ", + "letter_name_ipa": "[ko]", + "letter_sound_ipa": "[ko]", + "roman_letter": "ko" + }, + { + "letter": "さ", + "letter_name_ipa": "[sa]", + "letter_sound_ipa": "[sa]", + "roman_letter": "sa" + }, + { + "letter": "サ", + "letter_name_ipa": "[sa]", + "letter_sound_ipa": "[sa]", + "roman_letter": "sa" + }, + { + "letter": "し", + "letter_name_ipa": "[ɕi]", + "letter_sound_ipa": "[ɕi]", + "roman_letter": "shi" + }, + { + "letter": "シ", + "letter_name_ipa": "[ɕi]", + "letter_sound_ipa": "[ɕi]", + "roman_letter": "shi" + }, + { + "letter": "す", + "letter_name_ipa": "[sɯ]", + "letter_sound_ipa": "[sɯ]", + "roman_letter": "su" + }, + { + "letter": "ス", + "letter_name_ipa": "[sɯ]", + "letter_sound_ipa": "[sɯ]", + "roman_letter": "su" + }, + { + "letter": "せ", + "letter_name_ipa": "[se]", + "letter_sound_ipa": "[se]", + "roman_letter": "se" + }, + { + "letter": "セ", + "letter_name_ipa": "[se]", + "letter_sound_ipa": "[se]", + "roman_letter": "se" + }, + { + "letter": "そ", + "letter_name_ipa": "[so]", + "letter_sound_ipa": "[so]", + "roman_letter": "so" + }, + { + "letter": "ソ", + "letter_name_ipa": "[so]", + "letter_sound_ipa": "[so]", + "roman_letter": "so" + }, + { + "letter": "た", + "letter_name_ipa": "[ta]", + "letter_sound_ipa": "[ta]", + "roman_letter": "ta" + }, + { + "letter": "タ", + "letter_name_ipa": "[ta]", + "letter_sound_ipa": "[ta]", + "roman_letter": "ta" + }, + { + "letter": "ち", + "letter_name_ipa": "[tɕi]", + "letter_sound_ipa": "[tɕi]", + "roman_letter": "chi" + }, + { + "letter": "チ", + "letter_name_ipa": "[tɕi]", + "letter_sound_ipa": "[tɕi]", + "roman_letter": "chi" + }, + { + "letter": "つ", + "letter_name_ipa": "[t͡sɯ]", + "letter_sound_ipa": "[t͡sɯ]", + "roman_letter": "tsu" + }, + { + "letter": "ツ", + "letter_name_ipa": "[t͡sɯ]", + "letter_sound_ipa": "[t͡sɯ]", + "roman_letter": "tsu" + }, + { + "letter": "て", + "letter_name_ipa": "[te]", + "letter_sound_ipa": "[te]", + "roman_letter": "te" + }, + { + "letter": "テ", + "letter_name_ipa": "[te]", + "letter_sound_ipa": "[te]", + "roman_letter": "te" + }, + { + "letter": "と", + "letter_name_ipa": "[to]", + "letter_sound_ipa": "[to]", + "roman_letter": "to" + }, + { + "letter": "ト", + "letter_name_ipa": "[to]", + "letter_sound_ipa": "[to]", + "roman_letter": "to" + }, + { + "letter": "な", + "letter_name_ipa": "[na]", + "letter_sound_ipa": "[na]", + "roman_letter": "na" + }, + { + "letter": "ナ", + "letter_name_ipa": "[na]", + "letter_sound_ipa": "[na]", + "roman_letter": "na" + }, + { + "letter": "に", + "letter_name_ipa": "[ni]", + "letter_sound_ipa": "[ni]", + "roman_letter": "ni" + }, + { + "letter": "ニ", + "letter_name_ipa": "[ni]", + "letter_sound_ipa": "[ni]", + "roman_letter": "ni" + }, + { + "letter": "ぬ", + "letter_name_ipa": "[nɯ]", + "letter_sound_ipa": "[nɯ]", + "roman_letter": "nu" + }, + { + "letter": "ヌ", + "letter_name_ipa": "[nɯ]", + "letter_sound_ipa": "[nɯ]", + "roman_letter": "nu" + }, + { + "letter": "ね", + "letter_name_ipa": "[ne]", + "letter_sound_ipa": "[ne]", + "roman_letter": "ne" + }, + { + "letter": "ネ", + "letter_name_ipa": "[ne]", + "letter_sound_ipa": "[ne]", + "roman_letter": "ne" + }, + { + "letter": "の", + "letter_name_ipa": "[no]", + "letter_sound_ipa": "[no]", + "roman_letter": "no" + }, + { + "letter": "ノ", + "letter_name_ipa": "[no]", + "letter_sound_ipa": "[no]", + "roman_letter": "no" + }, + { + "letter": "は", + "letter_name_ipa": "[ha]", + "letter_sound_ipa": "[ha]", + "roman_letter": "ha" + }, + { + "letter": "ハ", + "letter_name_ipa": "[ha]", + "letter_sound_ipa": "[ha]", + "roman_letter": "ha" + }, + { + "letter": "ひ", + "letter_name_ipa": "[çi]", + "letter_sound_ipa": "[çi]", + "roman_letter": "hi" + }, + { + "letter": "ヒ", + "letter_name_ipa": "[çi]", + "letter_sound_ipa": "[çi]", + "roman_letter": "hi" + }, + { + "letter": "ふ", + "letter_name_ipa": "[ɸɯ]", + "letter_sound_ipa": "[ɸɯ]", + "roman_letter": "fu" + }, + { + "letter": "フ", + "letter_name_ipa": "[ɸɯ]", + "letter_sound_ipa": "[ɸɯ]", + "roman_letter": "fu" + }, + { + "letter": "へ", + "letter_name_ipa": "[he]", + "letter_sound_ipa": "[he]", + "roman_letter": "he" + }, + { + "letter": "ヘ", + "letter_name_ipa": "[he]", + "letter_sound_ipa": "[he]", + "roman_letter": "he" + }, + { + "letter": "ほ", + "letter_name_ipa": "[ho]", + "letter_sound_ipa": "[ho]", + "roman_letter": "ho" + }, + { + "letter": "ホ", + "letter_name_ipa": "[ho]", + "letter_sound_ipa": "[ho]", + "roman_letter": "ho" + }, + { + "letter": "ま", + "letter_name_ipa": "[ma]", + "letter_sound_ipa": "[ma]", + "roman_letter": "ma" + }, + { + "letter": "マ", + "letter_name_ipa": "[ma]", + "letter_sound_ipa": "[ma]", + "roman_letter": "ma" + }, + { + "letter": "み", + "letter_name_ipa": "[mi]", + "letter_sound_ipa": "[mi]", + "roman_letter": "mi" + }, + { + "letter": "ミ", + "letter_name_ipa": "[mi]", + "letter_sound_ipa": "[mi]", + "roman_letter": "mi" + }, + { + "letter": "む", + "letter_name_ipa": "[mɯ]", + "letter_sound_ipa": "[mɯ]", + "roman_letter": "mu" + }, + { + "letter": "ム", + "letter_name_ipa": "[mɯ]", + "letter_sound_ipa": "[mɯ]", + "roman_letter": "mu" + }, + { + "letter": "め", + "letter_name_ipa": "[me]", + "letter_sound_ipa": "[me]", + "roman_letter": "me" + }, + { + "letter": "メ", + "letter_name_ipa": "[me]", + "letter_sound_ipa": "[me]", + "roman_letter": "me" + }, + { + "letter": "も", + "letter_name_ipa": "[mo]", + "letter_sound_ipa": "[mo]", + "roman_letter": "mo" + }, + { + "letter": "モ", + "letter_name_ipa": "[mo]", + "letter_sound_ipa": "[mo]", + "roman_letter": "mo" + }, + { + "letter": "や", + "letter_name_ipa": "[ja]", + "letter_sound_ipa": "[ja]", + "roman_letter": "ya" + }, + { + "letter": "ヤ", + "letter_name_ipa": "[ja]", + "letter_sound_ipa": "[ja]", + "roman_letter": "ya" + }, + { + "letter": "ゆ", + "letter_name_ipa": "[jɯ]", + "letter_sound_ipa": "[jɯ]", + "roman_letter": "yu" + }, + { + "letter": "ユ", + "letter_name_ipa": "[jɯ]", + "letter_sound_ipa": "[jɯ]", + "roman_letter": "yu" + }, + { + "letter": "よ", + "letter_name_ipa": "[jo]", + "letter_sound_ipa": "[jo]", + "roman_letter": "yo" + }, + { + "letter": "ヨ", + "letter_name_ipa": "[jo]", + "letter_sound_ipa": "[jo]", + "roman_letter": "yo" + }, + { + "letter": "ら", + "letter_name_ipa": "[ɾa]", + "letter_sound_ipa": "[ɾa]", + "roman_letter": "ra" + }, + { + "letter": "ラ", + "letter_name_ipa": "[ɾa]", + "letter_sound_ipa": "[ɾa]", + "roman_letter": "ra" + }, + { + "letter": "り", + "letter_name_ipa": "[ɾi]", + "letter_sound_ipa": "[ɾi]", + "roman_letter": "ri" + }, + { + "letter": "リ", + "letter_name_ipa": "[ɾi]", + "letter_sound_ipa": "[ɾi]", + "roman_letter": "ri" + }, + { + "letter": "る", + "letter_name_ipa": "[ɾɯ]", + "letter_sound_ipa": "[ɾɯ]", + "roman_letter": "ru" + }, + { + "letter": "ル", + "letter_name_ipa": "[ɾɯ]", + "letter_sound_ipa": "[ɾɯ]", + "roman_letter": "ru" + }, + { + "letter": "れ", + "letter_name_ipa": "[ɾe]", + "letter_sound_ipa": "[ɾe]", + "roman_letter": "re" + }, + { + "letter": "レ", + "letter_name_ipa": "[ɾe]", + "letter_sound_ipa": "[ɾe]", + "roman_letter": "re" + }, + { + "letter": "ろ", + "letter_name_ipa": "[ɾo]", + "letter_sound_ipa": "[ɾo]", + "roman_letter": "ro" + }, + { + "letter": "ロ", + "letter_name_ipa": "[ɾo]", + "letter_sound_ipa": "[ɾo]", + "roman_letter": "ro" + }, + { + "letter": "わ", + "letter_name_ipa": "[wa]", + "letter_sound_ipa": "[wa]", + "roman_letter": "wa" + }, + { + "letter": "ワ", + "letter_name_ipa": "[wa]", + "letter_sound_ipa": "[wa]", + "roman_letter": "wa" + }, + { + "letter": "を", + "letter_name_ipa": "[o]", + "letter_sound_ipa": "[o]", + "roman_letter": "wo" + }, + { + "letter": "ヲ", + "letter_name_ipa": "[o]", + "letter_sound_ipa": "[o]", + "roman_letter": "wo" + }, + { + "letter": "ん", + "letter_name_ipa": "[n]", + "letter_sound_ipa": "[n], [m], [ŋ]", + "roman_letter": "n" + }, + { + "letter": "ン", + "letter_name_ipa": "[n]", + "letter_sound_ipa": "[n], [m], [ŋ]", + "roman_letter": "n" + } +] \ No newline at end of file diff --git a/public/alphabets/uyghur.json b/public/alphabets/uyghur.json new file mode 100644 index 0000000..e21334e --- /dev/null +++ b/public/alphabets/uyghur.json @@ -0,0 +1,162 @@ +[ + { + "letter": "ئا", + "letter_name_ipa": "[ʔɑ]", + "letter_sound_ipa": "[ɑ]" + }, + { + "letter": "ئە", + "letter_name_ipa": "[ʔæ]", + "letter_sound_ipa": "[æ]" + }, + { + "letter": "ب", + "letter_name_ipa": "[bɛ]", + "letter_sound_ipa": "[b]" + }, + { + "letter": "پ", + "letter_name_ipa": "[pɛ]", + "letter_sound_ipa": "[p]" + }, + { + "letter": "ت", + "letter_name_ipa": "[tɛ]", + "letter_sound_ipa": "[t]" + }, + { + "letter": "ج", + "letter_name_ipa": "[dʒɛ]", + "letter_sound_ipa": "[dʒ]" + }, + { + "letter": "چ", + "letter_name_ipa": "[tʃɛ]", + "letter_sound_ipa": "[tʃ]" + }, + { + "letter": "خ", + "letter_name_ipa": "[xɛ]", + "letter_sound_ipa": "[x]" + }, + { + "letter": "د", + "letter_name_ipa": "[dɛ]", + "letter_sound_ipa": "[d]" + }, + { + "letter": "ر", + "letter_name_ipa": "[rɛ]", + "letter_sound_ipa": "[r]" + }, + { + "letter": "ز", + "letter_name_ipa": "[zɛ]", + "letter_sound_ipa": "[z]" + }, + { + "letter": "ژ", + "letter_name_ipa": "[ʒɛ]", + "letter_sound_ipa": "[ʒ]" + }, + { + "letter": "س", + "letter_name_ipa": "[sɛ]", + "letter_sound_ipa": "[s]" + }, + { + "letter": "ش", + "letter_name_ipa": "[ʃɛ]", + "letter_sound_ipa": "[ʃ]" + }, + { + "letter": "غ", + "letter_name_ipa": "[ʁɛ]", + "letter_sound_ipa": "[ʁ]" + }, + { + "letter": "ف", + "letter_name_ipa": "[fɛ]", + "letter_sound_ipa": "[f]" + }, + { + "letter": "ق", + "letter_name_ipa": "[qɛ]", + "letter_sound_ipa": "[q]" + }, + { + "letter": "ك", + "letter_name_ipa": "[kɛ]", + "letter_sound_ipa": "[k]" + }, + { + "letter": "گ", + "letter_name_ipa": "[gɛ]", + "letter_sound_ipa": "[g]" + }, + { + "letter": "ڭ", + "letter_name_ipa": "[ŋɛ]", + "letter_sound_ipa": "[ŋ]" + }, + { + "letter": "ل", + "letter_name_ipa": "[lɛ]", + "letter_sound_ipa": "[l]" + }, + { + "letter": "م", + "letter_name_ipa": "[mɛ]", + "letter_sound_ipa": "[m]" + }, + { + "letter": "ن", + "letter_name_ipa": "[nɛ]", + "letter_sound_ipa": "[n]" + }, + { + "letter": "ھ", + "letter_name_ipa": "[hɛ]", + "letter_sound_ipa": "[h]" + }, + { + "letter": "ئو", + "letter_name_ipa": "[ʔo]", + "letter_sound_ipa": "[o]" + }, + { + "letter": "ئۇ", + "letter_name_ipa": "[ʔu]", + "letter_sound_ipa": "[u]" + }, + { + "letter": "ئۆ", + "letter_name_ipa": "[ʔø]", + "letter_sound_ipa": "[ø]" + }, + { + "letter": "ئۈ", + "letter_name_ipa": "[ʔy]", + "letter_sound_ipa": "[y]" + }, + { + "letter": "ۋ", + "letter_name_ipa": "[wɛ]", + "letter_sound_ipa": "[w], [v]" + }, + { + "letter": "ئې", + "letter_name_ipa": "[ʔe]", + "letter_sound_ipa": "[e]" + }, + { + "letter": "ئى", + "letter_name_ipa": "[ʔi]", + "letter_sound_ipa": "[i]" + }, + { + "letter": "ي", + "letter_name_ipa": "[jɛ]", + "letter_sound_ipa": "[j]" + } +] \ No newline at end of file diff --git a/public/changelog.txt b/public/changelog.txt index e9dfa72..9b019f1 100644 --- a/public/changelog.txt +++ b/public/changelog.txt @@ -1,4 +1,5 @@ -2025.10.08 加快了TTS的速度,将IPA生成设置为可选项 +2025.09.25 新增记忆字母表功能 +2025.10.08 加快了TTS的生成速度,将IPA生成设置为可选项 2025.10.07 新增文本朗读器,优化了视频播放器UI 2025.10.06 更新了主页面UI,移除IPA生成与文本朗读功能,新增全语言翻译器 2025.10.05 新增IPA生成与文本朗读功能 diff --git a/public/images/close_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg b/public/images/close_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..fbc8515 --- /dev/null +++ b/public/images/close_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/more_horiz_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg b/public/images/more_horiz_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..885b985 --- /dev/null +++ b/public/images/more_horiz_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/refresh_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg b/public/images/refresh_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..30298c2 --- /dev/null +++ b/public/images/refresh_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/alphabet/MemoryCard.tsx b/src/app/alphabet/MemoryCard.tsx new file mode 100644 index 0000000..9de12ff --- /dev/null +++ b/src/app/alphabet/MemoryCard.tsx @@ -0,0 +1,46 @@ +import Button from "@/components/Button"; +import IconClick from "@/components/IconClick"; +import IMAGES from "@/config/images"; +import { Letter, SupportedAlphabets } from "@/interfaces"; +import { Dispatch, SetStateAction, useRef, useState } from "react"; + +export default function MemoryCard( + { + alphabet, + language, + setChosenAlphabet + }: { + alphabet: Letter[], + language: string, + setChosenAlphabet: Dispatch> + } +) { + const [index, setIndex] = useState(Math.floor(Math.random() * alphabet.length)); + const [more, setMore] = useState(false); + const [ipaDisplay, setIPADisplay] = useState(true); + const [letterDisplay, setLetterDisplay] = useState(true); + const letter = alphabet[index]; + return ( +
+
+
+ setChosenAlphabet(null)}> +
+
+ {letterDisplay ? letter.letter : ''} + {ipaDisplay ? letter.letter_sound_ipa : ''} +
+
+ setIndex(Math.floor(Math.random() * alphabet.length))}> + setMore(!more)}> + { + more ? (<> + + + ) : (<>) + } +
+
+
+ ); +} \ No newline at end of file diff --git a/src/app/alphabet/page.tsx b/src/app/alphabet/page.tsx new file mode 100644 index 0000000..817bfa8 --- /dev/null +++ b/src/app/alphabet/page.tsx @@ -0,0 +1,70 @@ +'use client'; + +import Button from "@/components/Button"; +import { Letter, SupportedAlphabets } from "@/interfaces"; +import { useEffect, useState } from "react"; +import MemoryCard from "./MemoryCard"; + +export default function Home() { + const [chosenAlphabet, setChosenAlphabet] = useState(null); + const [alphabetData, setAlphabetData] = useState>({ + japanese: null, + english: null, + esperanto: null, + uyghur: null + }); + const [loadingState, setLoadingState] = useState<'idle' | 'loading' | 'success' | 'error'>('idle'); + + + useEffect(() => { + if (chosenAlphabet && !alphabetData[chosenAlphabet]) { + setLoadingState('loading'); + + fetch('/alphabets/' + chosenAlphabet + '.json') + .then(res => { + if (!res.ok) throw new Error('Network response was not ok'); + return res.json(); + }).then((obj) => { + setAlphabetData(prev => ({ ...prev, [chosenAlphabet]: obj as Letter[] })); + setLoadingState('success'); + }).catch(() => { + setLoadingState('error'); + }); + } + }, [chosenAlphabet, alphabetData]); + + useEffect(() => { + if (loadingState === 'error') { + const timer = setTimeout(() => { + setLoadingState('idle'); + setChosenAlphabet(null); + }, 2000); + return () => clearTimeout(timer); + } + }, [loadingState]); + + if (!chosenAlphabet) return ( +
+ 请选择您想学习的字符 +
+ + + + +
+
); + if (loadingState === 'loading') { + return '加载中...'; + } + if (loadingState === 'error') { + return '加载失败,请重试'; + } + if (loadingState === 'success' && alphabetData[chosenAlphabet]) { + return ( + ); + } + return null; +} \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx index bfe8e04..6f819bc 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -56,6 +56,11 @@ function LinkGrid() { name="逐句视频播放器" description="基于SRT字幕文件,逐句播放视频以模仿母语者的发音" color="#3c988d"> +