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", "", "", "", "", "", ".", ""]
]
}
}