From d66fedcab79aeea335d91260dbfa2b537b3a46cf Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Tue, 5 May 2026 16:01:26 +0800 Subject: [PATCH] feat(reader): manage rules shortcut in proofread popup (#4062) --- .../public/locales/zh-CN/translation.json | 8 ++++---- .../public/locales/zh-TW/translation.json | 8 ++++---- .../components/ProofreadPopup.test.tsx | 19 +++++++++++++++++++ .../reader/components/annotator/Annotator.tsx | 5 +++++ .../components/annotator/ProofreadPopup.tsx | 18 ++++++++++++++++-- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 54b00833..0f8b2532 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -751,7 +751,7 @@ "Search in OPDS Catalog...": "在 OPDS 目录中搜索...", "Please log in to use advanced TTS features": "请登录以使用高级 TTS 功能", "Word limit of 30 words exceeded.": "已超过 30 个词的限制。", - "Proofread": "校对", + "Proofread": "文字校对", "Current selection": "当前选中内容", "All occurrences in this book": "本书中的所有出现位置", "All occurrences in your library": "整个书库中的所有出现位置", @@ -764,7 +764,7 @@ "Library": "书库", "Yes": "是", "No": "否", - "Proofread Replacement Rules": "校对替换规则", + "Proofread Replacement Rules": "文字校对替换规则", "Selected Text Rules": "选中文本规则", "No selected text replacement rules": "暂无选中文本的替换规则", "Book Specific Rules": "书籍范围规则", @@ -783,7 +783,7 @@ "Look up text in dictionary after selection": "在字典中查找选中文本", "Translate text after selection": "翻译选中文本", "Read text aloud after selection": "朗读选中文本", - "Proofread text after selection": "校对选中文本", + "Proofread text after selection": "文字校对选中文本", "{{activeCount}} active, {{pendingCount}} pending": "{{activeCount}} 进行中,{{pendingCount}} 等待中", "{{failedCount}} failed": "{{failedCount}} 失败", "Waiting...": "等待中...", @@ -1103,7 +1103,7 @@ "Translate Selection": "翻译选中内容", "Dictionary Lookup": "词典查询", "Read Aloud Selection": "朗读选中内容", - "Proofread Selection": "校对选中内容", + "Proofread Selection": "文字校对选中内容", "Open Settings": "打开设置", "Open Command Palette": "打开命令面板", "Show Keyboard Shortcuts": "显示键盘快捷键", diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 5cab799d..8cbed257 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -750,7 +750,7 @@ "Search in OPDS Catalog...": "在 OPDS 目錄中搜尋...", "Please log in to use advanced TTS features": "請登入以使用進階 TTS 功能", "Word limit of 30 words exceeded.": "已超過 30 個詞的限制。", - "Proofread": "校對", + "Proofread": "文字校對", "Current selection": "目前選取內容", "All occurrences in this book": "本書中的所有出現位置", "All occurrences in your library": "整個書庫中的所有出現位置", @@ -763,7 +763,7 @@ "Library": "書庫", "Yes": "是", "No": "否", - "Proofread Replacement Rules": "校對取代規則", + "Proofread Replacement Rules": "文字校對取代規則", "Selected Text Rules": "已選取文字規則", "No selected text replacement rules": "沒有已選取文字的取代規則", "Book Specific Rules": "書籍層級規則", @@ -782,7 +782,7 @@ "Look up text in dictionary after selection": "在字典中查找選取後的文字", "Translate text after selection": "翻譯選取後的文字", "Read text aloud after selection": "朗讀選取後的文字", - "Proofread text after selection": "校對選取後的文字", + "Proofread text after selection": "文字校對選取後的文字", "{{activeCount}} active, {{pendingCount}} pending": "{{activeCount}} 進行中,{{pendingCount}} 等待中", "{{failedCount}} failed": "{{failedCount}} 失敗", "Waiting...": "等待中...", @@ -1103,7 +1103,7 @@ "Translate Selection": "翻譯選取內容", "Dictionary Lookup": "字典查詢", "Read Aloud Selection": "朗讀選取內容", - "Proofread Selection": "校對選取內容", + "Proofread Selection": "文字校對選取內容", "Open Settings": "開啟設定", "Open Command Palette": "開啟指令面板", "Show Keyboard Shortcuts": "顯示鍵盤快捷鍵", diff --git a/apps/readest-app/src/__tests__/components/ProofreadPopup.test.tsx b/apps/readest-app/src/__tests__/components/ProofreadPopup.test.tsx index 5cd0414a..ff6e546c 100644 --- a/apps/readest-app/src/__tests__/components/ProofreadPopup.test.tsx +++ b/apps/readest-app/src/__tests__/components/ProofreadPopup.test.tsx @@ -233,4 +233,23 @@ describe('ProofreadPopup Component', () => { expect(mockOnClose).not.toHaveBeenCalled(); }); }); + + describe('Manage Replacement Rules Shortcut', () => { + it('should not render manage button when onManage is not provided', () => { + renderWithProviders(); + + expect(screen.queryByLabelText('Proofread Replacement Rules')).toBeNull(); + }); + + it('should render manage button and invoke onManage when provided', () => { + const mockOnManage = vi.fn(); + renderWithProviders(); + + const button = screen.getByLabelText('Proofread Replacement Rules'); + expect(button).toBeTruthy(); + + fireEvent.click(button); + expect(mockOnManage).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/apps/readest-app/src/app/reader/components/annotator/Annotator.tsx b/apps/readest-app/src/app/reader/components/annotator/Annotator.tsx index 96c15c8a..c51282c0 100644 --- a/apps/readest-app/src/app/reader/components/annotator/Annotator.tsx +++ b/apps/readest-app/src/app/reader/components/annotator/Annotator.tsx @@ -46,6 +46,7 @@ import DictionaryPopup from './DictionaryPopup'; import TranslatorPopup from './TranslatorPopup'; import useShortcuts from '@/hooks/useShortcuts'; import ProofreadPopup from './ProofreadPopup'; +import { setProofreadRulesVisibility } from '@/app/reader/components/ProofreadRules'; import ExportMarkdownDialog from './ExportMarkdownDialog'; const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => { @@ -1019,6 +1020,10 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => { popupWidth={proofreadPopupWidth} popupHeight={proofreadPopupHeight} onDismiss={handleDismissPopupAndSelection} + onManage={() => { + handleDismissPopupAndSelection(); + setProofreadRulesVisibility(true); + }} /> )} {editingAnnotation && editingAnnotation.color && selection && ( diff --git a/apps/readest-app/src/app/reader/components/annotator/ProofreadPopup.tsx b/apps/readest-app/src/app/reader/components/annotator/ProofreadPopup.tsx index f1792d25..a96342a7 100644 --- a/apps/readest-app/src/app/reader/components/annotator/ProofreadPopup.tsx +++ b/apps/readest-app/src/app/reader/components/annotator/ProofreadPopup.tsx @@ -1,5 +1,6 @@ import clsx from 'clsx'; import React, { useRef, useState } from 'react'; +import { RiListSettingsLine } from 'react-icons/ri'; import { useEnv } from '@/context/EnvContext'; import { useReaderStore } from '@/store/readerStore'; import { useTranslation } from '@/hooks/useTranslation'; @@ -21,6 +22,7 @@ interface ProofreadPopupProps { popupHeight: number; onConfirm?: (options: CreateProofreadRuleOptions) => void; onDismiss: () => void; + onManage?: () => void; } const ProofreadPopup: React.FC = ({ @@ -32,6 +34,7 @@ const ProofreadPopup: React.FC = ({ popupHeight, onConfirm, onDismiss, + onManage, }) => { const _ = useTranslation(); const { envConfig } = useEnv(); @@ -124,11 +127,22 @@ const ProofreadPopup: React.FC = ({ onDismiss={onDismiss} >
-
+
{_('Selected text:')} - + "{selection?.text || ''}" + {onManage && ( + + )}