ci / rust-arm64 (pull_request) Successful in 1m29s
ci / bun-nix (pull_request) Successful in 19s
apple / swift (pull_request) Successful in 1m22s
apple / screenshots (pull_request) Skipped
ci / web (pull_request) Successful in 1m48s
ci / docs-site (pull_request) Successful in 1m53s
ci / rust (pull_request) Successful in 4m25s
Six findings from the on-device pass over #91, all iOS-facing: - The tray blurs no longer grow into place on a push: the screen layer resolves its internal layout (safe-area trays, the scrims' full-bleed) in a geometryGroup BEFORE the insertion animates. - The option band is LINEAR now, not a ring. A ring showed the first option waiting to the right of the last one - unreachable, since left/right clamps - and on a 2-option ring the unselected item flipped sides with every step (the 60/120 Hz row). Positions are fixed, the ends are the ends, and A's wrap travels back across the list. Options other than the facing one exist only while the drum is moving, so a long label never sits under a resting neighbour as overlapping text. - Toggles (and the pin rows) ride the band too: Off left of On, matching the left-off/right-on step semantics. - The close X is gone from settings, add-host and the library - a gamepad UI exits with B. A chromeless cancel button keeps hardware Esc and the macOS sheet working, and the library's loading/error/empty states gain a zero-size B listener so a controller-only user is never trapped where the coverflow (and its B) doesn't exist yet. - The heading is a real heading: leading-aligned with the 24 pt content inset, 24/34 pt (was 20/30), top margin 18/28 (was 10/18) - launcher, settings, add-host and library alike. The launcher's hidden-mirror chip trick died with the centred title that needed it. Verified: swift build (macOS), swift build --triple arm64-apple-ios17.0, swift test 208 passed / 0 failed.
56 lines
2.5 KiB
Swift
56 lines
2.5 KiB
Swift
// The library as one of the gamepad shell's in-place layers (iOS): console chrome — a pinned
|
|
// title and a close ✕ styled like the settings screen's — around the shared LibraryView, whose
|
|
// gamepad branch renders the coverflow. The cover presentation used to get its title and Close
|
|
// from the wrapping NavigationStack's bar; a shell layer has no bar, so this restores both in
|
|
// the console's own grammar. Everything data-shaped (the fetch, the loading/error/empty states,
|
|
// the image session lifecycle) stays LibraryView's.
|
|
|
|
import PunktfunkKit
|
|
import SwiftUI
|
|
#if os(iOS)
|
|
|
|
struct GamepadLibraryScreen: View {
|
|
@Environment(\.gamepadInk) private var ink
|
|
@ObservedObject var store: HostStore
|
|
let host: StoredHost
|
|
let onLaunch: (String) -> Void
|
|
let close: () -> Void
|
|
var controllerActive = true
|
|
|
|
/// `.compact` in a landscape phone window — tighter chrome, like every gamepad screen.
|
|
@Environment(\.verticalSizeClass) private var vSizeClass
|
|
|
|
private var compact: Bool { vSizeClass == .compact }
|
|
|
|
var body: some View {
|
|
LibraryView(
|
|
store: store, host: host, onLaunch: onLaunch,
|
|
onClose: close, controllerActive: controllerActive)
|
|
.safeAreaInset(edge: .top, spacing: 0) {
|
|
// Leading, like every gamepad heading — no close chrome, B is the exit (the
|
|
// coverflow's, or LibraryView's own back-catcher before the coverflow exists).
|
|
Text("\(host.displayName) — Library")
|
|
.font(.geist(gamepadTitleSize(compact: compact), .bold, relativeTo: .title))
|
|
.foregroundStyle(ink.fg)
|
|
.lineLimit(1)
|
|
.minimumScaleFactor(0.75)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(.horizontal, 24)
|
|
.padding(.top, gamepadTitleTopPadding(compact: compact))
|
|
.padding(.bottom, gamepadTitleBottomPadding(compact: compact))
|
|
.background { GamepadTrayScrim(edge: .top) }
|
|
}
|
|
// A hardware keyboard's Esc still closes, without chrome.
|
|
.background {
|
|
Button("Close") { close() }
|
|
.keyboardShortcut(.cancelAction)
|
|
.buttonStyle(.plain)
|
|
.frame(width: 0, height: 0)
|
|
.opacity(0)
|
|
.accessibilityHidden(true)
|
|
}
|
|
.gamepadPaletteInk()
|
|
}
|
|
}
|
|
#endif
|