From 550b5743f68b3e32d7dca4368dd9e13a3089a3f2 Mon Sep 17 00:00:00 2001 From: TU Date: Mon, 20 Jul 2026 11:45:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=A8=E8=AF=8D=E6=8B=BC?= =?UTF-8?q?=E6=8E=A5=E5=AD=A6=E4=B9=A0=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 整合动词拼接沙盒,并扩充常见复合动词词库,方便在歌词学习之外进行动词组合练习。 Co-authored-by: Cursor --- src/App.tsx | 45 +- src/components/AppNav.tsx | 25 +- src/components/CompoundVerbLab.tsx | 450 ++++++ src/components/LineItem.tsx | 4 +- src/components/Sidebar.tsx | 40 +- src/components/Toolbar.tsx | 22 +- src/components/VocabCards.tsx | 116 +- src/features/compoundVerbs/types.ts | 48 + src/features/compoundVerbs/verbsData.ts | 1662 +++++++++++++++++++++++ 9 files changed, 2292 insertions(+), 120 deletions(-) create mode 100644 src/components/CompoundVerbLab.tsx create mode 100644 src/features/compoundVerbs/types.ts create mode 100644 src/features/compoundVerbs/verbsData.ts diff --git a/src/App.tsx b/src/App.tsx index 70e7b9f..d557233 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,6 +10,7 @@ import { LineItem } from './components/LineItem'; import { Sidebar, SavedDocumentNote } from './components/Sidebar'; import { AppNav, AppView } from './components/AppNav'; import { VocabCards } from './components/VocabCards'; +import { CompoundVerbLab } from './components/CompoundVerbLab'; import { adjustFuriganaItemsForTextChange, normalizeLine, normalizeLines } from './utils'; import { apiUrl } from './api'; import { Check, Copy, Plus, X } from 'lucide-react'; @@ -980,7 +981,7 @@ export default function App() { {saveNotice && (
{activeView === 'lyrics' && showSavedArea && ( -
-
+
+
{serverSaveFiles.length > 0 ? (
{serverSaveFiles.map((file) => ( @@ -1016,7 +1017,7 @@ export default function App() { key={file.name} type="button" onClick={() => handleLoadServerSave(file)} - className="w-full text-left bg-white hover:bg-[#FAF9F6] active:bg-[#E8E4DE]/30 border border-[#E8E4DE]/70 hover:border-[#8B7E74]/40 rounded-lg px-3 py-2.5 transition cursor-pointer" + className="w-full text-left bg-white hover:bg-[#FAF9F6] active:bg-[#E8E4DE]/30 border-b border-[#E8E4DE]/70 px-3 py-2 transition cursor-pointer last:border-b-0" >
{file.title}
@@ -1025,7 +1026,7 @@ export default function App() { ))}
) : ( -
+
还没有保存的歌词
)} @@ -1036,9 +1037,9 @@ export default function App() { {activeView === 'lyrics' ? (
{/* LEFT COMPARTMENT: The writing sheet */} -
+
{showImportArea && ( -
+

粘贴整段日语文本后,系统会按换行切成写字板的每一行;也支持类似 - + 日本語{にほんご} 的注音格式。 @@ -1070,7 +1071,7 @@ export default function App() { value={importText} onChange={(e) => setImportText(e.target.value)} placeholder="在此粘贴整段文本,每一行会变成写字板的一行。" - className="w-full text-xs font-mono bg-[#FAF9F6] border border-[#E8E4DE] rounded-lg p-3 focus:outline-none focus:ring-1 focus:ring-[#8B7E74] text-[#2D2926] placeholder-[#A69F92]/60 resize-y" + className="w-full text-xs font-mono bg-[#FAF9F6] border border-[#E8E4DE] p-2.5 focus:outline-none focus:ring-1 focus:ring-[#8B7E74] text-[#2D2926] placeholder-[#A69F92]/60 resize-y" />

@@ -1102,13 +1103,13 @@ export default function App() { setImportText(''); setShowImportArea(false); }} - className="px-3 py-1.5 bg-white border border-[#E8E4DE] hover:bg-[#FAF9F6] text-[#A69F92] hover:text-[#2D2926] font-semibold rounded-lg transition" + className="px-3 py-1.5 bg-white border border-[#E8E4DE] hover:bg-[#FAF9F6] text-[#A69F92] hover:text-[#2D2926] font-semibold transition" > 取消
- ) : ( + ) : activeView === 'vocab' ? ( + ) : ( + )}
{/* Floating Sticky Drawer for Mobile / Tablet screens which normally hides the Sidebar */} {activeView === 'lyrics' && currentSelection && ( -
+
@@ -1251,7 +1254,7 @@ export default function App() { showTransientSaveNotice('复制失败', 'error'); } }} - className="shrink-0 flex items-center gap-1 rounded-md border border-[#E8E4DE] bg-white px-2 py-1 text-[11px] font-semibold text-[#8B7E74] hover:bg-[#FAF9F6] active:bg-[#E8E4DE]/40" + className="shrink-0 flex items-center gap-1 border border-[#E8E4DE] bg-white px-2 py-1 text-[11px] font-semibold text-[#8B7E74] hover:bg-[#FAF9F6] active:bg-[#E8E4DE]/40" title="复制选中文本" > @@ -1289,7 +1292,7 @@ export default function App() { rows={4} id="comment-textarea-mobile-existing" defaultValue={mobileSelectedNote.comment} - className="w-full text-sm bg-white border border-[#E8E4DE] rounded p-2 focus:outline-none focus:ring-1 focus:ring-[#8B7E74] text-[#2D2926] leading-relaxed" + className="w-full text-sm bg-white border border-[#E8E4DE] p-2 focus:outline-none focus:ring-1 focus:ring-[#8B7E74] text-[#2D2926] leading-relaxed" /> @@ -1341,7 +1344,7 @@ export default function App() { rows={3} id="comment-textarea-mobile" placeholder="在此为选中字词记录您的日语随笔、语法释义..." - className="w-full text-xs bg-white border border-[#E8E4DE] rounded p-2 focus:outline-none focus:ring-1 focus:ring-[#8B7E74] mb-2 text-[#2D2926]" + className="w-full text-xs bg-white border border-[#E8E4DE] p-2 focus:outline-none focus:ring-1 focus:ring-[#8B7E74] mb-2 text-[#2D2926]" /> diff --git a/src/components/AppNav.tsx b/src/components/AppNav.tsx index f0f8d14..7803dfd 100644 --- a/src/components/AppNav.tsx +++ b/src/components/AppNav.tsx @@ -4,9 +4,9 @@ */ import React from 'react'; -import { BookOpen, Layers3 } from 'lucide-react'; +import { BookOpen, GitMerge, Layers3 } from 'lucide-react'; -export type AppView = 'lyrics' | 'vocab'; +export type AppView = 'lyrics' | 'vocab' | 'compound'; interface AppNavProps { activeView: AppView; @@ -16,12 +16,13 @@ interface AppNavProps { const NAV_ITEMS = [ { id: 'lyrics' as const, label: '歌词', icon: BookOpen }, { id: 'vocab' as const, label: '单词卡片', icon: Layers3 }, + { id: 'compound' as const, label: '动词拼接', icon: GitMerge }, ]; export const AppNav: React.FC = ({ activeView, onChange }) => { return ( <> -