Files
Rocky 4dce67df84 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
2026-10-29 11:54:13 +08:00

30 lines
1.2 KiB
Swift

// VoiceMicPlacement.swift
// OSGKeyboard · Shared
//
// Vertical placement of the voice surface's mic row. Every shell height
// (phone, unfolded Duo, landscape, iPad narrow / wide) leaves a different
// amount of free height between the top bar and the bottom row; this splits it
// into the context slot above the mic and the gap below it with one rule, so
// the mic sits centred in the area below the top bar on every device.
import CoreGraphics
public enum VoiceMicPlacement {
/// Never let the mic touch the bottom row.
public static let minimumGap: CGFloat = 10
/// Context slot height for a free height (`contextAndGap` = slot + gap).
/// Centred means the slot above the mic equals the gap plus the bottom row
/// below it, but the slot never drops under `minimumContextHeight` (the
/// live transcript) and the gap never under `minimumGap`.
public static func contextHeight(
contextAndGap: CGFloat,
bottomRowHeight: CGFloat,
minimumContextHeight: CGFloat
) -> CGFloat {
let centred = (contextAndGap + bottomRowHeight) / 2
let ceiling = max(0, contextAndGap - minimumGap)
return min(ceiling, max(minimumContextHeight, centred))
}
}