mirror of
https://github.com/yattee/yattee.git
synced 2026-02-21 10:19:46 +00:00
Add opaque black background to onboarding on tvOS to prevent Home screen content from leaking through the fullScreenCover. Replace toolbar Skip button with plain overlay button to avoid blurred material style, and add tvOS card button style with default focus on Continue button.
130 lines
4.0 KiB
Swift
130 lines
4.0 KiB
Swift
//
|
|
// OnboardingTitleScreen.swift
|
|
// Yattee
|
|
//
|
|
// First onboarding screen with app logo, title, and feature highlights.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct OnboardingTitleScreen: View {
|
|
let onContinue: () -> Void
|
|
|
|
#if os(tvOS)
|
|
@FocusState private var continueButtonFocused: Bool
|
|
#endif
|
|
|
|
var body: some View {
|
|
GeometryReader { geometry in
|
|
let iconSize = min(max(geometry.size.height * 0.13, 60), 140)
|
|
let cornerRadius = iconSize * 0.23
|
|
|
|
VStack(spacing: 32) {
|
|
Spacer()
|
|
|
|
// App icon and title
|
|
VStack {
|
|
Image("AppIconPreview")
|
|
.resizable()
|
|
.scaledToFit()
|
|
.frame(width: iconSize, height: iconSize)
|
|
.clipShape(RoundedRectangle(cornerRadius: cornerRadius))
|
|
|
|
Text(verbatim: "Yattee")
|
|
.font(.largeTitle)
|
|
.fontWeight(.bold)
|
|
|
|
Text(String(localized: "onboarding.title.tagline"))
|
|
.font(.title3)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
|
|
Spacer()
|
|
|
|
// Feature highlights
|
|
VStack(alignment: .leading, spacing: 20) {
|
|
FeatureRow(
|
|
icon: "lock.shield",
|
|
title: String(localized: "onboarding.title.privacy.title"),
|
|
description: String(localized: "onboarding.title.privacy.description")
|
|
)
|
|
|
|
FeatureRow(
|
|
icon: "server.rack",
|
|
title: String(localized: "onboarding.title.sources.title"),
|
|
description: String(localized: "onboarding.title.sources.description")
|
|
)
|
|
|
|
FeatureRow(
|
|
icon: "icloud",
|
|
title: String(localized: "onboarding.title.sync.title"),
|
|
description: String(localized: "onboarding.title.sync.description")
|
|
)
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(.horizontal)
|
|
|
|
|
|
// Continue button
|
|
Button(action: onContinue) {
|
|
Text(String(localized: "onboarding.continue"))
|
|
.font(.headline)
|
|
.frame(maxWidth: .infinity)
|
|
.padding()
|
|
#if os(tvOS)
|
|
.background(Color.accentColor.opacity(0.2))
|
|
#else
|
|
.background(Color.accentColor)
|
|
.foregroundStyle(.white)
|
|
#endif
|
|
.clipShape(RoundedRectangle(cornerRadius: 12))
|
|
}
|
|
#if os(tvOS)
|
|
.buttonStyle(.card)
|
|
.focused($continueButtonFocused)
|
|
#endif
|
|
.padding(.horizontal)
|
|
.padding(.bottom)
|
|
}
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.padding()
|
|
#if os(tvOS)
|
|
.onAppear { continueButtonFocused = true }
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Feature Row
|
|
|
|
private struct FeatureRow: View {
|
|
let icon: String
|
|
let title: String
|
|
let description: String
|
|
|
|
var body: some View {
|
|
HStack(alignment: .top, spacing: 16) {
|
|
Image(systemName: icon)
|
|
.font(.title2)
|
|
.foregroundStyle(Color.accentColor)
|
|
.frame(width: 32)
|
|
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Text(title)
|
|
.font(.headline)
|
|
|
|
Text(description)
|
|
.font(.subheadline)
|
|
.foregroundStyle(.secondary)
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Preview
|
|
|
|
#Preview {
|
|
OnboardingTitleScreen(onContinue: {})
|
|
}
|