07067ca6c5
- Custom Keyboard Extension with push-to-talk UI - iOS 26 SpeechAnalyzer + DictationTranscriber (iOS 18 SF fallback) - OpenAI-compatible LLM client (4 built-in providers + custom) - 3-page onboarding flow + provider config UI - App Group shared storage for cross-process config - 8s LLM timeout with raw-transcript fallback - App Store privacy manifests for both targets - SwiftLint + XcodeGen + GitHub Actions CI - Unit tests (4/4 passing)
51 lines
1.8 KiB
Swift
51 lines
1.8 KiB
Swift
// SettingsView.swift
|
|
// OSGKeyboard · Main App
|
|
//
|
|
// Reachable from HomeView. Reuses the same Onboarding cards.
|
|
|
|
import SwiftUI
|
|
import OSGKeyboardShared
|
|
|
|
struct SettingsView: View {
|
|
@ObservedObject var config = ProviderConfig.shared
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
ZStack {
|
|
Theme.background.ignoresSafeArea()
|
|
ScrollView {
|
|
VStack(spacing: 14) {
|
|
ProviderPickerSection(config: config)
|
|
APISettingsCard(config: config)
|
|
.padding(.horizontal, 16)
|
|
|
|
Button {
|
|
if let url = URL(string: UIApplication.openSettingsURLString) {
|
|
UIApplication.shared.open(url)
|
|
}
|
|
} label: {
|
|
Label("Open iOS Keyboard Settings", systemImage: "keyboard")
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.vertical, 12)
|
|
.background(Theme.card, in: RoundedRectangle(cornerRadius: 12))
|
|
.foregroundStyle(Theme.textPrimary)
|
|
}
|
|
.padding(.horizontal, 16)
|
|
}
|
|
.padding(.vertical, 18)
|
|
}
|
|
}
|
|
.navigationTitle("Settings")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .confirmationAction) {
|
|
Button("Done") { dismiss() }
|
|
.foregroundStyle(Theme.accent)
|
|
}
|
|
}
|
|
.preferredColorScheme(.dark)
|
|
}
|
|
}
|
|
}
|