chore(release): bump version to 2.1.6 (build 131)

Version: CURRENT_PROJECT_VERSION 130 -> 131 (project.yml, AGENTS.md, READMEs,
docs/llms.txt).

fix(flow): host-app identification now compiles in every build configuration
(Debug, TestFlight, Release). The arbiter probe and HostAppIdentity were
DEBUG-only, so TestFlight/App Store builds never knew the host bundle id and
could not auto-return after a startflow handoff. Debug-only logging and the
Home test card are unchanged.

Also includes the pending work in the tree:
- Home: single account/setup card surface (HomeAccountSurfacePolicy/Views)
- Wide screens: voice key row and centred mic placement, iPhone Duo layout
- Keyboard: clipboard skill ranking and AI skill layout updates
- Debug: account session handoff to the Simulator (+ import script)
- Docs: portfolio assets, privacy policy URL, site/README refresh
This commit is contained in:
Rocky
2026-10-29 11:54:13 +08:00
parent 055a40976f
commit 4dce67df84
65 changed files with 3682 additions and 787 deletions
@@ -38,9 +38,16 @@ struct KeyboardSurfaceRoot: View {
static func height(
for surface: KeyboardState.Surface,
isIPad: Bool = false,
width: CGFloat = 0
width: CGFloat = 0,
isExpandedPhone: Bool = false,
isCompactHeightPhone: Bool = false
) -> CGFloat {
TypingSurfaceMetrics.contentHeight(isIPad: isIPad, width: width)
TypingSurfaceMetrics.contentHeight(
isIPad: isIPad,
width: width,
isExpandedPhone: isExpandedPhone,
isCompactHeightPhone: isCompactHeightPhone
)
}
var body: some View {
+45 -8
View File
@@ -27,12 +27,32 @@ enum TypingLayoutMetrics {
// MARK: - iPad (regular size class) metrics
static func metrics(isIPad: Bool, width: CGFloat) -> TypingKeyLayoutBuilder.Metrics {
TypingSurfaceMetrics.metrics(isIPad: isIPad, width: width)
static func metrics(
isIPad: Bool,
width: CGFloat,
isExpandedPhone: Bool = false,
isCompactHeightPhone: Bool = false
) -> TypingKeyLayoutBuilder.Metrics {
TypingSurfaceMetrics.metrics(
isIPad: isIPad,
width: width,
isExpandedPhone: isExpandedPhone,
isCompactHeightPhone: isCompactHeightPhone
)
}
static func contentHeight(isIPad: Bool, width: CGFloat) -> CGFloat {
TypingSurfaceMetrics.contentHeight(isIPad: isIPad, width: width)
static func contentHeight(
isIPad: Bool,
width: CGFloat,
isExpandedPhone: Bool = false,
isCompactHeightPhone: Bool = false
) -> CGFloat {
TypingSurfaceMetrics.contentHeight(
isIPad: isIPad,
width: width,
isExpandedPhone: isExpandedPhone,
isCompactHeightPhone: isCompactHeightPhone
)
}
}
@@ -50,8 +70,18 @@ struct TypingRootView: View {
/// Keys currently under a finger (grid-level touch pad, multi-touch).
@State private var highlightedKeyIDs: Set<String> = []
static func totalHeight(isIPad: Bool = false, width: CGFloat = 0) -> CGFloat {
TypingLayoutMetrics.contentHeight(isIPad: isIPad, width: width)
static func totalHeight(
isIPad: Bool = false,
width: CGFloat = 0,
isExpandedPhone: Bool = false,
isCompactHeightPhone: Bool = false
) -> CGFloat {
TypingLayoutMetrics.contentHeight(
isIPad: isIPad,
width: width,
isExpandedPhone: isExpandedPhone,
isCompactHeightPhone: isCompactHeightPhone
)
}
private var palette: ThemePalette {
@@ -95,7 +125,9 @@ struct TypingRootView: View {
.frame(
height: Self.totalHeight(
isIPad: state.usesIPadLayoutMetrics,
width: state.layoutWidth
width: state.layoutWidth,
isExpandedPhone: state.usesExpandedPhoneLayoutMetrics,
isCompactHeightPhone: state.usesCompactHeightPhoneLayoutMetrics
)
)
.background(Color.clear)
@@ -569,7 +601,12 @@ struct TypingRootView: View {
// keyboard. Using `size` here would compare the grid's own width to
// its height (always landscape) and could pick a different bucket than
// the height constraint, clipping the bottom row.
let metrics = TypingLayoutMetrics.metrics(isIPad: isIPad, width: state.layoutWidth)
let metrics = TypingLayoutMetrics.metrics(
isIPad: isIPad,
width: state.layoutWidth,
isExpandedPhone: state.usesExpandedPhoneLayoutMetrics,
isCompactHeightPhone: state.usesCompactHeightPhoneLayoutMetrics
)
let pageLabel = typing.page == .letters ? "123" : "ABC"
let spaceLabel = typing.language == .chinese ? "空格" : "space"
let returnLabel: String = {