Skip to content

Commit ee8e05c

Browse files
committed
feat: 优化校对功能并移除通知服务
refactor(ChapterNav): 添加隐藏已校对章节功能 refactor(useAICheck): 实现分批处理大章节文本 refactor(ProofreadPanel): 移除通知相关代码 chore: 更新版本号至0.8.6
1 parent 24f9064 commit ee8e05c

9 files changed

Lines changed: 222 additions & 268 deletions

File tree

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "proofreader"
3-
version = "0.8.5"
3+
version = "0.8.6"
44
edition = "2021"
55

66
[lib]

src-tauri/target/.rustc_info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"rustc_fingerprint":8645173116325193397,"outputs":{"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.90.0 (1159e78c4 2025-09-14)\nbinary: rustc\ncommit-hash: 1159e78c4747b02ef996e55082b704c09b970588\ncommit-date: 2025-09-14\nhost: aarch64-apple-darwin\nrelease: 1.90.0\nLLVM version: 20.1.8\n","stderr":""},"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/hegeken/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"vh\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"6432102384495711296":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/hegeken/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"vh\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""}},"successes":{}}
1+
{"rustc_fingerprint":8181815494667461818,"outputs":{"2595164081506252816":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/Users/hegeken/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"neon\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"android\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/hegeken/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"vh\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"11449549311697287552":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/Users/hegeken/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_feature=\"ssse3\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"android\"\ntarget_pointer_width=\"32\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.90.0 (1159e78c4 2025-09-14)\nbinary: rustc\ncommit-hash: 1159e78c4747b02ef996e55082b704c09b970588\ncommit-date: 2025-09-14\nhost: aarch64-apple-darwin\nrelease: 1.90.0\nLLVM version: 20.1.8\n","stderr":""},"3285132367535543654":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/Users/hegeken/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"popcnt\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_feature=\"sse4.1\"\ntarget_feature=\"ssse3\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"android\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"10144619854796028087":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/Users/hegeken/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"eabi\"\ntarget_arch=\"arm\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"android\"\ntarget_pointer_width=\"32\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-schema-generator/schemas/config.schema.json",
33
"productName": "Proof Reader",
4-
"version": "0.8.5",
4+
"version": "0.8.6",
55
"identifier": "cn.helilab.proofreader",
66
"build": {
77
"frontendDist": "../dist",

src/App.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,12 @@ select {
702702
color: var(--text-muted);
703703
}
704704

705+
.nav-header-actions {
706+
display: flex;
707+
align-items: center;
708+
gap: 8px;
709+
}
710+
705711
.chapter-count {
706712
font-size: 11px;
707713
color: var(--text-muted);
@@ -712,6 +718,30 @@ select {
712718
backdrop-filter: blur(20px);
713719
}
714720

721+
.btn-hide-proofread {
722+
display: flex;
723+
align-items: center;
724+
gap: 4px;
725+
font-size: 11px;
726+
color: var(--accent);
727+
background: var(--bg-overlay);
728+
padding: 4px 10px;
729+
border-radius: 20px;
730+
border: 1px solid var(--border);
731+
backdrop-filter: blur(20px);
732+
cursor: pointer;
733+
transition: all var(--duration) var(--ease);
734+
}
735+
736+
.btn-hide-proofread:hover {
737+
background: var(--bg-hover);
738+
border-color: var(--border-strong);
739+
}
740+
741+
.btn-hide-proofread.active {
742+
color: var(--text-muted);
743+
}
744+
715745
.chapter-list {
716746
flex: 1;
717747
overflow-y: auto;

src/components/ChapterNav.tsx

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// ============================================================
22
// 章节导航侧栏
33
// ============================================================
4+
import { useState } from "react";
45
import { useAppStore } from "../stores/appStore";
56
import { EmptyState } from "./EmptyState";
67
import { Icons } from "./Icons";
@@ -51,6 +52,10 @@ export function ChapterNav({
5152
const chapters = useAppStore((s) => s.chapters);
5253
const currentChapterIndex = useAppStore((s) => s.currentChapterIndex);
5354
const setCurrentChapterIndex = useAppStore((s) => s.setCurrentChapterIndex);
55+
const proofreadStatus = useAppStore((s) => s.proofreadStatus);
56+
const [hideProofread, setHideProofread] = useState(false);
57+
58+
const proofreadCount = Object.values(proofreadStatus).filter(Boolean).length;
5459

5560
if (chapters.length === 0) {
5661
return (
@@ -66,30 +71,49 @@ export function ChapterNav({
6671
);
6772
}
6873

74+
const displayedChapters = hideProofread
75+
? chapters.filter((ch) => !proofreadStatus[ch.id])
76+
: chapters;
77+
6978
return (
7079
<div className="chapter-nav">
7180
<div className="nav-header">
7281
<h3>
7382
<Icons.list size={16} />
7483
章节
7584
</h3>
76-
<span className="chapter-count">{chapters.length}</span>
85+
<div className="nav-header-actions">
86+
<span className="chapter-count">{displayedChapters.length}/{chapters.length}</span>
87+
{proofreadCount > 0 && (
88+
<button
89+
className={`btn-hide-proofread ${hideProofread ? "active" : ""}`}
90+
onClick={() => setHideProofread(!hideProofread)}
91+
title={hideProofread ? "显示已校对章节" : "隐藏已校对章节"}
92+
>
93+
<Icons.circleCheckBig size={14} />
94+
{hideProofread ? "显示" : "隐藏"}已校对
95+
</button>
96+
)}
97+
</div>
7798
</div>
7899
<div className="chapter-list">
79-
{chapters.map((ch, i) => (
80-
<ChapterItem
81-
key={ch.id}
82-
chapter={ch}
83-
index={i}
84-
isActive={i === currentChapterIndex}
85-
onSelect={() => {
86-
setCurrentChapterIndex(i);
87-
if (onChapterSelect) {
88-
onChapterSelect();
89-
}
90-
}}
91-
/>
92-
))}
100+
{displayedChapters.map((ch) => {
101+
const originalIndex = chapters.indexOf(ch);
102+
return (
103+
<ChapterItem
104+
key={ch.id}
105+
chapter={ch}
106+
index={originalIndex}
107+
isActive={originalIndex === currentChapterIndex}
108+
onSelect={() => {
109+
setCurrentChapterIndex(originalIndex);
110+
if (onChapterSelect) {
111+
onChapterSelect();
112+
}
113+
}}
114+
/>
115+
);
116+
})}
93117
</div>
94118
</div>
95119
);

src/components/ProofreadPanel.tsx

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ import { IgnoredWordsManager } from "./IgnoredWordsManager";
1414
import { ToastContainer } from "./Toast";
1515
import type { ToastMessage } from "./Toast";
1616
import type { CheckGranularity, ProofreadError } from "../types";
17-
import {
18-
initNotificationService,
19-
updateProofreadProgress,
20-
sendProofreadCompleteNotification,
21-
} from "../utils/notificationService";
17+
2218

2319
const ERROR_TYPE_LABELS: Record<string, { icon: keyof typeof Icons; label: string }> = {
2420
typo: { icon: "typo", label: "错别字" },
@@ -64,7 +60,6 @@ export function ProofreadPanel() {
6460
const [singleCheckingLine, setSingleCheckingLine] = useState<number | null>(
6561
null,
6662
);
67-
const [notificationInit, setNotificationInit] = useState(false);
6863
const [showIgnoredWordsModal, setShowIgnoredWordsModal] = useState(false);
6964
const [toastMessages, setToastMessages] = useState<ToastMessage[]>([]);
7065
// 动画互斥:防止快速连续点击"采纳"
@@ -159,47 +154,12 @@ export function ProofreadPanel() {
159154
}
160155
}, [chapter?.id, paragraphIndexMap, chapter, setResults, setStartLine]);
161156

162-
useEffect(() => {
163-
if (!checking || !chapter) return;
164-
const chapterId = chapter.id;
165-
const chapterTitle = chapter.title;
166-
const interval = setInterval(async () => {
167-
const currentResults = useProofreadStore.getState().results[chapterId] ?? [];
168-
const totalErrors = currentResults.reduce((sum, r) => sum + r.errors.length, 0);
169-
const remainingErrors = currentResults.reduce(
170-
(sum, r) => sum + r.errors.filter((e) => !e.applied && !e.skipped).length,
171-
0,
172-
);
173-
const processedCount = totalErrors - remainingErrors;
174-
if (totalErrors > 0) {
175-
await updateProofreadProgress({
176-
chapterTitle,
177-
totalErrors,
178-
remainingErrors,
179-
processedCount,
180-
});
181-
}
182-
}, 5000);
183-
return () => clearInterval(interval);
184-
}, [checking, chapter]);
157+
185158

186159
const handleStartCheck = async () => {
187-
if (!notificationInit) {
188-
await initNotificationService();
189-
setNotificationInit(true);
190-
}
191160
setChecking(true);
192161
await checkChapter(granularity, startLine ?? 0);
193162
setChecking(false);
194-
if (chapter) {
195-
const finalResults = useProofreadStore.getState().results[chapter.id] ?? [];
196-
const finalTotal = finalResults.reduce((sum, r) => sum + r.errors.length, 0);
197-
const finalProcessed = finalResults.reduce(
198-
(sum, r) => sum + r.errors.filter((e) => e.applied || e.skipped).length,
199-
0,
200-
);
201-
await sendProofreadCompleteNotification(chapter.title, finalTotal, finalProcessed);
202-
}
203163
};
204164

205165
const handleSingleLineCheck = async (originalIndex: number, filteredIndex: number) => {

0 commit comments

Comments
 (0)