mirror of
https://github.com/fcitx5-android/fcitx5-android.git
synced 2026-08-02 04:44:35 +08:00
chore: prepare clipboard enhancements for upstream
This commit is contained in:
parent
f5216c5758
commit
e2e02e5cdd
@ -143,9 +143,3 @@ configurations {
|
||||
exclude(group = "com.louiscad.splitties", module = "splitties-systemservices")
|
||||
}
|
||||
}
|
||||
|
||||
// descriptor.json is generated inside the main assets directory. Gradle 9 requires
|
||||
// consumers of that directory to declare the producing task explicitly.
|
||||
tasks.matching { it.name.startsWith("lint") || it.name.endsWith("LintReportModel") }.configureEach {
|
||||
dependsOn("generateDataDescriptor")
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ class ThemeSerializationTest {
|
||||
|
||||
@Test
|
||||
fun version2() {
|
||||
// Version 2.0, outdated
|
||||
// Version 2.0
|
||||
val raw = """
|
||||
{
|
||||
"name":"",
|
||||
@ -98,7 +98,7 @@ class ThemeSerializationTest {
|
||||
}
|
||||
""".trimIndent()
|
||||
val (decoded, migrated) = raw.toCustomTheme()
|
||||
Assert.assertEquals("Migration should happen", true, migrated)
|
||||
Assert.assertEquals("Migration shouldn't happen", false, migrated)
|
||||
Assert.assertEquals("Round trip", decoded, decoded.toJson().toCustomTheme().first)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,246 +0,0 @@
|
||||
# 剪贴板分类手工测试样本
|
||||
|
||||
这份文档用于 PR2 的模拟器手工测试。每次只复制代码块中的一条文本,然后打开小企鹅输入法的剪贴板,切换底部分类栏检查它出现的位置。
|
||||
|
||||
建议先复制每组中的“应命中”样本,再复制“应归入其他”的反例。顶栏切换到“收藏”后,还可以收藏其中一条,再验证“收藏 × 分类”组合筛选。
|
||||
|
||||
## 验证码
|
||||
|
||||
以下应归入“验证码”:
|
||||
|
||||
```text
|
||||
1234
|
||||
```
|
||||
|
||||
```text
|
||||
8042
|
||||
```
|
||||
|
||||
```text
|
||||
0000
|
||||
```
|
||||
|
||||
```text
|
||||
123456
|
||||
```
|
||||
|
||||
```text
|
||||
000000
|
||||
```
|
||||
|
||||
```text
|
||||
9876
|
||||
```
|
||||
|
||||
```text
|
||||
123456
|
||||
```
|
||||
|
||||
以下不应归入“验证码”,而应归入“其他”:
|
||||
|
||||
```text
|
||||
123
|
||||
```
|
||||
|
||||
```text
|
||||
12345
|
||||
```
|
||||
|
||||
```text
|
||||
验证码:123456
|
||||
```
|
||||
|
||||
```text
|
||||
验证码 8042
|
||||
```
|
||||
|
||||
```text
|
||||
OTP: 123456
|
||||
```
|
||||
|
||||
```text
|
||||
Your verification code is 8042
|
||||
```
|
||||
|
||||
```text
|
||||
订单号 123456
|
||||
```
|
||||
|
||||
```text
|
||||
12 34
|
||||
```
|
||||
|
||||
```text
|
||||
12-34
|
||||
```
|
||||
|
||||
## 电话号码
|
||||
|
||||
以下应归入“电话”:
|
||||
|
||||
```text
|
||||
13800138000
|
||||
```
|
||||
|
||||
```text
|
||||
+86 138-0013-8000
|
||||
```
|
||||
|
||||
```text
|
||||
(010) 8888-8888
|
||||
```
|
||||
|
||||
```text
|
||||
12345678
|
||||
```
|
||||
|
||||
以下应归入“其他”:
|
||||
|
||||
```text
|
||||
电话:13800138000
|
||||
```
|
||||
|
||||
```text
|
||||
13800138000 转 1234
|
||||
```
|
||||
|
||||
```text
|
||||
12345
|
||||
```
|
||||
|
||||
## 邮箱
|
||||
|
||||
以下应归入“邮箱”:
|
||||
|
||||
```text
|
||||
person@example.com
|
||||
```
|
||||
|
||||
```text
|
||||
person+tag@example.com
|
||||
```
|
||||
|
||||
```text
|
||||
first.last@sub.example.co.uk
|
||||
```
|
||||
|
||||
以下应归入“其他”:
|
||||
|
||||
```text
|
||||
邮箱:person@example.com
|
||||
```
|
||||
|
||||
```text
|
||||
请联系 person@example.com 获取帮助
|
||||
```
|
||||
|
||||
```text
|
||||
person@example
|
||||
```
|
||||
|
||||
## 网址
|
||||
|
||||
以下应归入“网址”:
|
||||
|
||||
```text
|
||||
https://example.com/path?q=1
|
||||
```
|
||||
|
||||
```text
|
||||
http://example.org
|
||||
```
|
||||
|
||||
```text
|
||||
ftp://files.example.org/archive.zip
|
||||
```
|
||||
|
||||
```text
|
||||
example.org/docs
|
||||
```
|
||||
|
||||
```text
|
||||
www.example.com
|
||||
```
|
||||
|
||||
以下应归入“其他”:
|
||||
|
||||
```text
|
||||
访问 https://example.com 获取详情
|
||||
```
|
||||
|
||||
```text
|
||||
example
|
||||
```
|
||||
|
||||
```text
|
||||
https://example.com 帮助
|
||||
```
|
||||
|
||||
## 追踪口令
|
||||
|
||||
当前版本刻意采用保守规则。以下应归入“口令”:
|
||||
|
||||
```text
|
||||
¥AbC123xy¥
|
||||
```
|
||||
|
||||
```text
|
||||
复制这段内容后打开淘宝 ¥AbC123xy¥
|
||||
```
|
||||
|
||||
```text
|
||||
¥a1b2c3d4¥
|
||||
```
|
||||
|
||||
```text
|
||||
商品分享 ₤Token9876₤ 请打开应用
|
||||
```
|
||||
|
||||
以下应归入“其他”:
|
||||
|
||||
```text
|
||||
复制这段内容后打开淘宝领取优惠
|
||||
```
|
||||
|
||||
```text
|
||||
这里提到了口令但没有结构
|
||||
```
|
||||
|
||||
```text
|
||||
¥abc¥
|
||||
```
|
||||
|
||||
```text
|
||||
¥只有左边符号
|
||||
```
|
||||
|
||||
## 普通文本
|
||||
|
||||
以下均应归入“其他”:
|
||||
|
||||
```text
|
||||
北京市朝阳区示例路 100 号
|
||||
```
|
||||
|
||||
```text
|
||||
这是一个普通的剪贴板条目。
|
||||
```
|
||||
|
||||
```text
|
||||
账号 example_user_01
|
||||
```
|
||||
|
||||
```text
|
||||
明天下午三点开会
|
||||
```
|
||||
|
||||
## 推荐交互检查
|
||||
|
||||
1. 在“剪贴板”页依次切换七个底部分类,检查条目只出现在预期分类中。
|
||||
2. 收藏一个验证码和一个网址,切换到“收藏”页,再分别选择“验证码”和“网址”。
|
||||
3. 选择一个没有条目的分类,检查显示分类专用空状态。
|
||||
4. 退出剪贴板面板后重新进入,检查恢复为“剪贴板 + 全部”。
|
||||
5. 重复复制同一条文本,检查它移动到最前,但收藏和置顶状态不丢失。
|
||||
6. 将条目编辑成另一类内容,检查它从旧分类移动到新分类。
|
||||
7. 检查底部栏可以横向滚动,窄屏下“其他”仍可访问。
|
||||
8. 检查批量清空、滑动删除和撤销行为与阶段 1 相同;本版本不应发生任何自动删除。
|
||||
@ -1,214 +0,0 @@
|
||||
# F5Clipboard 剪贴板增强计划
|
||||
|
||||
## 总体方案与阶段
|
||||
|
||||
基于当前 fork 的主 `app` 模块开发,保持上游兼容,不拆成独立插件或增强版应用。
|
||||
|
||||
- **阶段 1:顶栏与收藏**(功能完成;全仓既有门禁问题待处理)
|
||||
- **阶段 2:智能管理**(分类、底部筛选和可选自动清理均已完成)
|
||||
- **阶段 3:常用词**(已完成:自定义短语、三字符匹配与一键补全)
|
||||
|
||||
上游相关需求:[fcitx5-android/fcitx5-android#456](https://github.com/fcitx5-android/fcitx5-android/issues/456)。
|
||||
|
||||
## 阶段 1:顶栏与收藏
|
||||
|
||||
### 数据与接口
|
||||
|
||||
- Room 数据库由 v4 升到 v5,为剪贴板条目增加 `favorite` 状态,并通过自动迁移保留旧数据。
|
||||
- 使用 `ClipboardEntryFilter` 统一“全部”和“收藏”查询入口,为后续分类过滤保留扩展点。
|
||||
- 使用独立的 `ClipboardPanelSection` 表示键盘面板顶栏页面,并扩展“常用词”页面。
|
||||
- 阶段 1 不增加 `category`、`expiresAt` 等尚未使用的字段,也不修改插件 AIDL。
|
||||
|
||||
### 收藏与删除语义
|
||||
|
||||
- 收藏与置顶相互独立,同一条目可以同时置顶和收藏。
|
||||
- 剪贴板页显示全部未删除条目;收藏页只显示收藏条目,均按置顶优先、时间倒序排列。
|
||||
- 历史上限裁剪和一键清空只处理既未置顶、也未收藏的条目。
|
||||
- 收藏属于软保护:用户仍可通过菜单或滑动手动删除,并可撤销。
|
||||
- 重复复制已有文本时只更新时间,保留置顶和收藏状态。
|
||||
|
||||
### 顶栏与交互
|
||||
|
||||
- 顶栏布局:返回按钮 + “剪贴板 / 收藏”标签 + 清空按钮。
|
||||
- 默认进入剪贴板页,不持久化上次标签。
|
||||
- 收藏页隐藏清空按钮;没有收藏时显示独立空状态。
|
||||
- 长按菜单提供“收藏/取消收藏”;条目使用星标展示状态。
|
||||
- 新增英文、简体中文和繁体中文资源,其他语言回退到英文。
|
||||
|
||||
## 后续阶段预留
|
||||
|
||||
### 阶段 2:智能管理
|
||||
|
||||
阶段 2 的分类与自动清理保持模块化实现。分类本身不改变删除语义;只有用户明确开启对应的自动删除开关后,验证码或追踪口令才会获得有效期。
|
||||
|
||||
#### 2A:数据模型与内容分析器
|
||||
|
||||
- Room 数据库由 v5 升到 v6,新增:
|
||||
- `category`:稳定的字符串枚举,包含 `Phone`、`Email`、`Url`、`Otp`、`TrackingToken`、`Other`。
|
||||
- `classificationVersion`:分析规则版本,用于未来规则升级后安全地重新分析旧数据。
|
||||
- v5→v6 迁移先把旧条目标记为 `Other / classificationVersion=0`,数据库打开后再分批重新分析;迁移 SQL 本身不运行复杂正则,避免阻塞启动和迁移失败。
|
||||
- 新增纯 Kotlin 的 `ClipboardContentAnalyzer`,输入原始文本,输出唯一分类及命中的规则 ID。分析器不依赖 Room、UI、自动清理设置、sensitive 标记或来源 App,可通过表驱动单元测试独立验证。
|
||||
- 后续自动清理不得维护第二套验证码/口令识别器:是否具备删除资格必须直接复用本分析器的分类结果。
|
||||
- 原文保持不变;仅对 `trim()` 后的临时文本做判断,不自动改写电话号码、URL 或口令。
|
||||
- 当前 `ClipboardEntryFilter` 从枚举扩展为组合查询对象:
|
||||
- `scope`:全部或收藏。
|
||||
- `category`:全部类别或单个类别。
|
||||
这样不会为“收藏 × 分类”制造大量枚举值,阶段 3 也可继续沿用。
|
||||
|
||||
分类优先级采用:`TrackingToken > Otp > Email > Url > Phone > Other`。高特征、短生命周期内容优先,防止淘口令被当作普通文本、验证码被当作电话号码。
|
||||
|
||||
具体识别规则:
|
||||
|
||||
- **追踪口令**:首版只匹配成对的 `¥…¥`/`¥…¥`/`₤…₤` 高置信度结构。单独出现“口令”“复制后打开淘宝/天猫”等说明文字不命中;京东、拼多多等格式在取得稳定样本后再以独立规则加入,避免凭关键词误判。
|
||||
- **验证码**:去除首尾空白并完成全角归一化后,内容必须恰好是 4 位或 6 位纯数字。系统“仅复制验证码”可以直接命中;`验证码:123456`、短信正文、带字母的代码和 5 位数字归入 `Other`。7–15 位纯数字仍按电话号码规则判断。分类不依赖 sensitive 标记。
|
||||
- **邮箱**:去除首尾空白后必须整体匹配邮箱格式,不从长段落中截取局部邮箱。
|
||||
- **网址**:必须是完整 URL,或可安全补全协议的完整域名;首版不把包含 URL 的整段分享文案归类为网址。
|
||||
- **电话**:仅允许 `+`、数字、空格、连字符和括号,去除分隔符后为 7–15 位数字;其中纯 4 位和纯 6 位数字已优先归为验证码,其他满足长度的纯数字仍可归为电话。
|
||||
- **其他**:没有满足上述完整规则的内容。
|
||||
|
||||
写入和更新语义:
|
||||
|
||||
- 新条目在同一事务内完成分析和写入。
|
||||
- 重复复制已有文本时更新时间并重新计算分类,同时保留置顶、收藏状态。
|
||||
- 编辑条目后重新分析,置顶和收藏状态保持不变。
|
||||
- 规则版本升级时仅重分析 `classificationVersion` 较旧的有效条目,并限制每批数量,避免大历史库卡顿。
|
||||
|
||||
#### 2B:分类筛选界面
|
||||
|
||||
- 分类筛选栏固定在剪贴板面板底部、位于条目列表下方,使用可横向滚动的紧凑栏:`全部、电话、邮箱、网址、验证码、口令、其他`。顶栏仍然只有返回按钮、“剪贴板 / 收藏”和清空按钮,不增加第二行顶栏。
|
||||
- 分类筛选同时适用于剪贴板页和收藏页;切换顶栏页面时保留当前分类,退出并重新进入剪贴板窗口时恢复为“剪贴板 + 全部”。
|
||||
- 筛选栏只改变查询,不改变排序;仍按置顶优先、时间倒序排列。
|
||||
- 每种分类提供独立空状态,例如“没有已收藏的网址”,不复用“尝试复制内容”。
|
||||
- 条目本身暂不增加醒目的分类角标,避免卡片过于拥挤;首版只通过筛选栏表达分类。后续如需要,可在长按菜单中显示只读分类信息。
|
||||
- 英文、简体中文、繁体中文提供完整资源,其他语言继续回退英文。
|
||||
|
||||
#### 2C:可选自动过期与保护
|
||||
|
||||
- 自动清理首版只作用于被分析器分类为 `Otp` 或 `TrackingToken` 的条目。电话、邮箱、网址和其他类别永不过期。
|
||||
- 剪贴板设置增加两个独立开关和时长:
|
||||
- 自动删除验证码:默认关闭;开启后允许配置 1–1440 分钟,初始建议值 10 分钟。
|
||||
- 自动删除追踪口令:默认关闭;开启后允许配置 1–720 小时,初始建议值 24 小时。
|
||||
- 两个开关默认均为关闭。只要对应开关未开启,该类别不会生成有效期,清理调度器和数据库删除查询也必须再次检查开关,保证关闭状态下完全不发生自动删除。
|
||||
- 不增加“最近清理”、恢复区、`deletedAt` 或 `deletionReason`,也不改变现有手动删除 + Snackbar 撤销逻辑。自动过期到达后按 ID 直接从数据库彻底删除。
|
||||
- 开启某类自动删除时,已有的同类未保护条目统一从开启时刻开始计算新的有效期,不追溯旧时间立即删除。
|
||||
- 修改删除时长时,尚未过期的同类未保护条目统一从修改时刻重新计时;关闭开关时立即把该类别所有待过期条目的 `expiresAt` 清空。
|
||||
- 置顶或收藏任一操作都会清空该条目的 `expiresAt`,使其永久保留;之后取消保护也不会自动恢复旧有效期。若用户确实需要重新启用过期,只需再次复制该内容。
|
||||
- 自动清理触发点:数据库初始化、收到新剪贴板、进入剪贴板窗口、修改相关设置,以及输入法进程存活期间最近一个 `expiresAt` 到达时。首版不引入 WorkManager,因此不承诺应用进程被系统杀死时准点到秒清理,但下次启动会立即补清。
|
||||
- 自动清理不会弹出打断输入的 Snackbar;这是用户预先启用并配置时间后的直接删除行为。
|
||||
- 开发者设置中的彻底清库行为保持不变。
|
||||
|
||||
#### PR2 验收标准
|
||||
|
||||
- v5→v6 迁移无损,旧条目可后台重分析,置顶和收藏状态保持不变。
|
||||
- 分类规则对中英文样例、边界长度、全角符号、换行和误判反例均有表驱动测试。
|
||||
- 全部/收藏与七种分类组合查询、分页和排序正确。
|
||||
- 重复复制和编辑会重新分类,且不会清除置顶或收藏。
|
||||
- PR2 不增加 `expiresAt`、清理调度器或自动删除设置,不改变阶段 1 的删除行为。
|
||||
- API 35 模拟器上验证深浅主题、横竖屏、窄屏筛选栏、敏感内容遮罩及大批量分页。
|
||||
|
||||
#### 明确不纳入阶段 2
|
||||
|
||||
- 不读取或记录剪贴板来源 App;分类完全依据文本,也不使用 Android sensitive 标记影响分类。
|
||||
- 不自动修改 URL、电话号码或口令原文;ClearURLs 插件仍保持独立。
|
||||
- 不引入机器学习模型、联系人匹配、云端规则或联网分析。
|
||||
- 不实现阶段 3 的常用词、候选预测或新的插件 AIDL。
|
||||
|
||||
### 阶段 3:常用词
|
||||
|
||||
- 顶栏扩展为“剪贴板 / 收藏 / 常用词”。
|
||||
- 复用现有 `QuickPhraseManager`、`QuickPhraseEntry` 和 `.mb` 快速输入文件格式,以独立的 `f5clipboard-common-words.mb` 保存常用词,不增加数据库表。
|
||||
- 常用词页支持点击直接上屏、长按删除;新增和编辑按钮从键盘打开专用快速输入编辑页,保存后立即刷新键盘数据和 Fcitx 快速输入。
|
||||
- 编辑常用词时若关键词留空,自动取短语最前面的三个 Unicode 字符作为关键词;关键词只用于兼容快速输入文件格式,补全匹配始终以短语正文为准。
|
||||
- 光标前已提交文本与某条常用词的开头连续匹配至少三个 Unicode 字符时,在空闲工具栏显示最佳匹配;点击只提交尚未输入的后缀,避免重复文本。
|
||||
- 多条短语同时匹配时优先选择当前匹配前缀最长的条目;ASCII 匹配不区分大小写,但补全文本保留已保存短语的大小写。
|
||||
- 密码输入框和 `IME_FLAG_NO_PERSONALIZED_LEARNING` 私密输入模式中禁用常用词预测。
|
||||
- 中文拼音仍由现有 Fcitx preedit/candidate 流程处理;常用词预测只检查编辑器中已经提交到光标前的文本,不抢占输入法候选。
|
||||
|
||||
## 阶段 1 验证清单
|
||||
|
||||
- [x] v4 数据库无损迁移到 v5,旧条目默认未收藏。
|
||||
- [x] 收藏切换、全部查询、收藏查询和排序正确。
|
||||
- [x] 历史裁剪与一键清空跳过置顶及收藏。
|
||||
- [x] 手动删除收藏条目及撤销正常。
|
||||
- [x] 重复复制不会清除收藏状态。
|
||||
- [x] 顶栏切换和各类空状态正确。
|
||||
- [ ] 全仓门禁完全通过(`testDebugUnitTest`、`assembleDebug` 已通过;`lintDebug` 被 269 个既有错误阻塞)。
|
||||
- [x] API 35 模拟器上的阶段 1 自动化与手工交互验证通过。
|
||||
|
||||
### 2026-07-30 验收记录
|
||||
|
||||
- `testDebugUnitTest`、`assembleDebug`、`assembleDebugAndroidTest` 均通过。
|
||||
- API 35 上通过 AndroidJUnitRunner 直接执行阶段 1 的 6 个仪器测试;Gradle `connectedDebugAndroidTest` 的 UTP 启动被本机离线依赖缓存阻塞。
|
||||
- 手工验证了收藏/取消收藏、填充星标、收藏筛选、独立空状态、批量清空保护,以及重新进入时默认回到剪贴板页。
|
||||
- `lintDebug` 完成扫描,本次改动没有命中 lint 报告;任务仍因仓库原有的 269 个错误失败,首个错误位于未改动的 `fragment_setup.xml`。
|
||||
- 仓库原有 `FcitxTest` 在 API 35 上进入首项测试后超过 90 秒没有完成;阶段 1 的独立仪器测试不受影响。
|
||||
|
||||
## PR2 验证清单
|
||||
|
||||
- [x] Room v5→v6 无损迁移,旧条目默认 `Other / classificationVersion=0`。
|
||||
- [x] 旧条目分批重分类,置顶和收藏状态不变。
|
||||
- [x] 新增、重复复制和编辑会按同一分析器更新分类。
|
||||
- [x] 纯 4 位和纯 6 位数字归为验证码;带说明文字、5 位数字等反例不命中。
|
||||
- [x] 口令首版仅识别成对货币符号结构,宽泛说明文字不命中。
|
||||
- [x] 全部/收藏与各分类组合查询及排序正确。
|
||||
- [x] 底部分类栏切换、分类空状态和重新进入时复位正确。
|
||||
- [x] PR2 不包含任何自动过期字段、设置或删除逻辑。
|
||||
- [x] `testDebugUnitTest`、`assembleDebug`、`assembleDebugAndroidTest` 通过。
|
||||
- [x] API 35 上 9 项剪贴板数据库仪器测试通过。
|
||||
- [x] `git diff --check` 通过。
|
||||
- [ ] `lintDebug` 全任务通过(当前被项目构建插件的 `cxxAbiModel` 缺失阻断,尚未进入 lint 扫描)。
|
||||
|
||||
### 2026-07-30 PR2 验收记录
|
||||
|
||||
- 分类分析器的 3 组表驱动单元测试全部通过,覆盖 4/6 位验证码、全角数字、电话边界、带文本验证码反例及保守口令规则。
|
||||
- API 35 上 9/9 仪器测试通过,覆盖 v4→v5、v5→v6 迁移,分类筛选与收藏组合,以及重复复制重分类后保留保护状态。
|
||||
- 已在模拟器中检查底部栏布局、电话筛选和“收藏 × 分类”独立空状态;验证码规则的最终修订由最新单元测试及重新构建的 APK 覆盖。
|
||||
- `lintDebug` 和排除首个失败任务后的 `lintAnalyzeDebug` 都在 lint 扫描前被现有原生构建插件阻断:`installProjectConfig` / `installProjectPrebuiltAssets` 无法取得 `cxxAbiModel`。该问题不来自 PR2 源码;编译、APK 打包及仪器测试均已通过。
|
||||
|
||||
## 阶段 2C 验证清单
|
||||
|
||||
- [x] Room v6→v7 无损迁移,旧条目的 `expiresAt` 默认为空。
|
||||
- [x] 两类自动删除开关默认关闭;关闭时新条目不产生有效期,已有有效期会被清空。
|
||||
- [x] 开启开关或修改时长时,同类未保护条目从当前时刻重新计时。
|
||||
- [x] 只有分析器分类为 `Otp` 或 `TrackingToken` 的条目可自动过期。
|
||||
- [x] 置顶或收藏会清空有效期,取消保护不会恢复旧有效期。
|
||||
- [x] 到期条目直接删除,不进入手动删除的撤销流程。
|
||||
- [x] 进程内定时器、应用初始化和进入剪贴板窗口都会补做过期清理。
|
||||
- [x] 英文、简体中文、繁体中文设置资源和禁用状态正确。
|
||||
- [x] `testDebugUnitTest`、`assembleDebug`、`assembleDebugAndroidTest` 通过。
|
||||
- [x] API 35 上 12 项数据库仪器测试和 1 项管理器集成测试通过。
|
||||
- [x] `git diff --check` 通过。
|
||||
|
||||
### 2026-07-30 阶段 2C 验收记录
|
||||
|
||||
- 新增 3 项纯 Kotlin 过期策略测试,验证默认关闭、分类范围及置顶/收藏保护。
|
||||
- API 35 数据库测试覆盖 v6→v7 迁移、按类别删除、最近到期时间、重新计时和保护状态切换。
|
||||
- 管理器集成测试验证了复制 6 位验证码后生成有效期、收藏后取消有效期、再次复制后重新计时,以及关闭开关后清空有效期且后续复制不再安排删除。
|
||||
- 模拟器设置页已检查:两个开关默认关闭,时长项仅在对应开关开启时可编辑,默认值分别为 10 分钟和 24 小时。
|
||||
|
||||
## 阶段 3 验证清单
|
||||
|
||||
- [x] 常用词使用独立 `.mb` 文件保存,可被现有快速输入管理器读取和重新加载。
|
||||
- [x] 顶栏包含“常用词”页面,分类底栏在该页面隐藏,空列表显示独立提示。
|
||||
- [x] 点击条目直接上屏,长按可进入编辑或删除,右侧加号可新增。
|
||||
- [x] 三个及以上 Unicode 字符的连续前缀可触发预测,点击只提交缺失后缀。
|
||||
- [x] 多条匹配选择最长前缀,ASCII 匹配不区分大小写。
|
||||
- [x] 密码输入框和私密输入模式不显示常用词预测。
|
||||
- [x] `CommonWordMatcherTest` 的 4 项单元测试通过。
|
||||
- [x] `testDebugUnitTest`、`assembleDebug`、`assembleDebugAndroidTest` 通过。
|
||||
- [x] API 35 上常用词管理器及阶段 1、2 回归仪器测试共 14 项通过。
|
||||
- [x] `git diff --check` 通过。
|
||||
|
||||
### 2026-07-30 阶段 3 验收记录
|
||||
|
||||
- 常用词管理器仪器测试验证了保存、重新读取、变更通知、删除,以及测试结束后恢复原文件。
|
||||
- 模拟器中导入地址、账号、电话和邮箱样例后,输入 `Acc` 可见 `Account-Example-001` 的星标补全建议。
|
||||
- 新增和编辑复用应用内的快速输入编辑页;从键盘发起后会暂时离开输入界面,保存时立即通知键盘并重新加载 Fcitx 数据。
|
||||
- 预测只读取光标前已提交文本,不处理仍在拼音组合区中的 preedit 文本,以避免和现有中文候选竞争。
|
||||
|
||||
## 环境约定
|
||||
|
||||
- 使用 Android Platform 36、Build Tools 36.1.0、NDK 28.0.13004108、CMake 3.31.6。
|
||||
- Windows 原生构建使用 MSYS2 UCRT64 的 ECM/gettext。
|
||||
- 本地优先使用 Android Studio 自带 JBR 21;CI 继续验证 JDK 17。
|
||||
- Debug 包沿用 `.debug` 后缀,与正式版共存。
|
||||
@ -1,4 +0,0 @@
|
||||
address 北京市朝阳区示例路100号
|
||||
account Account-Example-001
|
||||
phone 13800138000
|
||||
email person@example.com
|
||||
Loading…
x
Reference in New Issue
Block a user