feat(keyboard): improve typing, voice flow, and polish reliability

Reduce extension memory pressure and delivery races while adding richer candidates, tactile feedback, and safer two-level creative polishing.
This commit is contained in:
Rocky
2026-08-05 21:39:31 +08:00
parent 38e5ad570d
commit 31f5937a7f
177 changed files with 8343 additions and 3904 deletions
@@ -17,36 +17,84 @@ public enum TypingKeyPage: String, CaseIterable, Sendable {
/// The Phase 1 SwiftUI keyboard reads this; a future Kit-backed shell
/// can feed the same consumer.
public protocol TypingLayoutProviding: Sendable {
func rows(for page: TypingKeyPage, shiftActive: Bool) -> [[String]]
func rows(
for page: TypingKeyPage,
language: TypingInputLanguage,
shiftActive: Bool
) -> [[String]]
}
/// Standard phone QWERTY + 123 + light symbols (NanoMouse / system-like).
/// Phone QWERTY + 123 / #+= pages aligned with iOS system keyboards
/// (English US and Simplified Chinese Pinyin).
public struct StandardTypingLayout: TypingLayoutProviding {
public init() {}
public func rows(for page: TypingKeyPage, shiftActive: Bool) -> [[String]] {
public func rows(
for page: TypingKeyPage,
language: TypingInputLanguage,
shiftActive: Bool
) -> [[String]] {
switch page {
case .letters:
let upper = shiftActive
let map: (String) -> String = { upper ? $0.uppercased() : $0 }
return [
["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"].map(map),
["a", "s", "d", "f", "g", "h", "j", "k", "l"].map(map),
["⇧", "z", "x", "c", "v", "b", "n", "m", "⌫"].map { $0.count == 1 ? map($0) : $0 }
]
return letterRows(shiftActive: shiftActive)
case .numbers:
return [
["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
["-", "/", ":", ";", "(", ")", "$", "&", "@", "\""],
["#+=", ".", ",", "?", "!", "'", "⌫"]
]
return language == .chinese ? chineseNumberRows : englishNumberRows
case .symbols:
return [
["[", "]", "{", "}", "#", "%", "^", "*", "+", "="],
["_", "\\", "|", "~", "<", ">", "€", "£", "¥", "·"],
["123", ".", ",", "?", "!", "'", "⌫"],
[",", "。", "、", "?", "!", ":", ";"]
]
return language == .chinese ? chineseSymbolRows : englishSymbolRows
}
}
// MARK: - Letters (shared)
private func letterRows(shiftActive: Bool) -> [[String]] {
let upper = shiftActive
let map: (String) -> String = { upper ? $0.uppercased() : $0 }
return [
["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"].map(map),
["a", "s", "d", "f", "g", "h", "j", "k", "l"].map(map),
["⇧", "z", "x", "c", "v", "b", "n", "m", "⌫"].map { $0.count == 1 ? map($0) : $0 }
]
}
// MARK: - English (iOS US)
/// iOS English US · Numbers
private var englishNumberRows: [[String]] {
[
["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
["-", "/", ":", ";", "(", ")", "$", "&", "@", "\""],
["#+=", ".", ",", "?", "!", "'", "⌫"]
]
}
/// iOS English US · Symbols
private var englishSymbolRows: [[String]] {
[
["[", "]", "{", "}", "#", "%", "^", "*", "+", "="],
["_", "\\", "|", "~", "<", ">", "€", "£", "¥", "·"],
["123", ".", ",", "?", "!", "'", "⌫"]
]
}
// MARK: - Chinese (iOS 简体拼音)
/// iOS Simplified Chinese · Numbers (fullwidth punctuation where system uses it)
private var chineseNumberRows: [[String]] {
[
["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
// System 123 page uses curly double quotes “ ” (not corner brackets).
["-", "/", ":", ";", "(", ")", "¥", "@", "“", "”"],
["#+=", "。", ",", "、", "?", "!", ".", "⌫"]
]
}
/// iOS Simplified Chinese · Symbols
private var chineseSymbolRows: [[String]] {
[
// 「」 live on #+= so they remain reachable after numbers use “ ”.
["【", "】", "「", "」", "#", "%", "^", "*", "+", "="],
["_", "\\", "|", "~", "《", "》", "€", "£", "¥", "·"],
["123", "。", ",", "、", "?", "!", ".", "⌫"]
]
}
}