Files
hapi/ios/Hapi/Features/Home/FoldableDevice.swift
T
weishu c6fae86c42 feat(ios): adapt layout for iPhone Duo
- Use the split navigation on foldable iPhones once UIHingeInteraction
  (iOS 27.1+) reports a hinge: unfolded shows sidebar + chat, folded
  collapses to the phone stack without recreating the chat.
- Side-by-side sidebar: drop the truncated inline "Sessions" title and
  move the filter beside the hub menu (also fixes iPad).
- Folded outer screen: drop the home title so the empty bar disappears,
  use the leading-aligned system title/subtitle in chat, minimize the
  chat title on scroll, and let the composer sit 16pt closer to the home
  indicator while the text field is unfocused.
- Qualify Markdown.Document, which is ambiguous with the iOS 27.1 SDK.
- test-transcript.sh picks the newest runtime that supports the device
  type (iOS 27.1 only ships iPhone Duo); split tests run on iPhone Duo.
2026-10-28 10:32:21 +08:00

35 lines
1.0 KiB
Swift

import Observation
import SwiftUI
import UIKit
/// Whether this phone has a hinge (iPhone Duo) and can unfold to a
/// tablet-width display. UIKit reports hinges only asynchronously through
/// `UIHingeInteraction`, so this starts false and latches true for the
/// process; a nil update only means the probe left its hierarchy.
@MainActor @Observable
final class FoldableDevice {
static let shared = FoldableDevice()
private(set) var hasHinge = false
func recordHinge() {
if !hasHinge { hasHinge = true }
}
}
/// Invisible view that reports a hinge to `FoldableDevice.shared`.
struct HingeProbe: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()
view.isUserInteractionEnabled = false
if #available(iOS 27.1, *) {
view.addInteraction(UIHingeInteraction { _, update in
if update.hinge != nil { FoldableDevice.shared.recordHinge() }
})
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
}