From a2e579cb7b31dcab320076d632dcc3f0161adb50 Mon Sep 17 00:00:00 2001 From: goddonebianu Date: Thu, 20 Nov 2025 10:40:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E4=B9=B1=E5=BA=8F=E8=AE=B0?= =?UTF-8?q?=E5=BF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- messages/en-US.json | 30 +------------ messages/zh-CN.json | 26 +---------- src/app/(features)/memorize/Memorize.tsx | 55 ++++++++++++++++++------ 3 files changed, 46 insertions(+), 65 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index 2043f58..7518dd8 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -83,48 +83,22 @@ "githubLogin": "GitHub Login" }, "memorize": { - "choose": { - "back": "Back", - "choose": "Choose" - }, - "edit": { - "back": "Back", - "save": "Save Word Pairs", - "locale1": "Locale 1", - "locale2": "Locale 2" - }, "folder_selector": { "selectFolder": "Select a folder", "noFolders": "No folders found", "folderInfo": "{id}. {name} ({count})" }, - "main": { - "title": "Memorize", - "locale1": "Your selected locale 1 is {locale}", - "locale2": "Your selected locale 2 is {locale}", - "total": "There are {total} word pairs in total", - "start": "Start", - "import": "Import", - "export": "Export", - "edit": "Edit" - }, "memorize": { "showAnswer": "Show Answer", "next": "Next", "reverse": "Reverse", "dictation": "Dictation", "noTextPairs": "No text pairs available", - "progress": "{current}/{total}" + "progress": "{current}/{total}", + "disorder": "Disorder" }, "page": { "unauthorized": "You are not authorized to access this folder" - }, - "start": { - "show": "Show", - "reverse": "Reverse", - "dictation": "Dictation", - "back": "Back", - "next": "Next" } }, "navbar": { diff --git a/messages/zh-CN.json b/messages/zh-CN.json index a79130d..2675d9f 100644 --- a/messages/zh-CN.json +++ b/messages/zh-CN.json @@ -87,44 +87,22 @@ "back": "返回", "choose": "选择" }, - "edit": { - "back": "返回", - "save": "保存单词对", - "locale1": "区域1", - "locale2": "区域2" - }, "folder_selector": { "selectFolder": "选择文件夹", "noFolders": "未找到文件夹", "folderInfo": "{id}. {name} ({count})" }, - "main": { - "title": "记忆", - "locale1": "您选择的区域一是{locale}", - "locale2": "您选择的区域二是{locale}", - "total": "总计有{total}个单词对", - "start": "开始", - "import": "导入", - "export": "导出", - "edit": "编辑" - }, "memorize": { "showAnswer": "显示答案", "next": "下一个", "reverse": "反向", "dictation": "听写", "noTextPairs": "没有可用的文本对", - "progress": "{current}/{total}" + "progress": "{current}/{total}", + "disorder": "乱序" }, "page": { "unauthorized": "您无权访问该文件夹" - }, - "start": { - "show": "显示", - "reverse": "反向", - "dictation": "听写", - "back": "返回", - "next": "下个" } }, "navbar": { diff --git a/src/app/(features)/memorize/Memorize.tsx b/src/app/(features)/memorize/Memorize.tsx index 52a805e..c746d4e 100644 --- a/src/app/(features)/memorize/Memorize.tsx +++ b/src/app/(features)/memorize/Memorize.tsx @@ -3,7 +3,7 @@ import { Center } from "@/components/Center"; import { text_pair } from "../../../../generated/prisma/browser"; import Container from "@/components/cards/Container"; -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import LightButton from "@/components/buttons/LightButton"; import { useAudioPlayer } from "@/hooks/useAudioPlayer"; import { getTTSAudioUrl } from "@/lib/browser/tts"; @@ -18,18 +18,37 @@ const Memorize: React.FC = ({ textPairs }) => { const t = useTranslations("memorize.memorize"); const [reverse, setReverse] = useState(false); const [dictation, setDictation] = useState(false); + const [disorder, setDisorder] = useState(false); const [index, setIndex] = useState(0); const [show, setShow] = useState<"question" | "answer">("question"); const { load, play } = useAudioPlayer(); + const [disorderedTextPairs, setDisorderedTextPairs] = useState( + [], + ); + + useEffect(() => { + setDisorderedTextPairs(textPairs.toSorted(() => Math.random() - 0.5)); + }, [textPairs]); + + const getTextPairs = () => { + if (disorder) { + return disorderedTextPairs; + } + return textPairs.toSorted((a, b) => a.id - b.id); + }; + return (
- {(textPairs.length > 0 && ( + {(getTextPairs().length > 0 && ( <>
- {t("progress", { current: index + 1, total: textPairs.length })} + {t("progress", { + current: index + 1, + total: getTextPairs().length, + })}
{dictation ? ( show === "question" ? ( @@ -38,26 +57,28 @@ const Memorize: React.FC = ({ textPairs }) => { <>
{reverse - ? textPairs[index].text2 - : textPairs[index].text1} + ? getTextPairs()[index].text2 + : getTextPairs()[index].text1}
{reverse - ? textPairs[index].text1 - : textPairs[index].text2} + ? getTextPairs()[index].text1 + : getTextPairs()[index].text2}
) ) : ( <>
- {reverse ? textPairs[index].text2 : textPairs[index].text1} + {reverse + ? getTextPairs()[index].text2 + : getTextPairs()[index].text1}
{show === "answer" ? reverse - ? textPairs[index].text1 - : textPairs[index].text2 + ? getTextPairs()[index].text1 + : getTextPairs()[index].text2 : ""}
@@ -68,15 +89,15 @@ const Memorize: React.FC = ({ textPairs }) => { className="w-32" onClick={async () => { if (show === "answer") { - const newIndex = (index + 1) % textPairs.length; + const newIndex = (index + 1) % getTextPairs().length; setIndex(newIndex); if (dictation) getTTSAudioUrl( - textPairs[newIndex][reverse ? "text2" : "text1"], + getTextPairs()[newIndex][reverse ? "text2" : "text1"], VOICES.find( (v) => v.locale === - textPairs[newIndex][ + getTextPairs()[newIndex][ reverse ? "locale2" : "locale1" ], )!.short_name, @@ -106,6 +127,14 @@ const Memorize: React.FC = ({ textPairs }) => { > {t("dictation")} + { + setDisorder(!disorder); + }} + selected={disorder} + > + {t("disorder")} +
)) ||

{t("noTextPairs")}

}