Files
OSGKeyboard/OSGKeyboard/Views/KeyboardPreviewSheet.swift
T
Zhongshu e0b92ff35a [P0-①] Theme follows system + keyboard background transparent
- Split Palette.dark / Palette.light into a ThemePalette struct
- Add EnvironmentKey<ThemePalette> + ThemedRoot<Content>
- Wrap OSGKeyboardApp root in ThemedRoot so main App follows system
- Remove 6 .preferredColorScheme(.dark) overrides from main App views
- KeyboardRootView drops its Palette.background fill, uses .background(Color.clear)
- Drop the unused 'background' computed property from KeyboardRootView
- Legacy 'Palette.xxx' static accessors still resolve to dark values,
  so 2000 lines of existing call sites stay untouched

xcodebuild iOS Simulator: SUCCEEDED
2026-06-18 10:38:23 +08:00

99 lines
3.2 KiB
Swift

// KeyboardPreviewSheet.swift
// OSGKeyboard · Main App
//
// Renders a stand-in keyboard layout inside the main app so the user
// can preview what the real keyboard extension looks like without
// enabling the keyboard in iOS Settings. Tap the disc to cycle
// through idle / recording / processing so all visual states are
// inspectable.
import SwiftUI
import OSGKeyboardShared
struct KeyboardPreviewSheet: View {
@Environment(\.dismiss) private var dismiss
// We mirror only the fields the stand-in actually needs, instead of
// crossing the OSGKeyboardExt target boundary to construct a
// `KeyboardViewController.State` (whose initialiser is internal).
@State private var phase: StubPhase = .idle
@State private var level: Double = 0
@State private var transcript: String = ""
private enum StubPhase { case idle, recording, processing }
var body: some View {
ZStack {
Palette.background.ignoresSafeArea()
VStack(spacing: 0) {
VStack(spacing: Spacing.md) {
Text("Keyboard Preview")
.font(TypeStyle.title2)
.foregroundStyle(Palette.textPrimary)
Text("Tap the disc to cycle states. The real keyboard uses the same layout.")
.font(TypeStyle.caption)
.foregroundStyle(Palette.textSecondary)
.multilineTextAlignment(.center)
.padding(.horizontal, Spacing.lg)
mockTextField.padding(.horizontal, Spacing.md)
}
.padding(.top, Spacing.lg)
Spacer(minLength: 0)
keyboardBlock
}
}
}
private var mockTextField: some View {
HStack {
Image(systemName: "magnifyingglass")
.foregroundStyle(Palette.textSecondary)
Text("Type here…")
.foregroundStyle(Palette.textTertiary)
Spacer()
}
.padding(Spacing.md)
.background(Palette.surface, in: RoundedRectangle(cornerRadius: Radius.medium))
.overlay(
RoundedRectangle(cornerRadius: Radius.medium)
.stroke(Palette.divider, lineWidth: 0.5)
)
}
private var keyboardBlock: some View {
VStack(spacing: 0) {
Rectangle()
.fill(Palette.divider)
.frame(height: 0.5)
KeyboardPreviewStub(
phase: stubPhase,
level: level,
transcript: transcript
)
.environment(\.colorScheme, .dark)
Rectangle()
.fill(Color.black)
.frame(height: 34)
.overlay(alignment: .center) {
Capsule()
.fill(Color.white.opacity(0.4))
.frame(width: 134, height: 5)
}
}
}
private var stubPhase: KeyboardPreviewStub.Phase {
switch phase {
case .idle: return .idle
case .recording: return .recording
case .processing: return .processing
}
}
}
#if DEBUG
#Preview {
KeyboardPreviewSheet()
}
#endif