Skip to content

feat(history): 润色未变化检测与历史重新润色 (Fixes #653)#666

Open
HKLHaoBin wants to merge 11 commits into
Open-Less:betafrom
HKLHaoBin:feat/issue-653-polish-unchanged
Open

feat(history): 润色未变化检测与历史重新润色 (Fixes #653)#666
HKLHaoBin wants to merge 11 commits into
Open-Less:betafrom
HKLHaoBin:feat/issue-653-polish-unchanged

Conversation

@HKLHaoBin

@HKLHaoBin HKLHaoBin commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

User description

摘要

Fixes #653

非原文润色结果与 ASR 原文规范化比较后完全一致时,标记 polishUnchanged 并在历史页提供「重新润色」;功能默认关闭,需在 设置 → 隐私 → 数据存储 开启「润色未变化检测」。

依赖说明: 本分支基于 feat/android-auto-update(上游 PR #664)。若 #664 尚未合并,diff 会包含 Android 自动更新相关提交;Issue #653 专属改动为最近 2 个 commit、约 15 个文件(+510 行)。

修复 / 新增 / 改进

  • 检测与标记normalize_for_polish_compare + is_polish_unchangedend_session 在 pref 开启且非 raw 时写入 errorCode = polishUnchanged
  • 历史重新润色:新增 repolish_history_entry IPC / command;按原 stylePackId(或 mode fallback)单轮润色并原地回写,保留 id / createdAt / 录音 / 插入状态。
  • 边界修复:翻译听写条目(translationActive)禁止重新润色(UI + IPC);回写时仅重算 None / polishUnchanged / polishFailed,保留 focusRestoreFailedwindowsImeTsfRequired 等插入错误码。
  • 前端:History 列表 tag、详情 banner、「重新润色」按钮(pref 门控);DataStorageSection 全局开关,默认
  • i18n:en / zh-CN / zh-TW / ja / ko。
  • 单测is_polish_unchangedresolve_polish_unchanged_error_coderesolve_repolish_history_error_code 等(CI Linux / macOS 已跑过)。

兼容

  • 不包含:模糊相似度阈值、自动重试、overlay 胶囊展示、改造现有裸 repolish(rawText, mode) IPC。
  • 对现有用户 / 本地环境 / 构建流程的影响
    • 默认关闭,现有用户行为不变;开启后仅影响新完成的听写会话及历史页 UI。
    • 重新润色依赖已配置的 LLM 凭据与网络,与现有润色路径相同。
    • Android 与桌面共用同一套 History / Settings UI,无额外 native 模块。

测试计划

  • 命令:npm run build

  • 结果:通过

  • 证据路径:本地构建

  • 命令:CI workflow_dispatchfeat/issue-653-polish-unchanged

  • 结果:4 job success(Android cargo check / macOS / Linux / Windows)

  • 证据路径:https://github.com/HKLHaoBin/openless/actions/runs/27520160830

  • 命令:cargo test --lib(polish / repolish 相关,CI)

  • 结果:通过(Windows 本地缺 MSVC linker,未本地跑)

  • 证据路径:同上 CI Linux / macOS job

  • 命令:Android release APK 真机 adb install -r + History / 设置操作

  • 结果:启动无 crash;pref 开启时列表 tag + 详情 banner +「重新润色」可见;点击重新润色触发 LLM;pref 关闭后 tag / banner / 按钮隐藏

  • 证据路径:ci-artifacts/openless-653-*.png(本地,未提交)

  • 命令:桌面端 History 回归(pref 开/关、重新润色、raw / 翻译条目)

  • 结果:待 reviewer / 维护者复测

  • 证据路径:—


PR Type

Enhancement, Bug fix


Description

  • Detect unchanged polish and allow re-polish from history

  • Add polish unchanged detection, repolish IPC, and UI

  • Fix Android release JNI crashes and overlay service issues

  • Update Android updater logic and CI for signed APK builds


Diagram Walkthrough

flowchart LR
  A[End session] --> B{polish unchanged?}
  B -- Yes --> C[Mark errorCode=polishUnchanged]
  B -- No --> D[Normal flow]
  C --> E[History detail shows banner + repolish button]
  E --> F[User clicks repolish]
  F --> G[IPC: repolish_history_entry]
  G --> H[Re-polish with original style pack]
  H --> I[Update entry in history]
Loading

File Walkthrough

Relevant files
Enhancement
15 files
dictation.rs
Add polish unchanged detection and repolish helpers           
+272/-9 
coordinator.rs
Add repolish_history_entry coordinator method                       
+105/-14
updater.rs
Refactor updater to use updater_logic helpers                       
+19/-65 
updater_logic.rs
Add pure updater helper functions with tests                         
+123/-0 
history.rs
Add repolish_history_entry IPC command                                     
+9/-0     
AutoUpdate.tsx
Support auto-install for Android updates                                 
+80/-54 
AutoUpdateGate.tsx
Enable auto-install for Android background checks               
+6/-9     
History.tsx
Add polish unchanged badge and repolish button                     
+51/-2   
types.ts
Add polishUnchangedEnabled preference type                             
+10/-6   
BetaChannelSection.tsx
Rework Beta toggle layout and add separate row                     
+12/-15 
CheckUpdateButton.tsx
Use explicit channel labels for manual checks                       
+5/-9     
AutoUpdateSection.tsx
Add Android auto-update toggle section                                     
+36/-0   
ipc.ts
Add repolishHistoryEntry mock and invoke                                 
+18/-0   
DataStorageSection.tsx
Add polish unchanged detection toggle                                       
+10/-1   
check-android-updater-pubkey.mjs
Add script to validate pubkey consistency                               
+37/-0   
Configuration changes
3 files
types.rs
Add polish_unchanged_enabled preference field                       
+17/-11 
android-apk.yml
Support signed release builds on workflow_dispatch             
+64/-10 
package.json
Add check:android-updater-pubkey script                                   
+2/-1     
Bug fix
6 files
jni.rs
Fix accessibility state via Settings.Secure                           
+136/-23
OpenLessOverlayService.kt
Fix recording foreground service failure handling               
+37/-18 
OpenLessOverlayBridge.kt
Add @Keep annotations to prevent R8 stripping                       
+4/-0     
OpenLessAccessibilityService.kt
Add @Keep annotations to JNI methods                                         
+3/-0     
OpenLessUpdateInstaller.kt
Add @Keep and @JvmStatic annotations                                         
+4/-0     
OpenLessPermissionBridge.kt
Add @Keep annotation to object                                                     
+3/-0     
Miscellaneous
3 files
lib.rs
Register repolish_history_entry command                                   
+2/-0     
mod.rs
Export updater_logic module                                                           
+1/-0     
tabs.tsx
Add AutoUpdateSection to Advanced tab                                       
+2/-0     
Documentation
7 files
ja.ts
Add Japanese translations for polish unchanged                     
+18/-1   
zh-TW.ts
Add Traditional Chinese translations for polish unchanged
+18/-1   
ko.ts
Add Korean translations for polish unchanged                         
+18/-1   
zh-CN.ts
Add Simplified Chinese translations for polish unchanged 
+18/-1   
en.ts
Add English translations for polish unchanged                       
+18/-1   
android-mobile-apk-overlay-plan.md
Update docs for in-app updater                                                     
+26/-2   
README.md
Document updater and updater_logic modules                             
+2/-0     
Tests
2 files
stylePrefs.test.ts
Add polishUnchangedEnabled to test default prefs                 
+3/-2     
ci.yml
Add pubkey check step                                                                       
+3/-0     

HKLHaoBin and others added 11 commits June 14, 2026 20:58
Align updateChannel prefs with background AutoUpdateGate, add symmetric manual stable/beta check buttons, Android auto-download after check, and settings toggle; extract updater_logic helpers with unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
call_static_method caused NoSuchMethodError on Thread-8 during AutoUpdateGate background check, killing the app ~4s after launch.

Co-authored-by: Cursor <cursoragent@cursor.com>
Manual workflow_dispatch builds signed release APKs when ANDROID_KEYSTORE_* is configured (overlay install, data preserved); otherwise falls back to unsigned debug with job summary notice. Tag releases still require all secrets; minisign/manifest/GitHub Release remain tag-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sync UPDATER_PUBKEY_B64 with tauri.conf.json; fail download when installApk returns false; put Beta channel above auto-update toggle; add pubkey CI check script.

Co-authored-by: Cursor <cursoragent@cursor.com>
Avoid squeezing the toggle beside long description text on narrow mobile layouts; align with AutoUpdateSection pattern.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Exclude Playwright/ui-check-screenshots outputs from version control and update the lockfile after tauri-nspanel resolution.

Co-authored-by: Cursor <cursoragent@cursor.com>
Avoid NoSuchMethodError when installed APK dex lacks OpenLessAccessibilityService.isEnabled static bridge; query enabled services and heartbeat prefs directly.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add @keep and @JvmStatic on Rust-invoked bridge methods; default overlay service starts to startService and only START_RECORDING uses startForegroundService on API 26+; abort recording when foreground promotion fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ess#653)

Add opt-in polishUnchanged detection, history-level repolish IPC, and UI; exclude translation history; preserve insert error codes on retry.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ssion

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

664 - Partially compliant

Compliant requirements:

  • Android auto-update with stable/beta channels (check, download, install).
  • Signature verification using minisign.
  • Updater logic extracted to updater_logic.rs with unit tests.
  • Beta channel toggle and auto-update switch UI added.
  • CI step npm run check:android-updater-pubkey added.
  • JNI methods preserved with @keep / @JvmStatic.
  • Overlay foreground service fixed to use startService for non-recording actions.

Non-compliant requirements:

Requires further human verification:

  • (Empty)

653 - Partially compliant

Compliant requirements:

  • is_polish_unchanged function and normalize_for_polish_compare.
  • polishUnchanged error code written in end_session.
  • UI: tag in list, banner in detail, re-polish button (gated by pref).
  • repolish_history_entry command and coordinator method.
  • Feature toggle polishUnchangedEnabled default false.
  • Unit tests for detection and error code resolution.

Non-compliant requirements:

  • (Empty)

Requires further human verification:

  • (Empty)
⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Compile Error

The function resolve_style_pack_for_history_entry is defined inside the mod tests block (around line 6238), making it private to the test module. It is called from the public repolish_history_entry method at line 1479, which will fail to compile because the function is not accessible outside the test module. This function must be moved out of the mod tests block into regular scope to be usable.

fn resolve_style_pack_for_history_entry(
    style_packs: &StylePackStore,
    entry: &DictationSession,
) -> StylePack {
    if let Some(id) = entry.style_pack_id.as_deref() {
        if let Ok(pack) = style_packs.get(id) {
            return pack;
        }
    }
    builtin_style_pack_for_mode(entry.mode)
}

@HKLHaoBin

Copy link
Copy Markdown
Contributor Author

感谢 bot 标注,这条 Compile Error 是误报,当前代码可以正常编译。

resolve_style_pack_for_history_entry 并不在 mod tests 内部:测试模块在 coordinator.rs L6236} 处结束,该 helper 从 L6238 起定义在模块顶层(与后面的 enabled_phrases 同级),repolish_history_entry(L1479)调用它是合法的同一模块内可见性。

CI 已在四平台通过(含 Android cargo check / macOS / Linux / Windows),若为真实编译错误,check 阶段会直接失败。

无需为此改动代码。

@HKLHaoBin

Copy link
Copy Markdown
Contributor Author

PR 合并冲突提示

1. 与 #664 的包含关系

2. dictation.rs(与 #682#688#692

3. 其他重叠(低风险)

建议合并顺序: 先定听写小修复(#682#688#692)与本 PR 谁先合,另一方 rebase 并解决 dictation.rs;不要同时合 #664

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[area:style] 润色结果偶发与原文完全一致,缺少重试提示

1 participant